diff --git a/trunk/src/app/srs_app_caster_flv.cpp b/trunk/src/app/srs_app_caster_flv.cpp index 6e77ba07d..ac78c0dbc 100644 --- a/trunk/src/app/srs_app_caster_flv.cpp +++ b/trunk/src/app/srs_app_caster_flv.cpp @@ -268,19 +268,8 @@ int SrsDynamicHttpConn::connect() // parse uri if (!req) { req = new SrsRequest(); - - size_t pos = string::npos; - string uri = req->tcUrl = output; - - // tcUrl, stream - if ((pos = uri.rfind("/")) != string::npos) { - req->stream = uri.substr(pos + 1); - req->tcUrl = uri = uri.substr(0, pos); - } - - srs_discovery_tc_url(req->tcUrl, - req->schema, req->host, req->vhost, req->app, req->port, - req->param); + srs_parse_rtmp_url(output, req->tcUrl, req->stream); + srs_discovery_tc_url(req->tcUrl, req->schema, req->host, req->vhost, req->app, req->port, req->param); } // connect host. diff --git a/trunk/src/app/srs_app_dvr.cpp b/trunk/src/app/srs_app_dvr.cpp index 3b0971af8..a15974098 100644 --- a/trunk/src/app/srs_app_dvr.cpp +++ b/trunk/src/app/srs_app_dvr.cpp @@ -107,7 +107,7 @@ int SrsFlvSegment::open(bool use_tmp_file) bool fresh_flv_file = !srs_path_exists(path); // create dir first. - std::string dir = path.substr(0, path.rfind("/")); + std::string dir = srs_path_dirname(path); if ((ret = srs_create_dir_recursively(dir)) != ERROR_SUCCESS) { srs_error("create dir=%s failed. ret=%d", dir.c_str(), ret); return ret; diff --git a/trunk/src/app/srs_app_http_conn.cpp b/trunk/src/app/srs_app_http_conn.cpp index a64a953ab..1023ed0c1 100644 --- a/trunk/src/app/srs_app_http_conn.cpp +++ b/trunk/src/app/srs_app_http_conn.cpp @@ -572,12 +572,7 @@ int SrsHttpMessage::update(string url, bool allow_jsonp, http_parser* header, Sr } // parse ext. - _ext = _uri->get_path(); - if ((pos = _ext.rfind(".")) != string::npos) { - _ext = _ext.substr(pos); - } else { - _ext = ""; - } + _ext = srs_path_filext(_uri->get_path()); // parse jsonp request message. if (allow_jsonp) { @@ -816,23 +811,23 @@ SrsRequest* SrsHttpMessage::to_request(string vhost) { SrsRequest* req = new SrsRequest(); - req->app = _uri->get_path(); - size_t pos = string::npos; - if ((pos = req->app.rfind("/")) != string::npos) { - req->stream = req->app.substr(pos + 1); - req->app = req->app.substr(0, pos); - } - if ((pos = req->stream.rfind(".")) != string::npos) { - req->stream = req->stream.substr(0, pos); - } + // http path, for instance, /live/livestream.flv, parse to + // app: /live + // stream: livestream.flv + srs_parse_rtmp_url(_uri->get_path(), req->app, req->stream); - req->tcUrl = "rtmp://" + vhost + req->app; + // trim the start slash, for instance, /live to live + req->app = srs_string_trim_start(req->app, "/"); + + // remove the extension, for instance, livestream.flv to livestream + req->stream = srs_path_filename(req->stream); + + // generate others. + req->tcUrl = "rtmp://" + vhost + "/" + req->app; req->pageUrl = get_request_header("Referer"); req->objectEncoding = 0; - srs_discovery_tc_url(req->tcUrl, - req->schema, req->host, req->vhost, req->app, req->port, - req->param); + srs_discovery_tc_url(req->tcUrl, req->schema, req->host, req->vhost, req->app, req->port, req->param); req->strip(); return req; diff --git a/trunk/src/app/srs_app_http_static.cpp b/trunk/src/app/srs_app_http_static.cpp index 18a3869a8..6304d864e 100644 --- a/trunk/src/app/srs_app_http_static.cpp +++ b/trunk/src/app/srs_app_http_static.cpp @@ -242,7 +242,7 @@ int SrsHttpStaticServer::initialize() mount = srs_string_replace(mount, SRS_CONSTS_RTMP_DEFAULT_VHOST"/", "/"); // the dir mount must always ends with "/" - if (mount != "/" && mount.rfind("/") != mount.length() - 1) { + if (mount != "/" && !srs_string_ends_with(mount, "/")) { mount += "/"; } diff --git a/trunk/src/app/srs_app_http_stream.cpp b/trunk/src/app/srs_app_http_stream.cpp index 204e9eb62..3f3c4f7f1 100644 --- a/trunk/src/app/srs_app_http_stream.cpp +++ b/trunk/src/app/srs_app_http_stream.cpp @@ -611,11 +611,7 @@ SrsLiveEntry::SrsLiveEntry(std::string m, bool h) req = NULL; source = NULL; - std::string ext; - size_t pos = string::npos; - if ((pos = m.rfind(".")) != string::npos) { - ext = m.substr(pos); - } + std::string ext = srs_path_filext(m); _is_flv = (ext == ".flv"); _is_ts = (ext == ".ts"); _is_mp3 = (ext == ".mp3"); @@ -1319,10 +1315,7 @@ string SrsHttpStreamServer::hls_mount_generate(SrsRequest* r, string uri, string std::string mount = tmpl; // the ts is relative from the m3u8, the same start dir. - size_t pos = string::npos; - if ((pos = mount.rfind("/")) != string::npos) { - mount = mount.substr(0, pos); - } + mount = srs_path_dirname(mount); // replace the vhost variable mount = srs_string_replace(mount, "[vhost]", r->vhost); diff --git a/trunk/src/app/srs_app_ingest.cpp b/trunk/src/app/srs_app_ingest.cpp index fab6647cf..512aa7132 100644 --- a/trunk/src/app/srs_app_ingest.cpp +++ b/trunk/src/app/srs_app_ingest.cpp @@ -35,6 +35,7 @@ using namespace std; #include #include #include +#include // when error, ingester sleep for a while and retry. // 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 } // find the app and stream in rtmp url - std::string url = output; std::string app, stream; - size_t pos = std::string::npos; - if ((pos = url.rfind("/")) != std::string::npos) { - stream = url.substr(pos + 1); - url = url.substr(0, pos); - } - if ((pos = url.rfind("/")) != std::string::npos) { - app = url.substr(pos + 1); - url = url.substr(0, pos); - } + srs_parse_rtmp_url(output, app, stream); + size_t pos; if ((pos = app.rfind("?")) != std::string::npos) { app = app.substr(0, pos); } diff --git a/trunk/src/app/srs_app_mpegts_udp.cpp b/trunk/src/app/srs_app_mpegts_udp.cpp index 313279b11..efb4e5bcd 100644 --- a/trunk/src/app/srs_app_mpegts_udp.cpp +++ b/trunk/src/app/srs_app_mpegts_udp.cpp @@ -611,19 +611,8 @@ int SrsMpegtsOverUdp::connect() // parse uri if (!req) { req = new SrsRequest(); - - size_t pos = string::npos; - string uri = req->tcUrl = output; - - // tcUrl, stream - if ((pos = uri.rfind("/")) != string::npos) { - req->stream = uri.substr(pos + 1); - req->tcUrl = uri = uri.substr(0, pos); - } - - srs_discovery_tc_url(req->tcUrl, - req->schema, req->host, req->vhost, req->app, req->port, - req->param); + srs_parse_rtmp_url(output, req->tcUrl, req->stream); + srs_discovery_tc_url(req->tcUrl, req->schema, req->host, req->vhost, req->app, req->port, req->param); } // connect host. diff --git a/trunk/src/app/srs_app_rtsp.cpp b/trunk/src/app/srs_app_rtsp.cpp index c0c6b38e1..ca73a659a 100644 --- a/trunk/src/app/srs_app_rtsp.cpp +++ b/trunk/src/app/srs_app_rtsp.cpp @@ -270,10 +270,7 @@ int SrsRtspConn::do_cycle() if ((pos = rtsp_tcUrl.rfind(".sdp")) != string::npos) { rtsp_tcUrl = rtsp_tcUrl.substr(0, pos); } - if ((pos = rtsp_tcUrl.rfind("/")) != string::npos) { - rtsp_stream = rtsp_tcUrl.substr(pos + 1); - rtsp_tcUrl = rtsp_tcUrl.substr(0, pos); - } + srs_parse_rtmp_url(rtsp_tcUrl, rtsp_tcUrl, rtsp_stream); srs_assert(req->sdp); video_id = ::atoi(req->sdp->video_stream_id.c_str()); @@ -651,8 +648,6 @@ int SrsRtspConn::connect() // parse uri if (!req) { - req = new SrsRequest(); - std::string schema, host, vhost, app, port, param; srs_discovery_tc_url(rtsp_tcUrl, schema, host, vhost, app, port, param); @@ -660,19 +655,10 @@ int SrsRtspConn::connect() std::string output = output_template; output = srs_string_replace(output, "[app]", app); output = srs_string_replace(output, "[stream]", rtsp_stream); - - size_t pos = string::npos; - string uri = req->tcUrl = output; - - // tcUrl, stream - if ((pos = uri.rfind("/")) != string::npos) { - req->stream = uri.substr(pos + 1); - req->tcUrl = uri = uri.substr(0, pos); - } - - srs_discovery_tc_url(req->tcUrl, - req->schema, req->host, req->vhost, req->app, req->port, - req->param); + + req = new SrsRequest(); + srs_parse_rtmp_url(output, req->tcUrl, req->stream); + srs_discovery_tc_url(req->tcUrl, req->schema, req->host, req->vhost, req->app, req->port, req->param); } // connect host. diff --git a/trunk/src/app/srs_app_st.hpp b/trunk/src/app/srs_app_st.hpp index ff28c149f..31af7d41f 100644 --- a/trunk/src/app/srs_app_st.hpp +++ b/trunk/src/app/srs_app_st.hpp @@ -202,6 +202,17 @@ public: virtual int writev(const iovec *iov, int iov_size, ssize_t* nwrite); }; +/** + * the common tcp client, to connect to specified TCP server, + * reconnect and close the connection. + */ +class SrsTcpClient +{ +public: + SrsTcpClient(); + virtual ~SrsTcpClient(); +}; + // initialize st, requires epoll. extern int srs_st_init(); diff --git a/trunk/src/kernel/srs_kernel_utility.cpp b/trunk/src/kernel/srs_kernel_utility.cpp index 550c8d2cd..13f863979 100644 --- a/trunk/src/kernel/srs_kernel_utility.cpp +++ b/trunk/src/kernel/srs_kernel_utility.cpp @@ -464,6 +464,29 @@ string srs_path_basename(string path) return dirname; } + +string srs_path_filename(string path) +{ + std::string filename = path; + size_t pos = string::npos; + + if ((pos = filename.rfind(".")) != string::npos) { + return filename.substr(0, pos); + } + + return filename; +} + +string srs_path_filext(string path) +{ + size_t pos = string::npos; + + if ((pos = path.rfind(".")) != string::npos) { + return path.substr(pos); + } + + return ""; +} 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) char* p = bytes; for (;;) { - if (!stream->require(p - bytes + 3)) { + if (!stream->require((int)(p - bytes + 3))) { return false; } diff --git a/trunk/src/kernel/srs_kernel_utility.hpp b/trunk/src/kernel/srs_kernel_utility.hpp index d2bc344ec..4a5bc5cb4 100644 --- a/trunk/src/kernel/srs_kernel_utility.hpp +++ b/trunk/src/kernel/srs_kernel_utility.hpp @@ -96,10 +96,14 @@ extern int srs_create_dir_recursively(std::string dir); // whether path exists. extern bool srs_path_exists(std::string path); -// get the dirname of path +// get the dirname of path, for instance, filename("/live/livestream")="/live" extern std::string srs_path_dirname(std::string path); -// get the basename of path +// get the basename of path, for instance, filename("/live/livestream")="livestream" extern std::string srs_path_basename(std::string path); +// get the filename of path, for instance, filename("livestream.flv")="livestream" +extern std::string srs_path_filename(std::string path); +// get the file extension of path, for instance, filext("live.flv")=".flv" +extern std::string srs_path_filext(std::string path); /** * whether stream starts with the avc NALU in "AnnexB" diff --git a/trunk/src/libs/srs_librtmp.cpp b/trunk/src/libs/srs_librtmp.cpp index d8592d482..e2fa7b9dd 100644 --- a/trunk/src/libs/srs_librtmp.cpp +++ b/trunk/src/libs/srs_librtmp.cpp @@ -464,16 +464,9 @@ int srs_librtmp_context_parse_uri(Context* context) { int ret = ERROR_SUCCESS; - // parse uri - size_t pos = string::npos; - string uri = context->url; - // tcUrl, stream - if ((pos = uri.rfind("/")) != string::npos) { - context->stream = uri.substr(pos + 1); - context->tcUrl = uri = uri.substr(0, pos); - } - std::string schema; + + srs_parse_rtmp_url(context->url, context->tcUrl, context->stream); srs_discovery_tc_url(context->tcUrl, schema, context->host, context->vhost, context->app, context->port, context->param); diff --git a/trunk/src/protocol/srs_http_stack.cpp b/trunk/src/protocol/srs_http_stack.cpp index b19c8519b..3c88fc44c 100755 --- a/trunk/src/protocol/srs_http_stack.cpp +++ b/trunk/src/protocol/srs_http_stack.cpp @@ -377,11 +377,7 @@ int SrsHttpFileServer::serve_file(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, } if (true) { - size_t pos; - std::string ext = fullpath; - if ((pos = ext.rfind(".")) != string::npos) { - ext = ext.substr(pos); - } + std::string ext = srs_path_filext(fullpath); if (_mime.find(ext) == _mime.end()) { w->header()->set_content_type("application/octet-stream"); diff --git a/trunk/src/protocol/srs_protocol_utility.cpp b/trunk/src/protocol/srs_protocol_utility.cpp index 682f92602..09cfd6b5c 100644 --- a/trunk/src/protocol/srs_protocol_utility.cpp +++ b/trunk/src/protocol/srs_protocol_utility.cpp @@ -44,7 +44,7 @@ using namespace std; void srs_discovery_tc_url( string tcUrl, string& schema, string& host, string& vhost, - string& app, int& port, std::string& param + string& app, int& port, string& param ) { size_t pos = std::string::npos; std::string url = tcUrl; @@ -229,7 +229,7 @@ int srs_rtmp_create_msg(char type, u_int32_t timestamp, char* data, int size, in return ret; } -std::string srs_generate_stream_url(std::string vhost, std::string app, std::string stream) +string srs_generate_stream_url(string vhost, string app, string stream) { std::string url = ""; @@ -244,6 +244,18 @@ std::string srs_generate_stream_url(std::string vhost, std::string app, std::str return url; } +void srs_parse_rtmp_url(string url, string& tcUrl, string& stream) +{ + size_t pos; + + if ((pos = url.rfind("/")) != string::npos) { + stream = url.substr(pos + 1); + tcUrl = url.substr(0, pos); + } else { + tcUrl = url; + } +} + string srs_generate_rtmp_url(string server, int port, string vhost, string app, string stream) { std::stringstream ss; diff --git a/trunk/src/protocol/srs_protocol_utility.hpp b/trunk/src/protocol/srs_protocol_utility.hpp index f3650f0a9..d2ce19068 100644 --- a/trunk/src/protocol/srs_protocol_utility.hpp +++ b/trunk/src/protocol/srs_protocol_utility.hpp @@ -101,16 +101,34 @@ extern bool srs_bytes_equals(void* pa, void* pb, int size); * @param data the packet bytes. user should never free it. * @param ppmsg output the shared ptr message. user should free it. */ -extern int srs_rtmp_create_msg(char type, u_int32_t timestamp, char* data, int size, int stream_id, SrsSharedPtrMessage** ppmsg); +extern int srs_rtmp_create_msg( + char type, u_int32_t timestamp, char* data, int size, int stream_id, + SrsSharedPtrMessage** ppmsg +); // get the stream identify, vhost/app/stream. -extern std::string srs_generate_stream_url(std::string vhost, std::string app, std::string stream); +extern std::string srs_generate_stream_url( + std::string vhost, std::string app, std::string stream +); + +// parse the rtmp url to tcUrl/stream, +// for example, rtmp://v.ossrs.net/live/livestream to +// tcUrl: rtmp://v.ossrs.net/live +// stream: livestream +extern void srs_parse_rtmp_url( + std::string url, std::string& tcUrl, std::string& stream +); // genereate the rtmp url, for instance, rtmp://server:port/app...vhost...vhost/stream -extern std::string srs_generate_rtmp_url(std::string server, int port, std::string vhost, std::string app, std::string stream); +extern std::string srs_generate_rtmp_url( + std::string server, int port, std::string vhost, std::string app, std::string stream +); // write large numbers of iovs. -extern int srs_write_large_iovs(ISrsProtocolReaderWriter* skt, iovec* iovs, int size, ssize_t* pnwrite = NULL); +extern int srs_write_large_iovs( + ISrsProtocolReaderWriter* skt, iovec* iovs, int size, + ssize_t* pnwrite = NULL +); #endif diff --git a/trunk/src/protocol/srs_rtsp_stack.cpp b/trunk/src/protocol/srs_rtsp_stack.cpp index 772957fee..0987c7d9d 100644 --- a/trunk/src/protocol/srs_rtsp_stack.cpp +++ b/trunk/src/protocol/srs_rtsp_stack.cpp @@ -988,10 +988,7 @@ int SrsRtspStack::do_recv_message(SrsRtspRequest* req) // for setup, parse the stream id from uri. if (req->is_setup()) { size_t pos = string::npos; - std::string stream_id; - if ((pos = req->uri.rfind("/")) != string::npos) { - stream_id = req->uri.substr(pos + 1); - } + std::string stream_id = srs_path_basename(req->uri); if ((pos = stream_id.find("=")) != string::npos) { stream_id = stream_id.substr(pos + 1); }