Skip to content

Commit

Permalink
for ossrs#324, refine code for hstrs, support hijack handler.
Browse files Browse the repository at this point in the history
  • Loading branch information
winlinvip committed Mar 14, 2015
1 parent 5c6ef6d commit 995b130
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 9 deletions.
54 changes: 54 additions & 0 deletions trunk/src/app/srs_app_http.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,14 @@ SrsHttpMuxEntry::~SrsHttpMuxEntry()
srs_freep(handler);
}

ISrsHttpMatchHijacker::ISrsHttpMatchHijacker()
{
}

ISrsHttpMatchHijacker::~ISrsHttpMatchHijacker()
{
}

SrsHttpServeMux::SrsHttpServeMux()
{
}
Expand All @@ -509,6 +517,7 @@ SrsHttpServeMux::~SrsHttpServeMux()
entries.clear();

vhosts.clear();
hijackers.clear();
}

int SrsHttpServeMux::initialize()
Expand All @@ -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;
Expand Down Expand Up @@ -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();
}

Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
Expand Down
32 changes: 32 additions & 0 deletions trunk/src/app/srs_app_http.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ class SrsHttpFileServer : public ISrsHttpHandler
};

// the mux entry for server mux.
// the matcher info, for example, the pattern and handler.
class SrsHttpMuxEntry
{
public:
Expand All @@ -300,6 +301,23 @@ class SrsHttpMuxEntry
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
Expand Down Expand Up @@ -338,6 +356,10 @@ class SrsHttpServeMux
// 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();
Expand All @@ -346,6 +368,11 @@ class SrsHttpServeMux
* 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.
Expand Down Expand Up @@ -442,6 +469,10 @@ class SrsHttpMessage
*/
std::string _url;
/**
* the extension of file, for example, .flv
*/
std::string _ext;
/**
* parsed http header.
*/
http_parser _header;
Expand Down Expand Up @@ -505,6 +536,7 @@ class SrsHttpMessage
virtual std::string url();
virtual std::string host();
virtual std::string path();
virtual std::string ext();
public:
/**
* read body to string.
Expand Down
70 changes: 65 additions & 5 deletions trunk/src/app/srs_app_http_conn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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());
Expand Down
25 changes: 21 additions & 4 deletions trunk/src/app/srs_app_http_conn.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,14 +252,27 @@ class SrsLiveStream : public ISrsHttpHandler
*/
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();
};

/**
Expand Down Expand Up @@ -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;
Expand All @@ -346,6 +360,9 @@ class SrsHttpServer : public ISrsReloadHandler
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();
Expand Down

0 comments on commit 995b130

Please sign in to comment.