the http server, use http stream or static server to serve requests.
源代码位置:
app\srs_app_http_conn.hpp
app\srs_app_http_conn.cpp
class SrsHttpServer : public ISrsHttpServeMux { private: SrsServer* server; SrsHttpStaticServer* http_static; SrsHttpStreamServer* http_stream; public: SrsHttpServer(SrsServer* svr); virtual ~SrsHttpServer(); public: virtual int initialize(); // ISrsHttpServeMux public: virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); // http flv/ts/mp3/aac stream public: virtual int http_mount(SrsSource* s, SrsRequest* r); virtual void http_unmount(SrsSource* s, SrsRequest* r); };
SrsHttpServer::SrsHttpServer(SrsServer* svr) { server = svr; http_stream = new SrsHttpStreamServer(svr); http_static = new SrsHttpStaticServer(svr); } SrsHttpServer::~SrsHttpServer() { srs_freep(http_stream); srs_freep(http_static); } int SrsHttpServer::initialize() { int ret = ERROR_SUCCESS; #if defined(SRS_AUTO_HTTP_SERVER) && defined(SRS_AUTO_HTTP_API) // for SRS go-sharp to detect the status of HTTP server of SRS HTTP FLV Cluster. if ((ret = http_static->mux.handle("/api/v1/versions", new SrsGoApiVersion())) != ERROR_SUCCESS) { return ret; }
/*
/api/v1/versions 返回结果
其中server字段是服务器进程的pid
*{"code":0,"server":1967,"data":{"major":2,"minor":0,"revision":239,"version":"2.0.239"}}
*/#endifif ((ret = http_stream->initialize()) != ERROR_SUCCESS) {
return ret;
}
if ((ret = http_static->initialize()) != ERROR_SUCCESS)
{ return ret; } return ret; }
int SrsHttpServer::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) {
// try http stream first. if (http_stream->mux.can_serve(r))
{ return http_stream->mux.serve_http(w, r); }
return http_static->mux.serve_http(w, r); }
int SrsHttpServer::http_mount(SrsSource* s, SrsRequest* r)
{
return http_stream->http_mount(s, r);
}
void SrsHttpServer::http_unmount(SrsSource* s, SrsRequest* r)
{
http_stream->http_unmount(s, r);
}
功能有类SrsHttpStreamServer和SrsHttpStaticServer实现
SrsHttpStreamServer的initialize方法
http_stream->initialize
源码位置 app\srs_app_http_stream.hpp
app\srs_app_http_stream.cpp
int SrsHttpStreamServer::initialize() { int ret = ERROR_SUCCESS; // remux rtmp to flv live streaming if ((ret = initialize_flv_streaming()) != ERROR_SUCCESS) { return ret; } return ret; }
int SrsHttpStreamServer::initialize_flv_streaming() { int ret = ERROR_SUCCESS; // http flv live stream mount for each vhost. SrsConfDirective* root = _srs_config->get_root(); for (int i = 0; i < (int)root->directives.size(); i++) { SrsConfDirective* conf = root->at(i); if (!conf->is_vhost()) { continue; } if ((ret = initialize_flv_entry(conf->arg0())) != ERROR_SUCCESS) { return ret; } } return ret; }
调用 initialize_flv_entry函数,参数是vhost的名称,如__defaultVhost__
int SrsHttpStreamServer::initialize_flv_entry(std::string vhost) { int ret = ERROR_SUCCESS; // vhost 的 http_remux enabled必须为on,否则直接返回 if (!_srs_config->get_vhost_http_remux_enabled(vhost)) { return ret; } SrsLiveEntry* entry = new SrsLiveEntry( _srs_config->get_vhost_http_remux_mount(vhost), _srs_config->get_vhost_http_remux_hstrs(vhost) ); /**
* 成员变量tflvs定义
* the http live streaming template, to create streams.
* std::map<std::string, SrsLiveEntry*> tflvs;
*/
tflvs[vhost] = entry; srs_trace("http flv live stream, vhost=%s, mount=%s", vhost.c_str(), entry->mount.c_str()); return ret; }
SrsLiveEntry的构造函数
SrsLiveEntry::SrsLiveEntry(std::string m, bool h) { mount = m; hstrs = h; stream = NULL; cache = NULL; req = NULL; source = NULL; std::string ext; size_t pos = string::npos; if ((pos = m.rfind(".")) != string::npos) { ext = m.substr(pos); } _is_flv = (ext == ".flv"); _is_ts = (ext == ".ts"); _is_mp3 = (ext == ".mp3"); _is_aac = (ext == ".aac"); }
bool SrsConfig::get_vhost_http_remux_enabled(string vhost) { SrsConfDirective* conf = get_vhost(vhost); if (!conf) { return false; } conf = conf->get("http_remux"); if (!conf) { return false; } conf = conf->get("enabled"); if (!conf || conf->arg0().empty()) { return false; } return SRS_CONF_PERFER_FALSE(conf->arg0()); }
// when user config an invalid value, macros to perfer true or false.
#define SRS_CONF_PERFER_FALSE(conf_arg) conf_arg == "on"
#define SRS_CONF_PERFER_TRUE(conf_arg) conf_arg != "off"
SrsLiveEntry定义
/** * the srs live entry */ struct SrsLiveEntry { private: bool _is_flv; bool _is_ts; bool _is_aac; bool _is_mp3; public: SrsRequest* req; SrsSource* source; public: // for template, the mount contains variables. // for concrete stream, the mount is url to access. std::string mount; // whether hstrs(http stream trigger rtmp source) bool hstrs; SrsLiveStream* stream; SrsStreamCache* cache; SrsLiveEntry(std::string m, bool h); void reset_hstrs(bool h); bool is_flv(); bool is_ts(); bool is_mp3(); bool is_aac(); };
int SrsHttpStaticServer::initialize() { int ret = ERROR_SUCCESS; bool default_root_exists = false; // http static file and flv vod stream mount for each vhost. SrsConfDirective* root = _srs_config->get_root(); for (int i = 0; i < (int)root->directives.size(); i++) { SrsConfDirective* conf = root->at(i); if (!conf->is_vhost()) { continue; } // 检查vhost 的 http 的 enabled标志 std::string vhost = conf->arg0(); if (!_srs_config->get_vhost_http_enabled(vhost)) { continue; } std::string mount = _srs_config->get_vhost_http_mount(vhost); std::string dir = _srs_config->get_vhost_http_dir(vhost); // replace the vhost variable mount = srs_string_replace(mount, "[vhost]", vhost); // remove the default vhost mount mount = srs_string_replace(mount, SRS_CONSTS_RTMP_DEFAULT_VHOST"/", "/"); // the dir mount must always ends with "/" if (mount != "/" && mount.rfind("/") != mount.length() - 1) { mount += "/"; } // mount the http of vhost.
// 若vhost名称是mars.tv,则访问mars/tv/,会定向到dir
if ((ret = mux.handle(mount, new SrsVodStream(dir))) != ERROR_SUCCESS) { srs_error("http: mount dir=%s for vhost=%s failed. ret=%d", dir.c_str(), vhost.c_str(), ret); return ret; } if (mount == "/") { default_root_exists = true; srs_warn("http: root mount to %s", dir.c_str()); } srs_trace("http: vhost=%s mount to %s", vhost.c_str(), mount.c_str()); } if (!default_root_exists) { // add root std::string dir = _srs_config->get_http_stream_dir();
// 对/ 的访问,不针对某个虚拟主机 if ((ret = mux.handle("/", new SrsVodStream(dir))) != ERROR_SUCCESS) { srs_error("http: mount root dir=%s failed. ret=%d", dir.c_str(), ret); return ret; } srs_trace("http: root mount to %s", dir.c_str()); } return ret; }
vhost 的http或http_static 用于静态文件或vod
http_mux用于 http stream
bool SrsConfig::get_vhost_http_enabled(string vhost) { SrsConfDirective* vconf = get_vhost(vhost); if (!vconf) { return false; } SrsConfDirective* conf = vconf->get("http"); if (!conf) { conf = vconf->get("http_static"); } if (!conf) { return false; } conf = conf->get("enabled"); if (!conf || conf->arg0().empty()) { return false; } return SRS_CONF_PERFER_FALSE(conf->arg0()); }