mirror of
https://github.com/ossrs/srs.git
synced 2025-02-15 04:42:04 +00:00
for #324, refine code for hstrs, support hijack handler.
This commit is contained in:
parent
5c6ef6ded6
commit
995b130090
4 changed files with 172 additions and 9 deletions
|
@ -495,6 +495,14 @@ SrsHttpMuxEntry::~SrsHttpMuxEntry()
|
|||
srs_freep(handler);
|
||||
}
|
||||
|
||||
ISrsHttpMatchHijacker::ISrsHttpMatchHijacker()
|
||||
{
|
||||
}
|
||||
|
||||
ISrsHttpMatchHijacker::~ISrsHttpMatchHijacker()
|
||||
{
|
||||
}
|
||||
|
||||
SrsHttpServeMux::SrsHttpServeMux()
|
||||
{
|
||||
}
|
||||
|
@ -509,6 +517,7 @@ SrsHttpServeMux::~SrsHttpServeMux()
|
|||
entries.clear();
|
||||
|
||||
vhosts.clear();
|
||||
hijackers.clear();
|
||||
}
|
||||
|
||||
int SrsHttpServeMux::initialize()
|
||||
|
@ -518,6 +527,24 @@ int SrsHttpServeMux::initialize()
|
|||
return ret;
|
||||
}
|
||||
|
||||
void SrsHttpServeMux::hijack(ISrsHttpMatchHijacker* h)
|
||||
{
|
||||
std::vector<ISrsHttpMatchHijacker*>::iterator it = ::find(hijackers.begin(), hijackers.end(), h);
|
||||
if (it != hijackers.end()) {
|
||||
return;
|
||||
}
|
||||
hijackers.push_back(h);
|
||||
}
|
||||
|
||||
void SrsHttpServeMux::unhijack(ISrsHttpMatchHijacker* h)
|
||||
{
|
||||
std::vector<ISrsHttpMatchHijacker*>::iterator it = ::find(hijackers.begin(), hijackers.end(), h);
|
||||
if (it == hijackers.end()) {
|
||||
return;
|
||||
}
|
||||
hijackers.erase(it);
|
||||
}
|
||||
|
||||
int SrsHttpServeMux::handle(std::string pattern, ISrsHttpHandler* handler)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
@ -629,8 +656,22 @@ int SrsHttpServeMux::find_handler(SrsHttpMessage* r, ISrsHttpHandler** ph)
|
|||
srs_error("http match handler failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// always hijack.
|
||||
if (!hijackers.empty()) {
|
||||
// notice all hijacker the match failed.
|
||||
std::vector<ISrsHttpMatchHijacker*>::iterator it;
|
||||
for (it = hijackers.begin(); it != hijackers.end(); ++it) {
|
||||
ISrsHttpMatchHijacker* hijacker = *it;
|
||||
if ((ret = hijacker->hijack(r, ph)) != ERROR_SUCCESS) {
|
||||
srs_error("hijacker match failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (*ph == NULL) {
|
||||
// TODO: FIXME: memory leak.
|
||||
*ph = new SrsHttpNotFoundHandler();
|
||||
}
|
||||
|
||||
|
@ -1066,6 +1107,14 @@ int SrsHttpMessage::update(string url, http_parser* header, SrsFastBuffer* body,
|
|||
_query[k] = v;
|
||||
}
|
||||
|
||||
// parse ext.
|
||||
_ext = _uri->get_path();
|
||||
if ((pos = _ext.rfind(".")) != string::npos) {
|
||||
_ext = _ext.substr(pos);
|
||||
} else {
|
||||
_ext = "";
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1162,6 +1211,11 @@ string SrsHttpMessage::path()
|
|||
return _uri->get_path();
|
||||
}
|
||||
|
||||
string SrsHttpMessage::ext()
|
||||
{
|
||||
return _ext;
|
||||
}
|
||||
|
||||
int SrsHttpMessage::body_read_all(string& body)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
|
|
@ -288,6 +288,7 @@ protected:
|
|||
};
|
||||
|
||||
// the mux entry for server mux.
|
||||
// the matcher info, for example, the pattern and handler.
|
||||
class SrsHttpMuxEntry
|
||||
{
|
||||
public:
|
||||
|
@ -300,6 +301,23 @@ public:
|
|||
virtual ~SrsHttpMuxEntry();
|
||||
};
|
||||
|
||||
/**
|
||||
* the hijacker for http pattern match.
|
||||
*/
|
||||
class ISrsHttpMatchHijacker
|
||||
{
|
||||
public:
|
||||
ISrsHttpMatchHijacker();
|
||||
virtual ~ISrsHttpMatchHijacker();
|
||||
public:
|
||||
/**
|
||||
* when match the request failed, no handler to process request.
|
||||
* @param request the http request message to match the handler.
|
||||
* @param ph the already matched handler, hijack can rewrite it.
|
||||
*/
|
||||
virtual int hijack(SrsHttpMessage* request, ISrsHttpHandler** ph) = 0;
|
||||
};
|
||||
|
||||
// ServeMux is an HTTP request multiplexer.
|
||||
// It matches the URL of each incoming request against a list of registered
|
||||
// patterns and calls the handler for the pattern that
|
||||
|
@ -338,6 +356,10 @@ private:
|
|||
// for example, for pattern /live/livestream.flv of vhost ossrs.net,
|
||||
// the path will rewrite to ossrs.net/live/livestream.flv
|
||||
std::map<std::string, ISrsHttpHandler*> vhosts;
|
||||
// all hijackers for http match.
|
||||
// for example, the hstrs(http stream trigger rtmp source)
|
||||
// can hijack and install handler when request incoming and no handler.
|
||||
std::vector<ISrsHttpMatchHijacker*> hijackers;
|
||||
public:
|
||||
SrsHttpServeMux();
|
||||
virtual ~SrsHttpServeMux();
|
||||
|
@ -346,6 +368,11 @@ public:
|
|||
* initialize the http serve mux.
|
||||
*/
|
||||
virtual int initialize();
|
||||
/**
|
||||
* hijack the http match.
|
||||
*/
|
||||
virtual void hijack(ISrsHttpMatchHijacker* h);
|
||||
virtual void unhijack(ISrsHttpMatchHijacker* h);
|
||||
public:
|
||||
// Handle registers the handler for the given pattern.
|
||||
// If a handler already exists for pattern, Handle panics.
|
||||
|
@ -442,6 +469,10 @@ private:
|
|||
*/
|
||||
std::string _url;
|
||||
/**
|
||||
* the extension of file, for example, .flv
|
||||
*/
|
||||
std::string _ext;
|
||||
/**
|
||||
* parsed http header.
|
||||
*/
|
||||
http_parser _header;
|
||||
|
@ -505,6 +536,7 @@ public:
|
|||
virtual std::string url();
|
||||
virtual std::string host();
|
||||
virtual std::string path();
|
||||
virtual std::string ext();
|
||||
public:
|
||||
/**
|
||||
* read body to string.
|
||||
|
|
|
@ -689,10 +689,43 @@ int SrsLiveStream::streaming_send_messages(ISrsStreamEncoder* enc, SrsSharedPtrM
|
|||
return ret;
|
||||
}
|
||||
|
||||
SrsLiveEntry::SrsLiveEntry()
|
||||
SrsLiveEntry::SrsLiveEntry(std::string m, bool h)
|
||||
{
|
||||
mount = m;
|
||||
hstrs = h;
|
||||
|
||||
stream = NULL;
|
||||
cache = 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 SrsLiveEntry::is_flv()
|
||||
{
|
||||
return _is_flv;
|
||||
}
|
||||
|
||||
bool SrsLiveEntry::is_ts()
|
||||
{
|
||||
return _is_ts;
|
||||
}
|
||||
|
||||
bool SrsLiveEntry::is_aac()
|
||||
{
|
||||
return _is_aac;
|
||||
}
|
||||
|
||||
bool SrsLiveEntry::is_mp3()
|
||||
{
|
||||
return _is_mp3;
|
||||
}
|
||||
|
||||
SrsHlsM3u8Stream::SrsHlsM3u8Stream()
|
||||
|
@ -765,10 +798,13 @@ SrsHlsEntry::SrsHlsEntry()
|
|||
|
||||
SrsHttpServer::SrsHttpServer()
|
||||
{
|
||||
mux.hijack(this);
|
||||
}
|
||||
|
||||
SrsHttpServer::~SrsHttpServer()
|
||||
{
|
||||
mux.unhijack(this);
|
||||
|
||||
if (true) {
|
||||
std::map<std::string, SrsLiveEntry*>::iterator it;
|
||||
for (it = tflvs.begin(); it != tflvs.end(); ++it) {
|
||||
|
@ -853,8 +889,7 @@ int SrsHttpServer::http_mount(SrsSource* s, SrsRequest* r)
|
|||
// remove the default vhost mount
|
||||
mount = srs_string_replace(mount, SRS_CONSTS_RTMP_DEFAULT_VHOST"/", "/");
|
||||
|
||||
entry = new SrsLiveEntry();
|
||||
entry->mount = mount;
|
||||
entry = new SrsLiveEntry(mount, tmpl->hstrs);
|
||||
|
||||
entry->cache = new SrsStreamCache(s, r);
|
||||
entry->stream = new SrsLiveStream(s, r, entry->cache);
|
||||
|
@ -1060,6 +1095,29 @@ int SrsHttpServer::on_reload_vhost_hls(string vhost)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int SrsHttpServer::hijack(SrsHttpMessage* 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->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;
|
||||
}
|
||||
if (ext != ".flv" && ext != ".ts" && ext != ".mp3" && ext != ".aac") {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// TODO: FIXME: implements it.
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsHttpServer::initialize_static_file()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
@ -1138,8 +1196,10 @@ int SrsHttpServer::initialize_flv_streaming()
|
|||
continue;
|
||||
}
|
||||
|
||||
SrsLiveEntry* entry = new SrsLiveEntry();
|
||||
entry->mount = _srs_config->get_vhost_http_remux_mount(vhost);
|
||||
SrsLiveEntry* entry = new SrsLiveEntry(
|
||||
_srs_config->get_vhost_http_remux_mount(vhost),
|
||||
_srs_config->get_vhost_http_remux_hstrs(vhost)
|
||||
);
|
||||
tflvs[vhost] = entry;
|
||||
srs_trace("http flv live stream, vhost=%s, mount=%s",
|
||||
vhost.c_str(), entry->mount.c_str());
|
||||
|
|
|
@ -252,14 +252,27 @@ private:
|
|||
*/
|
||||
struct SrsLiveEntry
|
||||
{
|
||||
private:
|
||||
bool _is_flv;
|
||||
bool _is_ts;
|
||||
bool _is_aac;
|
||||
bool _is_mp3;
|
||||
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();
|
||||
SrsLiveEntry(std::string m, bool h);
|
||||
|
||||
bool is_flv();
|
||||
bool is_ts();
|
||||
bool is_mp3();
|
||||
bool is_aac();
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -314,13 +327,14 @@ struct SrsHlsEntry
|
|||
* the http server instance,
|
||||
* serve http static file, flv vod stream and flv live stream.
|
||||
*/
|
||||
class SrsHttpServer : public ISrsReloadHandler
|
||||
class SrsHttpServer : virtual public ISrsReloadHandler
|
||||
, virtual public ISrsHttpMatchHijacker
|
||||
{
|
||||
public:
|
||||
SrsHttpServeMux mux;
|
||||
// the flv live streaming template, to create streams.
|
||||
// the http live streaming template, to create streams.
|
||||
std::map<std::string, SrsLiveEntry*> tflvs;
|
||||
// the flv live streaming streams, crote by template.
|
||||
// the http live streaming streams, crote by template.
|
||||
std::map<std::string, SrsLiveEntry*> sflvs;
|
||||
// the hls live streaming template, to create streams.
|
||||
std::map<std::string, SrsHlsEntry*> thls;
|
||||
|
@ -346,6 +360,9 @@ public:
|
|||
virtual int on_reload_vhost_http_updated();
|
||||
virtual int on_reload_vhost_http_remux_updated();
|
||||
virtual int on_reload_vhost_hls(std::string vhost);
|
||||
// interface ISrsHttpMatchHijacker
|
||||
public:
|
||||
virtual int hijack(SrsHttpMessage* request, ISrsHttpHandler** ph);
|
||||
private:
|
||||
virtual int initialize_static_file();
|
||||
virtual int initialize_flv_streaming();
|
||||
|
|
Loading…
Reference in a new issue