int SrsDvrPlan::open_new_segment()
{
    int ret = ERROR_SUCCESS;
    
    SrsRequest* req = _req;
    
    // new flv file
    std::stringstream path;
    
    path << _srs_config->get_dvr_path(req->vhost)
        << "/" << req->app << "/" 
        << req->stream << "." << srs_get_system_time_ms() << ".flv";
    
    if ((ret = flv_open(req->get_stream_url(), path.str())) != ERROR_SUCCESS) {
        return ret;
    }
    dvr_enabled = true;
    
    return ret;
}
int SrsHttpStreamServer::on_reload_vhost_http_remux_updated(string vhost)
{
    int ret = ERROR_SUCCESS;

    if (tflvs.find(vhost) == tflvs.end()) {
        if ((ret = initialize_flv_entry(vhost)) != ERROR_SUCCESS) {
            return ret;
        }

        // http mount need SrsRequest and SrsSource param, only create a mapping template entry
        // and do mount automatically on playing http flv if this stream is a new http_remux stream.
        return ret;
    }

    SrsLiveEntry* tmpl = tflvs[vhost];
    SrsRequest* req = tmpl->req;
    SrsSource* source = tmpl->source;

    if (source && req) {
        // cleanup the exists http remux.
        http_unmount(source, req);
    }

    if (!_srs_config->get_vhost_http_remux_enabled(vhost)) {
        return ret;
    }

    string old_tmpl_mount = tmpl->mount;
    string new_tmpl_mount = _srs_config->get_vhost_http_remux_mount(vhost);
    bool hstrs = _srs_config->get_vhost_http_remux_hstrs(vhost);

    tmpl->reset_hstrs(hstrs);

    /**
     * TODO: not support to reload different mount url for the time being.
     * if the mount is change, need more logical thing to deal with.
     * such as erase stream from sflvs and free all related resource.
     */
    srs_assert(old_tmpl_mount == new_tmpl_mount);

    // do http mount directly with SrsRequest and SrsSource if stream is played already.
    if (req) {
        std::string sid = req->get_stream_url();

        if (sflvs.find(sid) != sflvs.end()) {
            SrsLiveEntry* stream = sflvs[sid];
            stream->reset_hstrs(hstrs);
        }
        // remount stream.
        if ((ret = http_mount(source, req)) != ERROR_SUCCESS) {
            srs_trace("vhost %s http_remux reload failed", vhost.c_str());
            return ret;
        }
    } else {
        // for without SrsRequest and SrsSource if stream is not played yet, do http mount automatically
        // when start play this http flv stream.
    }

    srs_trace("vhost %s http_remux reload success", vhost.c_str());

    return ret;
}
int SrsHttpStreamServer::hijack(ISrsHttpMessage* request, ISrsHttpHandler** ph)
{
    int ret = ERROR_SUCCESS;
    
    // when handler not the root, we think the handler is ok.
    ISrsHttpHandler* h = *ph? *ph : NULL;
    if (h && h->entry && h->entry->pattern != "/") {
        return ret;
    }
    
    // only hijack for http streaming, http-flv/ts/mp3/aac.
    std::string ext = request->ext();
    if (ext.empty()) {
        return ret;
    }

    // find the actually request vhost.
    SrsConfDirective* vhost = _srs_config->get_vhost(request->host());
    if (!vhost || !_srs_config->get_vhost_enabled(vhost)) {
        return ret;
    }
    
    // find the entry template for the stream.
    SrsLiveEntry* entry = NULL;
    if (true) {
        // no http streaming on vhost, ignore.
        std::map<std::string, SrsLiveEntry*>::iterator it = tflvs.find(vhost->arg0());
        if (it == tflvs.end()) {
            return ret;
        }
        
        // hstrs not enabled, ignore.
        // for origin, the http stream will be mount already when publish,
        //      so it must never enter this line for stream already mounted.
        // for edge, the http stream is trigger by hstrs and mount by it,
        //      so we only hijack when only edge and hstrs is on.
        entry = it->second;
        if (!entry->hstrs) {
            return ret;
        }

        // check entry and request extension.
        if (entry->is_flv()) {
            if (ext != ".flv") {
                return ret;
            }
        } else if (entry->is_ts()) {
            if (ext != ".ts") {
                return ret;
            }
        } else if (entry->is_mp3()) {
            if (ext != ".mp3") {
                return ret;
            }
        } else if (entry->is_aac()) {
            if (ext != ".aac") {
                return ret;
            }
        } else {
            return ret;
        }
    }

    // convert to concreate class.
    SrsHttpMessage* hreq = dynamic_cast<SrsHttpMessage*>(request);
    srs_assert(hreq);
    
    // hijack for entry.
    SrsRequest* r = hreq->to_request(vhost->arg0());
    SrsAutoFree(SrsRequest, r);

    std::string sid = r->get_stream_url();
    // check whether the http remux is enabled,
    // for example, user disable the http flv then reload.
    if (sflvs.find(sid) != sflvs.end()) {
        SrsLiveEntry* s_entry = sflvs[sid];
        if (!s_entry->stream->entry->enabled) {
            // only when the http entry is disabled, check the config whether http flv disable,
            // for the http flv edge use hijack to trigger the edge ingester, we always mount it
            // eventhough the origin does not exists the specified stream.
            if (!_srs_config->get_vhost_http_remux_enabled(r->vhost)) {
                srs_error("stream is disabled, hijack failed. ret=%d", ret);
                return ret;
            }
        }
    }

    SrsSource* s = SrsSource::fetch(r);
    if (!s) {
        if ((ret = SrsSource::create(r, server, server, &s)) != ERROR_SUCCESS) {
            return ret;
        }
    }
    srs_assert(s != NULL);

    // create http streaming handler.
    if ((ret = http_mount(s, r)) != ERROR_SUCCESS) {
        return ret;
    }

    // use the handler if exists.
    if (ph) {
        if (sflvs.find(sid) != sflvs.end()) {
            entry = sflvs[sid];
            *ph = entry->stream;
        }
    }
    
    // trigger edge to fetch from origin.
    bool vhost_is_edge = _srs_config->get_vhost_is_edge(r->vhost);
    srs_trace("hstrs: source url=%s, is_edge=%d, source_id=%d[%d]",
        r->get_stream_url().c_str(), vhost_is_edge, s->source_id(), s->source_id());
    
    return ret;
}