winlin

use system utility for string finds

@@ -268,19 +268,8 @@ int SrsDynamicHttpConn::connect() @@ -268,19 +268,8 @@ int SrsDynamicHttpConn::connect()
268 // parse uri 268 // parse uri
269 if (!req) { 269 if (!req) {
270 req = new SrsRequest(); 270 req = new SrsRequest();
271 -  
272 - size_t pos = string::npos;  
273 - string uri = req->tcUrl = output;  
274 -  
275 - // tcUrl, stream  
276 - if ((pos = uri.rfind("/")) != string::npos) {  
277 - req->stream = uri.substr(pos + 1);  
278 - req->tcUrl = uri = uri.substr(0, pos);  
279 - }  
280 -  
281 - srs_discovery_tc_url(req->tcUrl,  
282 - req->schema, req->host, req->vhost, req->app, req->port,  
283 - req->param); 271 + srs_parse_rtmp_url(output, req->tcUrl, req->stream);
  272 + srs_discovery_tc_url(req->tcUrl, req->schema, req->host, req->vhost, req->app, req->port, req->param);
284 } 273 }
285 274
286 // connect host. 275 // connect host.
@@ -107,7 +107,7 @@ int SrsFlvSegment::open(bool use_tmp_file) @@ -107,7 +107,7 @@ int SrsFlvSegment::open(bool use_tmp_file)
107 bool fresh_flv_file = !srs_path_exists(path); 107 bool fresh_flv_file = !srs_path_exists(path);
108 108
109 // create dir first. 109 // create dir first.
110 - std::string dir = path.substr(0, path.rfind("/")); 110 + std::string dir = srs_path_dirname(path);
111 if ((ret = srs_create_dir_recursively(dir)) != ERROR_SUCCESS) { 111 if ((ret = srs_create_dir_recursively(dir)) != ERROR_SUCCESS) {
112 srs_error("create dir=%s failed. ret=%d", dir.c_str(), ret); 112 srs_error("create dir=%s failed. ret=%d", dir.c_str(), ret);
113 return ret; 113 return ret;
@@ -572,12 +572,7 @@ int SrsHttpMessage::update(string url, bool allow_jsonp, http_parser* header, Sr @@ -572,12 +572,7 @@ int SrsHttpMessage::update(string url, bool allow_jsonp, http_parser* header, Sr
572 } 572 }
573 573
574 // parse ext. 574 // parse ext.
575 - _ext = _uri->get_path();  
576 - if ((pos = _ext.rfind(".")) != string::npos) {  
577 - _ext = _ext.substr(pos);  
578 - } else {  
579 - _ext = "";  
580 - } 575 + _ext = srs_path_filext(_uri->get_path());
581 576
582 // parse jsonp request message. 577 // parse jsonp request message.
583 if (allow_jsonp) { 578 if (allow_jsonp) {
@@ -816,23 +811,23 @@ SrsRequest* SrsHttpMessage::to_request(string vhost) @@ -816,23 +811,23 @@ SrsRequest* SrsHttpMessage::to_request(string vhost)
816 { 811 {
817 SrsRequest* req = new SrsRequest(); 812 SrsRequest* req = new SrsRequest();
818 813
819 - req->app = _uri->get_path();  
820 - size_t pos = string::npos;  
821 - if ((pos = req->app.rfind("/")) != string::npos) {  
822 - req->stream = req->app.substr(pos + 1);  
823 - req->app = req->app.substr(0, pos);  
824 - }  
825 - if ((pos = req->stream.rfind(".")) != string::npos) {  
826 - req->stream = req->stream.substr(0, pos);  
827 - } 814 + // http path, for instance, /live/livestream.flv, parse to
  815 + // app: /live
  816 + // stream: livestream.flv
  817 + srs_parse_rtmp_url(_uri->get_path(), req->app, req->stream);
  818 +
  819 + // trim the start slash, for instance, /live to live
  820 + req->app = srs_string_trim_start(req->app, "/");
  821 +
  822 + // remove the extension, for instance, livestream.flv to livestream
  823 + req->stream = srs_path_filename(req->stream);
828 824
829 - req->tcUrl = "rtmp://" + vhost + req->app; 825 + // generate others.
  826 + req->tcUrl = "rtmp://" + vhost + "/" + req->app;
830 req->pageUrl = get_request_header("Referer"); 827 req->pageUrl = get_request_header("Referer");
831 req->objectEncoding = 0; 828 req->objectEncoding = 0;
832 829
833 - srs_discovery_tc_url(req->tcUrl,  
834 - req->schema, req->host, req->vhost, req->app, req->port,  
835 - req->param); 830 + srs_discovery_tc_url(req->tcUrl, req->schema, req->host, req->vhost, req->app, req->port, req->param);
836 req->strip(); 831 req->strip();
837 832
838 return req; 833 return req;
@@ -242,7 +242,7 @@ int SrsHttpStaticServer::initialize() @@ -242,7 +242,7 @@ int SrsHttpStaticServer::initialize()
242 mount = srs_string_replace(mount, SRS_CONSTS_RTMP_DEFAULT_VHOST"/", "/"); 242 mount = srs_string_replace(mount, SRS_CONSTS_RTMP_DEFAULT_VHOST"/", "/");
243 243
244 // the dir mount must always ends with "/" 244 // the dir mount must always ends with "/"
245 - if (mount != "/" && mount.rfind("/") != mount.length() - 1) { 245 + if (mount != "/" && !srs_string_ends_with(mount, "/")) {
246 mount += "/"; 246 mount += "/";
247 } 247 }
248 248
@@ -611,11 +611,7 @@ SrsLiveEntry::SrsLiveEntry(std::string m, bool h) @@ -611,11 +611,7 @@ SrsLiveEntry::SrsLiveEntry(std::string m, bool h)
611 req = NULL; 611 req = NULL;
612 source = NULL; 612 source = NULL;
613 613
614 - std::string ext;  
615 - size_t pos = string::npos;  
616 - if ((pos = m.rfind(".")) != string::npos) {  
617 - ext = m.substr(pos);  
618 - } 614 + std::string ext = srs_path_filext(m);
619 _is_flv = (ext == ".flv"); 615 _is_flv = (ext == ".flv");
620 _is_ts = (ext == ".ts"); 616 _is_ts = (ext == ".ts");
621 _is_mp3 = (ext == ".mp3"); 617 _is_mp3 = (ext == ".mp3");
@@ -1319,10 +1315,7 @@ string SrsHttpStreamServer::hls_mount_generate(SrsRequest* r, string uri, string @@ -1319,10 +1315,7 @@ string SrsHttpStreamServer::hls_mount_generate(SrsRequest* r, string uri, string
1319 std::string mount = tmpl; 1315 std::string mount = tmpl;
1320 1316
1321 // the ts is relative from the m3u8, the same start dir. 1317 // the ts is relative from the m3u8, the same start dir.
1322 - size_t pos = string::npos;  
1323 - if ((pos = mount.rfind("/")) != string::npos) {  
1324 - mount = mount.substr(0, pos);  
1325 - } 1318 + mount = srs_path_dirname(mount);
1326 1319
1327 // replace the vhost variable 1320 // replace the vhost variable
1328 mount = srs_string_replace(mount, "[vhost]", r->vhost); 1321 mount = srs_string_replace(mount, "[vhost]", r->vhost);
@@ -35,6 +35,7 @@ using namespace std; @@ -35,6 +35,7 @@ using namespace std;
35 #include <srs_app_pithy_print.hpp> 35 #include <srs_app_pithy_print.hpp>
36 #include <srs_kernel_utility.hpp> 36 #include <srs_kernel_utility.hpp>
37 #include <srs_app_utility.hpp> 37 #include <srs_app_utility.hpp>
  38 +#include <srs_protocol_utility.hpp>
38 39
39 // when error, ingester sleep for a while and retry. 40 // when error, ingester sleep for a while and retry.
40 // ingest never sleep a long time, for we must start the stream ASAP. 41 // ingest never sleep a long time, for we must start the stream ASAP.
@@ -354,17 +355,9 @@ int SrsIngester::initialize_ffmpeg(SrsFFMPEG* ffmpeg, SrsConfDirective* vhost, S @@ -354,17 +355,9 @@ int SrsIngester::initialize_ffmpeg(SrsFFMPEG* ffmpeg, SrsConfDirective* vhost, S
354 } 355 }
355 356
356 // find the app and stream in rtmp url 357 // find the app and stream in rtmp url
357 - std::string url = output;  
358 std::string app, stream; 358 std::string app, stream;
359 - size_t pos = std::string::npos;  
360 - if ((pos = url.rfind("/")) != std::string::npos) {  
361 - stream = url.substr(pos + 1);  
362 - url = url.substr(0, pos);  
363 - }  
364 - if ((pos = url.rfind("/")) != std::string::npos) {  
365 - app = url.substr(pos + 1);  
366 - url = url.substr(0, pos);  
367 - } 359 + srs_parse_rtmp_url(output, app, stream);
  360 + size_t pos;
368 if ((pos = app.rfind("?")) != std::string::npos) { 361 if ((pos = app.rfind("?")) != std::string::npos) {
369 app = app.substr(0, pos); 362 app = app.substr(0, pos);
370 } 363 }
@@ -611,19 +611,8 @@ int SrsMpegtsOverUdp::connect() @@ -611,19 +611,8 @@ int SrsMpegtsOverUdp::connect()
611 // parse uri 611 // parse uri
612 if (!req) { 612 if (!req) {
613 req = new SrsRequest(); 613 req = new SrsRequest();
614 -  
615 - size_t pos = string::npos;  
616 - string uri = req->tcUrl = output;  
617 -  
618 - // tcUrl, stream  
619 - if ((pos = uri.rfind("/")) != string::npos) {  
620 - req->stream = uri.substr(pos + 1);  
621 - req->tcUrl = uri = uri.substr(0, pos);  
622 - }  
623 -  
624 - srs_discovery_tc_url(req->tcUrl,  
625 - req->schema, req->host, req->vhost, req->app, req->port,  
626 - req->param); 614 + srs_parse_rtmp_url(output, req->tcUrl, req->stream);
  615 + srs_discovery_tc_url(req->tcUrl, req->schema, req->host, req->vhost, req->app, req->port, req->param);
627 } 616 }
628 617
629 // connect host. 618 // connect host.
@@ -270,10 +270,7 @@ int SrsRtspConn::do_cycle() @@ -270,10 +270,7 @@ int SrsRtspConn::do_cycle()
270 if ((pos = rtsp_tcUrl.rfind(".sdp")) != string::npos) { 270 if ((pos = rtsp_tcUrl.rfind(".sdp")) != string::npos) {
271 rtsp_tcUrl = rtsp_tcUrl.substr(0, pos); 271 rtsp_tcUrl = rtsp_tcUrl.substr(0, pos);
272 } 272 }
273 - if ((pos = rtsp_tcUrl.rfind("/")) != string::npos) {  
274 - rtsp_stream = rtsp_tcUrl.substr(pos + 1);  
275 - rtsp_tcUrl = rtsp_tcUrl.substr(0, pos);  
276 - } 273 + srs_parse_rtmp_url(rtsp_tcUrl, rtsp_tcUrl, rtsp_stream);
277 274
278 srs_assert(req->sdp); 275 srs_assert(req->sdp);
279 video_id = ::atoi(req->sdp->video_stream_id.c_str()); 276 video_id = ::atoi(req->sdp->video_stream_id.c_str());
@@ -651,8 +648,6 @@ int SrsRtspConn::connect() @@ -651,8 +648,6 @@ int SrsRtspConn::connect()
651 648
652 // parse uri 649 // parse uri
653 if (!req) { 650 if (!req) {
654 - req = new SrsRequest();  
655 -  
656 std::string schema, host, vhost, app, port, param; 651 std::string schema, host, vhost, app, port, param;
657 srs_discovery_tc_url(rtsp_tcUrl, schema, host, vhost, app, port, param); 652 srs_discovery_tc_url(rtsp_tcUrl, schema, host, vhost, app, port, param);
658 653
@@ -660,19 +655,10 @@ int SrsRtspConn::connect() @@ -660,19 +655,10 @@ int SrsRtspConn::connect()
660 std::string output = output_template; 655 std::string output = output_template;
661 output = srs_string_replace(output, "[app]", app); 656 output = srs_string_replace(output, "[app]", app);
662 output = srs_string_replace(output, "[stream]", rtsp_stream); 657 output = srs_string_replace(output, "[stream]", rtsp_stream);
663 -  
664 - size_t pos = string::npos;  
665 - string uri = req->tcUrl = output;  
666 -  
667 - // tcUrl, stream  
668 - if ((pos = uri.rfind("/")) != string::npos) {  
669 - req->stream = uri.substr(pos + 1);  
670 - req->tcUrl = uri = uri.substr(0, pos);  
671 - }  
672 -  
673 - srs_discovery_tc_url(req->tcUrl,  
674 - req->schema, req->host, req->vhost, req->app, req->port,  
675 - req->param); 658 +
  659 + req = new SrsRequest();
  660 + srs_parse_rtmp_url(output, req->tcUrl, req->stream);
  661 + srs_discovery_tc_url(req->tcUrl, req->schema, req->host, req->vhost, req->app, req->port, req->param);
676 } 662 }
677 663
678 // connect host. 664 // connect host.
@@ -202,6 +202,17 @@ public: @@ -202,6 +202,17 @@ public:
202 virtual int writev(const iovec *iov, int iov_size, ssize_t* nwrite); 202 virtual int writev(const iovec *iov, int iov_size, ssize_t* nwrite);
203 }; 203 };
204 204
  205 +/**
  206 + * the common tcp client, to connect to specified TCP server,
  207 + * reconnect and close the connection.
  208 + */
  209 +class SrsTcpClient
  210 +{
  211 +public:
  212 + SrsTcpClient();
  213 + virtual ~SrsTcpClient();
  214 +};
  215 +
205 // initialize st, requires epoll. 216 // initialize st, requires epoll.
206 extern int srs_st_init(); 217 extern int srs_st_init();
207 218
@@ -464,6 +464,29 @@ string srs_path_basename(string path) @@ -464,6 +464,29 @@ string srs_path_basename(string path)
464 464
465 return dirname; 465 return dirname;
466 } 466 }
  467 +
  468 +string srs_path_filename(string path)
  469 +{
  470 + std::string filename = path;
  471 + size_t pos = string::npos;
  472 +
  473 + if ((pos = filename.rfind(".")) != string::npos) {
  474 + return filename.substr(0, pos);
  475 + }
  476 +
  477 + return filename;
  478 +}
  479 +
  480 +string srs_path_filext(string path)
  481 +{
  482 + size_t pos = string::npos;
  483 +
  484 + if ((pos = path.rfind(".")) != string::npos) {
  485 + return path.substr(pos);
  486 + }
  487 +
  488 + return "";
  489 +}
467 490
468 bool srs_avc_startswith_annexb(SrsBuffer* stream, int* pnb_start_code) 491 bool srs_avc_startswith_annexb(SrsBuffer* stream, int* pnb_start_code)
469 { 492 {
@@ -471,7 +494,7 @@ bool srs_avc_startswith_annexb(SrsBuffer* stream, int* pnb_start_code) @@ -471,7 +494,7 @@ bool srs_avc_startswith_annexb(SrsBuffer* stream, int* pnb_start_code)
471 char* p = bytes; 494 char* p = bytes;
472 495
473 for (;;) { 496 for (;;) {
474 - if (!stream->require(p - bytes + 3)) { 497 + if (!stream->require((int)(p - bytes + 3))) {
475 return false; 498 return false;
476 } 499 }
477 500
@@ -96,10 +96,14 @@ extern int srs_create_dir_recursively(std::string dir); @@ -96,10 +96,14 @@ extern int srs_create_dir_recursively(std::string dir);
96 96
97 // whether path exists. 97 // whether path exists.
98 extern bool srs_path_exists(std::string path); 98 extern bool srs_path_exists(std::string path);
99 -// get the dirname of path 99 +// get the dirname of path, for instance, filename("/live/livestream")="/live"
100 extern std::string srs_path_dirname(std::string path); 100 extern std::string srs_path_dirname(std::string path);
101 -// get the basename of path 101 +// get the basename of path, for instance, filename("/live/livestream")="livestream"
102 extern std::string srs_path_basename(std::string path); 102 extern std::string srs_path_basename(std::string path);
  103 +// get the filename of path, for instance, filename("livestream.flv")="livestream"
  104 +extern std::string srs_path_filename(std::string path);
  105 +// get the file extension of path, for instance, filext("live.flv")=".flv"
  106 +extern std::string srs_path_filext(std::string path);
103 107
104 /** 108 /**
105 * whether stream starts with the avc NALU in "AnnexB" 109 * whether stream starts with the avc NALU in "AnnexB"
@@ -464,16 +464,9 @@ int srs_librtmp_context_parse_uri(Context* context) @@ -464,16 +464,9 @@ int srs_librtmp_context_parse_uri(Context* context)
464 { 464 {
465 int ret = ERROR_SUCCESS; 465 int ret = ERROR_SUCCESS;
466 466
467 - // parse uri  
468 - size_t pos = string::npos;  
469 - string uri = context->url;  
470 - // tcUrl, stream  
471 - if ((pos = uri.rfind("/")) != string::npos) {  
472 - context->stream = uri.substr(pos + 1);  
473 - context->tcUrl = uri = uri.substr(0, pos);  
474 - }  
475 -  
476 std::string schema; 467 std::string schema;
  468 +
  469 + srs_parse_rtmp_url(context->url, context->tcUrl, context->stream);
477 srs_discovery_tc_url(context->tcUrl, 470 srs_discovery_tc_url(context->tcUrl,
478 schema, context->host, context->vhost, context->app, context->port, 471 schema, context->host, context->vhost, context->app, context->port,
479 context->param); 472 context->param);
@@ -377,11 +377,7 @@ int SrsHttpFileServer::serve_file(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, @@ -377,11 +377,7 @@ int SrsHttpFileServer::serve_file(ISrsHttpResponseWriter* w, ISrsHttpMessage* r,
377 } 377 }
378 378
379 if (true) { 379 if (true) {
380 - size_t pos;  
381 - std::string ext = fullpath;  
382 - if ((pos = ext.rfind(".")) != string::npos) {  
383 - ext = ext.substr(pos);  
384 - } 380 + std::string ext = srs_path_filext(fullpath);
385 381
386 if (_mime.find(ext) == _mime.end()) { 382 if (_mime.find(ext) == _mime.end()) {
387 w->header()->set_content_type("application/octet-stream"); 383 w->header()->set_content_type("application/octet-stream");
@@ -44,7 +44,7 @@ using namespace std; @@ -44,7 +44,7 @@ using namespace std;
44 void srs_discovery_tc_url( 44 void srs_discovery_tc_url(
45 string tcUrl, 45 string tcUrl,
46 string& schema, string& host, string& vhost, 46 string& schema, string& host, string& vhost,
47 - string& app, int& port, std::string& param 47 + string& app, int& port, string& param
48 ) { 48 ) {
49 size_t pos = std::string::npos; 49 size_t pos = std::string::npos;
50 std::string url = tcUrl; 50 std::string url = tcUrl;
@@ -229,7 +229,7 @@ int srs_rtmp_create_msg(char type, u_int32_t timestamp, char* data, int size, in @@ -229,7 +229,7 @@ int srs_rtmp_create_msg(char type, u_int32_t timestamp, char* data, int size, in
229 return ret; 229 return ret;
230 } 230 }
231 231
232 -std::string srs_generate_stream_url(std::string vhost, std::string app, std::string stream) 232 +string srs_generate_stream_url(string vhost, string app, string stream)
233 { 233 {
234 std::string url = ""; 234 std::string url = "";
235 235
@@ -244,6 +244,18 @@ std::string srs_generate_stream_url(std::string vhost, std::string app, std::str @@ -244,6 +244,18 @@ std::string srs_generate_stream_url(std::string vhost, std::string app, std::str
244 return url; 244 return url;
245 } 245 }
246 246
  247 +void srs_parse_rtmp_url(string url, string& tcUrl, string& stream)
  248 +{
  249 + size_t pos;
  250 +
  251 + if ((pos = url.rfind("/")) != string::npos) {
  252 + stream = url.substr(pos + 1);
  253 + tcUrl = url.substr(0, pos);
  254 + } else {
  255 + tcUrl = url;
  256 + }
  257 +}
  258 +
247 string srs_generate_rtmp_url(string server, int port, string vhost, string app, string stream) 259 string srs_generate_rtmp_url(string server, int port, string vhost, string app, string stream)
248 { 260 {
249 std::stringstream ss; 261 std::stringstream ss;
@@ -101,16 +101,34 @@ extern bool srs_bytes_equals(void* pa, void* pb, int size); @@ -101,16 +101,34 @@ extern bool srs_bytes_equals(void* pa, void* pb, int size);
101 * @param data the packet bytes. user should never free it. 101 * @param data the packet bytes. user should never free it.
102 * @param ppmsg output the shared ptr message. user should free it. 102 * @param ppmsg output the shared ptr message. user should free it.
103 */ 103 */
104 -extern int srs_rtmp_create_msg(char type, u_int32_t timestamp, char* data, int size, int stream_id, SrsSharedPtrMessage** ppmsg); 104 +extern int srs_rtmp_create_msg(
  105 + char type, u_int32_t timestamp, char* data, int size, int stream_id,
  106 + SrsSharedPtrMessage** ppmsg
  107 +);
105 108
106 // get the stream identify, vhost/app/stream. 109 // get the stream identify, vhost/app/stream.
107 -extern std::string srs_generate_stream_url(std::string vhost, std::string app, std::string stream); 110 +extern std::string srs_generate_stream_url(
  111 + std::string vhost, std::string app, std::string stream
  112 +);
  113 +
  114 +// parse the rtmp url to tcUrl/stream,
  115 +// for example, rtmp://v.ossrs.net/live/livestream to
  116 +// tcUrl: rtmp://v.ossrs.net/live
  117 +// stream: livestream
  118 +extern void srs_parse_rtmp_url(
  119 + std::string url, std::string& tcUrl, std::string& stream
  120 +);
108 121
109 // genereate the rtmp url, for instance, rtmp://server:port/app...vhost...vhost/stream 122 // genereate the rtmp url, for instance, rtmp://server:port/app...vhost...vhost/stream
110 -extern std::string srs_generate_rtmp_url(std::string server, int port, std::string vhost, std::string app, std::string stream); 123 +extern std::string srs_generate_rtmp_url(
  124 + std::string server, int port, std::string vhost, std::string app, std::string stream
  125 +);
111 126
112 // write large numbers of iovs. 127 // write large numbers of iovs.
113 -extern int srs_write_large_iovs(ISrsProtocolReaderWriter* skt, iovec* iovs, int size, ssize_t* pnwrite = NULL); 128 +extern int srs_write_large_iovs(
  129 + ISrsProtocolReaderWriter* skt, iovec* iovs, int size,
  130 + ssize_t* pnwrite = NULL
  131 +);
114 132
115 #endif 133 #endif
116 134
@@ -988,10 +988,7 @@ int SrsRtspStack::do_recv_message(SrsRtspRequest* req) @@ -988,10 +988,7 @@ int SrsRtspStack::do_recv_message(SrsRtspRequest* req)
988 // for setup, parse the stream id from uri. 988 // for setup, parse the stream id from uri.
989 if (req->is_setup()) { 989 if (req->is_setup()) {
990 size_t pos = string::npos; 990 size_t pos = string::npos;
991 - std::string stream_id;  
992 - if ((pos = req->uri.rfind("/")) != string::npos) {  
993 - stream_id = req->uri.substr(pos + 1);  
994 - } 991 + std::string stream_id = srs_path_basename(req->uri);
995 if ((pos = stream_id.find("=")) != string::npos) { 992 if ((pos = stream_id.find("=")) != string::npos) {
996 stream_id = stream_id.substr(pos + 1); 993 stream_id = stream_id.substr(pos + 1);
997 } 994 }