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());
}