1
0
Fork 0
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:
winlin 2015-03-14 14:55:45 +08:00
parent 5c6ef6ded6
commit 995b130090
4 changed files with 172 additions and 9 deletions

View file

@ -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;

View file

@ -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.

View file

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

View file

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