mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
add http delivery framework
This commit is contained in:
parent
8d7877ebd1
commit
83f35d10b1
7 changed files with 316 additions and 63 deletions
|
@ -85,13 +85,6 @@ http_stream {
|
||||||
# for example, user use ip to access the stream: rtmp://192.168.1.2/live/livestream.
|
# for example, user use ip to access the stream: rtmp://192.168.1.2/live/livestream.
|
||||||
# for which cannot identify the required vhost.
|
# for which cannot identify the required vhost.
|
||||||
vhost __defaultVhost__ {
|
vhost __defaultVhost__ {
|
||||||
enabled on;
|
|
||||||
gop_cache on;
|
|
||||||
http {
|
|
||||||
enabled on;
|
|
||||||
mount /;
|
|
||||||
dir ./objs/nginx/html;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# vhost for http
|
# vhost for http
|
||||||
|
@ -103,9 +96,11 @@ vhost http.srs.com {
|
||||||
enabled on;
|
enabled on;
|
||||||
# the virtual directory root for this vhost to mount at
|
# the virtual directory root for this vhost to mount at
|
||||||
# for example, if mount to /hls, user access by http://server/hls
|
# for example, if mount to /hls, user access by http://server/hls
|
||||||
|
# default: /
|
||||||
mount /hls;
|
mount /hls;
|
||||||
# main dir of vhost,
|
# main dir of vhost,
|
||||||
# to delivery HTTP stream of this vhost.
|
# to delivery HTTP stream of this vhost.
|
||||||
|
# default: ./objs/nginx/html
|
||||||
dir ./objs/nginx/html;
|
dir ./objs/nginx/html;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -286,7 +286,7 @@ int SrsConfDirective::parse_conf(SrsFileBuffer* buffer, SrsDirectiveType type)
|
||||||
}
|
}
|
||||||
|
|
||||||
// see: ngx_conf_read_token
|
// see: ngx_conf_read_token
|
||||||
int SrsConfDirective::read_token(SrsFileBuffer* buffer, std::vector<string>& args)
|
int SrsConfDirective::read_token(SrsFileBuffer* buffer, vector<string>& args)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
@ -427,6 +427,11 @@ int SrsConfDirective::read_token(SrsFileBuffer* buffer, std::vector<string>& arg
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SrsConfDirective::is_vhost()
|
||||||
|
{
|
||||||
|
return name == "vhost";
|
||||||
|
}
|
||||||
|
|
||||||
SrsConfig::SrsConfig()
|
SrsConfig::SrsConfig()
|
||||||
{
|
{
|
||||||
show_help = false;
|
show_help = false;
|
||||||
|
@ -777,6 +782,11 @@ bool SrsConfig::get_deamon()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SrsConfDirective* SrsConfig::get_root()
|
||||||
|
{
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
int SrsConfig::get_max_connections()
|
int SrsConfig::get_max_connections()
|
||||||
{
|
{
|
||||||
srs_assert(root);
|
srs_assert(root);
|
||||||
|
@ -835,6 +845,21 @@ int SrsConfig::get_pithy_print_forwarder()
|
||||||
return ::atoi(pithy->arg0().c_str());
|
return ::atoi(pithy->arg0().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SrsConfig::get_pithy_print_encoder()
|
||||||
|
{
|
||||||
|
SrsConfDirective* pithy = root->get("encoder");
|
||||||
|
if (!pithy) {
|
||||||
|
return SRS_STAGE_ENCODER_INTERVAL_MS;
|
||||||
|
}
|
||||||
|
|
||||||
|
pithy = pithy->get("forwarder");
|
||||||
|
if (!pithy) {
|
||||||
|
return SRS_STAGE_ENCODER_INTERVAL_MS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ::atoi(pithy->arg0().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
int SrsConfig::get_pithy_print_hls()
|
int SrsConfig::get_pithy_print_hls()
|
||||||
{
|
{
|
||||||
SrsConfDirective* pithy = root->get("pithy_print");
|
SrsConfDirective* pithy = root->get("pithy_print");
|
||||||
|
@ -850,6 +875,21 @@ int SrsConfig::get_pithy_print_hls()
|
||||||
return ::atoi(pithy->arg0().c_str());
|
return ::atoi(pithy->arg0().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SrsConfig::get_pithy_print_play()
|
||||||
|
{
|
||||||
|
SrsConfDirective* pithy = root->get("pithy_print");
|
||||||
|
if (!pithy) {
|
||||||
|
return SRS_STAGE_PLAY_USER_INTERVAL_MS;
|
||||||
|
}
|
||||||
|
|
||||||
|
pithy = pithy->get("play");
|
||||||
|
if (!pithy) {
|
||||||
|
return SRS_STAGE_PLAY_USER_INTERVAL_MS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ::atoi(pithy->arg0().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
SrsConfDirective* SrsConfig::get_vhost(string vhost)
|
SrsConfDirective* SrsConfig::get_vhost(string vhost)
|
||||||
{
|
{
|
||||||
srs_assert(root);
|
srs_assert(root);
|
||||||
|
@ -857,7 +897,7 @@ SrsConfDirective* SrsConfig::get_vhost(string vhost)
|
||||||
for (int i = 0; i < (int)root->directives.size(); i++) {
|
for (int i = 0; i < (int)root->directives.size(); i++) {
|
||||||
SrsConfDirective* conf = root->at(i);
|
SrsConfDirective* conf = root->at(i);
|
||||||
|
|
||||||
if (conf->name != "vhost") {
|
if (!conf->is_vhost()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1116,7 +1156,7 @@ SrsConfDirective* SrsConfig::get_refer_publish(string vhost)
|
||||||
return conf->get("refer_publish");
|
return conf->get("refer_publish");
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsConfig::get_chunk_size(const std::string &vhost)
|
int SrsConfig::get_chunk_size(const string &vhost)
|
||||||
{
|
{
|
||||||
SrsConfDirective* conf = get_vhost(vhost);
|
SrsConfDirective* conf = get_vhost(vhost);
|
||||||
|
|
||||||
|
@ -1271,7 +1311,7 @@ string SrsConfig::get_transcode_ffmpeg(SrsConfDirective* transcode)
|
||||||
return conf->arg0();
|
return conf->arg0();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SrsConfig::get_transcode_engines(SrsConfDirective* transcode, std::vector<SrsConfDirective*>& engines)
|
void SrsConfig::get_transcode_engines(SrsConfDirective* transcode, vector<SrsConfDirective*>& engines)
|
||||||
{
|
{
|
||||||
if (!transcode) {
|
if (!transcode) {
|
||||||
return;
|
return;
|
||||||
|
@ -1414,7 +1454,7 @@ string SrsConfig::get_engine_vpreset(SrsConfDirective* engine)
|
||||||
return conf->arg0();
|
return conf->arg0();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SrsConfig::get_engine_vparams(SrsConfDirective* engine, std::vector<string>& vparams)
|
void SrsConfig::get_engine_vparams(SrsConfDirective* engine, vector<string>& vparams)
|
||||||
{
|
{
|
||||||
if (!engine) {
|
if (!engine) {
|
||||||
return;
|
return;
|
||||||
|
@ -1436,7 +1476,7 @@ void SrsConfig::get_engine_vparams(SrsConfDirective* engine, std::vector<string>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SrsConfig::get_engine_vfilter(SrsConfDirective* engine, std::vector<string>& vfilter)
|
void SrsConfig::get_engine_vfilter(SrsConfDirective* engine, vector<string>& vfilter)
|
||||||
{
|
{
|
||||||
if (!engine) {
|
if (!engine) {
|
||||||
return;
|
return;
|
||||||
|
@ -1514,7 +1554,7 @@ int SrsConfig::get_engine_achannels(SrsConfDirective* engine)
|
||||||
return ::atoi(conf->arg0().c_str());
|
return ::atoi(conf->arg0().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SrsConfig::get_engine_aparams(SrsConfDirective* engine, std::vector<string>& aparams)
|
void SrsConfig::get_engine_aparams(SrsConfDirective* engine, vector<string>& aparams)
|
||||||
{
|
{
|
||||||
if (!engine) {
|
if (!engine) {
|
||||||
return;
|
return;
|
||||||
|
@ -1754,34 +1794,68 @@ int SrsConfig::get_http_stream_listen()
|
||||||
return 8080;
|
return 8080;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsConfig::get_pithy_print_encoder()
|
bool SrsConfig::get_vhost_http_enabled(string vhost)
|
||||||
{
|
{
|
||||||
SrsConfDirective* pithy = root->get("encoder");
|
SrsConfDirective* conf = get_vhost(vhost);
|
||||||
if (!pithy) {
|
if (!conf) {
|
||||||
return SRS_STAGE_ENCODER_INTERVAL_MS;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
pithy = pithy->get("forwarder");
|
conf = conf->get("http");
|
||||||
if (!pithy) {
|
if (!conf) {
|
||||||
return SRS_STAGE_ENCODER_INTERVAL_MS;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ::atoi(pithy->arg0().c_str());
|
conf = conf->get("enabled");
|
||||||
|
if (!conf) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conf->arg0() == "on") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsConfig::get_pithy_print_play()
|
string SrsConfig::get_vhost_http_mount(string vhost)
|
||||||
{
|
{
|
||||||
SrsConfDirective* pithy = root->get("pithy_print");
|
SrsConfDirective* conf = get_vhost(vhost);
|
||||||
if (!pithy) {
|
if (!conf) {
|
||||||
return SRS_STAGE_PLAY_USER_INTERVAL_MS;
|
return SRS_CONF_DEFAULT_HTTP_MOUNT;
|
||||||
}
|
}
|
||||||
|
|
||||||
pithy = pithy->get("play");
|
conf = conf->get("http");
|
||||||
if (!pithy) {
|
if (!conf) {
|
||||||
return SRS_STAGE_PLAY_USER_INTERVAL_MS;
|
return SRS_CONF_DEFAULT_HTTP_MOUNT;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ::atoi(pithy->arg0().c_str());
|
conf = conf->get("mount");
|
||||||
|
if (!conf || conf->arg0().empty()) {
|
||||||
|
return SRS_CONF_DEFAULT_HTTP_MOUNT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return conf->arg0();
|
||||||
|
}
|
||||||
|
|
||||||
|
string SrsConfig::get_vhost_http_dir(string vhost)
|
||||||
|
{
|
||||||
|
SrsConfDirective* conf = get_vhost(vhost);
|
||||||
|
if (!conf) {
|
||||||
|
return SRS_CONF_DEFAULT_HTTP_DIR;
|
||||||
|
}
|
||||||
|
|
||||||
|
conf = conf->get("http");
|
||||||
|
if (!conf) {
|
||||||
|
return SRS_CONF_DEFAULT_HTTP_DIR;
|
||||||
|
}
|
||||||
|
|
||||||
|
conf = conf->get("dir");
|
||||||
|
if (!conf || conf->arg0().empty()) {
|
||||||
|
return SRS_CONF_DEFAULT_HTTP_DIR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return conf->arg0();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool srs_directive_equals(SrsConfDirective* a, SrsConfDirective* b)
|
bool srs_directive_equals(SrsConfDirective* a, SrsConfDirective* b)
|
||||||
|
|
|
@ -56,6 +56,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
// the interval in seconds for bandwidth check
|
// the interval in seconds for bandwidth check
|
||||||
#define SRS_CONF_DEFAULT_BANDWIDTH_LIMIT_KBPS 1000
|
#define SRS_CONF_DEFAULT_BANDWIDTH_LIMIT_KBPS 1000
|
||||||
|
|
||||||
|
#define SRS_CONF_DEFAULT_HTTP_MOUNT "/"
|
||||||
|
#define SRS_CONF_DEFAULT_HTTP_DIR SRS_CONF_DEFAULT_HLS_PATH
|
||||||
|
|
||||||
#define SRS_STAGE_PLAY_USER_INTERVAL_MS 1300
|
#define SRS_STAGE_PLAY_USER_INTERVAL_MS 1300
|
||||||
#define SRS_STAGE_PUBLISH_USER_INTERVAL_MS 1100
|
#define SRS_STAGE_PUBLISH_USER_INTERVAL_MS 1100
|
||||||
#define SRS_STAGE_FORWARDER_INTERVAL_MS 2000
|
#define SRS_STAGE_FORWARDER_INTERVAL_MS 2000
|
||||||
|
@ -86,6 +89,8 @@ public:
|
||||||
enum SrsDirectiveType{parse_file, parse_block};
|
enum SrsDirectiveType{parse_file, parse_block};
|
||||||
virtual int parse_conf(SrsFileBuffer* buffer, SrsDirectiveType type);
|
virtual int parse_conf(SrsFileBuffer* buffer, SrsDirectiveType type);
|
||||||
virtual int read_token(SrsFileBuffer* buffer, std::vector<std::string>& args);
|
virtual int read_token(SrsFileBuffer* buffer, std::vector<std::string>& args);
|
||||||
|
public:
|
||||||
|
virtual bool is_vhost();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -118,6 +123,7 @@ private:
|
||||||
virtual void print_help(char** argv);
|
virtual void print_help(char** argv);
|
||||||
// global section
|
// global section
|
||||||
public:
|
public:
|
||||||
|
virtual SrsConfDirective* get_root();
|
||||||
virtual bool get_deamon();
|
virtual bool get_deamon();
|
||||||
virtual int get_max_connections();
|
virtual int get_max_connections();
|
||||||
virtual SrsConfDirective* get_listen();
|
virtual SrsConfDirective* get_listen();
|
||||||
|
@ -201,6 +207,10 @@ private:
|
||||||
public:
|
public:
|
||||||
virtual bool get_http_stream_enabled();
|
virtual bool get_http_stream_enabled();
|
||||||
virtual int get_http_stream_listen();
|
virtual int get_http_stream_listen();
|
||||||
|
public:
|
||||||
|
virtual bool get_vhost_http_enabled(std::string vhost);
|
||||||
|
virtual std::string get_vhost_http_mount(std::string vhost);
|
||||||
|
virtual std::string get_vhost_http_dir(std::string vhost);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -325,8 +325,7 @@ SrsHttpHandler* SrsHttpHandler::create_http_api()
|
||||||
|
|
||||||
SrsHttpHandler* SrsHttpHandler::create_http_stream()
|
SrsHttpHandler* SrsHttpHandler::create_http_stream()
|
||||||
{
|
{
|
||||||
// TODO: FIXME: use http stream handler instead.
|
return new SrsHttpRoot();
|
||||||
return new SrsHttpHandler();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsHttpMessage::SrsHttpMessage()
|
SrsHttpMessage::SrsHttpMessage()
|
||||||
|
|
|
@ -32,16 +32,151 @@ using namespace std;
|
||||||
#include <srs_kernel_error.hpp>
|
#include <srs_kernel_error.hpp>
|
||||||
#include <srs_app_socket.hpp>
|
#include <srs_app_socket.hpp>
|
||||||
#include <srs_app_http.hpp>
|
#include <srs_app_http.hpp>
|
||||||
#include <srs_kernel_buffer.hpp>
|
|
||||||
#include <srs_core_autofree.hpp>
|
#include <srs_core_autofree.hpp>
|
||||||
|
#include <srs_app_json.hpp>
|
||||||
|
#include <srs_app_config.hpp>
|
||||||
|
|
||||||
#define SRS_HTTP_HEADER_BUFFER 1024
|
SrsHttpRoot::SrsHttpRoot()
|
||||||
|
{
|
||||||
|
// TODO: FIXME: support reload vhosts.
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsHttpRoot::~SrsHttpRoot()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int SrsHttpRoot::initialize()
|
||||||
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
handlers.push_back(new SrsHttpVhost(vhost, mount, dir));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SrsHttpRoot::is_handler_valid(SrsHttpMessage* req, int& status_code, std::string& reason_phrase)
|
||||||
|
{
|
||||||
|
if (!SrsHttpHandler::is_handler_valid(req, status_code, reason_phrase)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req->match()->matched_url.length() != 1) {
|
||||||
|
status_code = HTTP_NotFound;
|
||||||
|
reason_phrase = HTTP_NotFound_str;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SrsHttpRoot::can_handle(const char* path, int length, const char** pchild)
|
||||||
|
{
|
||||||
|
// reset the child path to path,
|
||||||
|
// for child to reparse the path.
|
||||||
|
*pchild = path;
|
||||||
|
|
||||||
|
// only compare the first char.
|
||||||
|
return srs_path_equals("/", path, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int SrsHttpRoot::do_process_request(SrsSocket* skt, SrsHttpMessage* req)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
|
||||||
|
ss << JOBJECT_START
|
||||||
|
<< JFIELD_ERROR(ERROR_SUCCESS) << JFIELD_CONT
|
||||||
|
<< JFIELD_ORG("urls", JOBJECT_START);
|
||||||
|
|
||||||
|
vector<SrsHttpHandler*>::iterator it;
|
||||||
|
for (it = handlers.begin(); it != handlers.end(); ++it) {
|
||||||
|
SrsHttpVhost* handler = dynamic_cast<SrsHttpVhost*>(*it);
|
||||||
|
srs_assert(handler);
|
||||||
|
|
||||||
|
ss << JFIELD_ORG(handler->mount(), JOBJECT_START)
|
||||||
|
<< JFIELD_STR("mount", handler->mount()) << JFIELD_CONT
|
||||||
|
<< JFIELD_STR("vhost", handler->vhost()) << JFIELD_CONT
|
||||||
|
<< JFIELD_STR("dir", handler->dir())
|
||||||
|
<< JOBJECT_END;
|
||||||
|
|
||||||
|
if (it + 1 != handlers.end()) {
|
||||||
|
ss << JFIELD_CONT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ss << JOBJECT_END
|
||||||
|
<< JOBJECT_END;
|
||||||
|
|
||||||
|
return res_json(skt, req, ss.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsHttpVhost::SrsHttpVhost(std::string vhost, std::string mount, std::string dir)
|
||||||
|
{
|
||||||
|
_vhost = vhost;
|
||||||
|
_mount = mount;
|
||||||
|
_dir = dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsHttpVhost::~SrsHttpVhost()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SrsHttpVhost::can_handle(const char* path, int length, const char** /*pchild*/)
|
||||||
|
{
|
||||||
|
return srs_path_equals("/api", path, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
int SrsHttpVhost::do_process_request(SrsSocket* skt, SrsHttpMessage* req)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
|
||||||
|
ss << JOBJECT_START
|
||||||
|
<< JFIELD_ERROR(ERROR_SUCCESS) << JFIELD_CONT
|
||||||
|
<< JFIELD_ORG("urls", JOBJECT_START)
|
||||||
|
<< JFIELD_STR("v1", "the api version 1.0")
|
||||||
|
<< JOBJECT_END
|
||||||
|
<< JOBJECT_END;
|
||||||
|
|
||||||
|
return res_json(skt, req, ss.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
string SrsHttpVhost::vhost()
|
||||||
|
{
|
||||||
|
return _vhost;
|
||||||
|
}
|
||||||
|
|
||||||
|
string SrsHttpVhost::mount()
|
||||||
|
{
|
||||||
|
return _mount;
|
||||||
|
}
|
||||||
|
|
||||||
|
string SrsHttpVhost::dir()
|
||||||
|
{
|
||||||
|
return _dir;
|
||||||
|
}
|
||||||
|
|
||||||
SrsHttpConn::SrsHttpConn(SrsServer* srs_server, st_netfd_t client_stfd, SrsHttpHandler* _handler)
|
SrsHttpConn::SrsHttpConn(SrsServer* srs_server, st_netfd_t client_stfd, SrsHttpHandler* _handler)
|
||||||
: SrsConnection(srs_server, client_stfd)
|
: SrsConnection(srs_server, client_stfd)
|
||||||
{
|
{
|
||||||
parser = new SrsHttpParser();
|
parser = new SrsHttpParser();
|
||||||
handler = _handler;
|
handler = _handler;
|
||||||
|
requires_crossdomain = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsHttpConn::~SrsHttpConn()
|
SrsHttpConn::~SrsHttpConn()
|
||||||
|
@ -96,34 +231,41 @@ int SrsHttpConn::do_cycle()
|
||||||
int SrsHttpConn::process_request(SrsSocket* skt, SrsHttpMessage* req)
|
int SrsHttpConn::process_request(SrsSocket* skt, SrsHttpMessage* req)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
// parse uri to schema/server:port/path?query
|
||||||
|
if ((ret = req->parse_uri()) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
if (req->method() == HTTP_OPTIONS) {
|
srs_trace("http request parsed, method=%d, url=%s, content-length=%"PRId64"",
|
||||||
char data[] = "HTTP/1.1 200 OK" __CRLF
|
req->method(), req->url().c_str(), req->content_length());
|
||||||
"Content-Length: 0"__CRLF
|
|
||||||
"Server: SRS/"RTMP_SIG_SRS_VERSION""__CRLF
|
// TODO: maybe need to parse the url.
|
||||||
"Allow: DELETE, GET, HEAD, OPTIONS, POST, PUT"__CRLF
|
std::string url = req->path();
|
||||||
"Access-Control-Allow-Origin: *"__CRLF
|
|
||||||
"Access-Control-Allow-Methods: GET, POST, HEAD, PUT, DELETE"__CRLF
|
SrsHttpHandlerMatch* p = NULL;
|
||||||
"Access-Control-Allow-Headers: Cache-Control,X-Proxy-Authorization,X-Requested-With,Content-Type"__CRLF
|
if ((ret = handler->best_match(url.data(), url.length(), &p)) != ERROR_SUCCESS) {
|
||||||
"Content-Type: text/html;charset=utf-8"__CRLFCRLF
|
srs_warn("failed to find the best match handler for url. ret=%d", ret);
|
||||||
"";
|
return ret;
|
||||||
return skt->write(data, sizeof(data), NULL);
|
}
|
||||||
} else {
|
|
||||||
std::string tilte = "SRS/"RTMP_SIG_SRS_VERSION;
|
// if success, p and pstart should be valid.
|
||||||
tilte += " hello http/1.1 server~\n";
|
srs_assert(p);
|
||||||
|
srs_assert(p->handler);
|
||||||
std::stringstream ss;
|
srs_assert(p->matched_url.length() <= url.length());
|
||||||
ss << "HTTP/1.1 200 OK " << __CRLF
|
srs_info("best match handler, matched_url=%s", p->matched_url.c_str());
|
||||||
<< "Content-Length: "<< tilte.length() + req->body_size() << __CRLF
|
|
||||||
<< "Server: SRS/"RTMP_SIG_SRS_VERSION"" << __CRLF
|
req->set_match(p);
|
||||||
<< "Allow: DELETE, GET, HEAD, OPTIONS, POST, PUT" << __CRLF
|
req->set_requires_crossdomain(requires_crossdomain);
|
||||||
<< "Access-Control-Allow-Origin: *" << __CRLF
|
|
||||||
<< "Access-Control-Allow-Methods: GET, POST, HEAD, PUT, DELETE" << __CRLF
|
// use handler to process request.
|
||||||
<< "Access-Control-Allow-Headers: Cache-Control,X-Proxy-Authorization,X-Requested-With,Content-Type" << __CRLF
|
if ((ret = p->handler->process_request(skt, req)) != ERROR_SUCCESS) {
|
||||||
<< "Content-Type: text/html;charset=utf-8" << __CRLFCRLF
|
srs_warn("handler failed to process http request. ret=%d", ret);
|
||||||
<< tilte << req->body().c_str()
|
return ret;
|
||||||
<< "";
|
}
|
||||||
return skt->write(ss.str().c_str(), ss.str().length(), NULL);
|
|
||||||
|
if (req->requires_crossdomain()) {
|
||||||
|
requires_crossdomain = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -34,19 +34,50 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
#include <srs_app_st.hpp>
|
#include <srs_app_st.hpp>
|
||||||
#include <srs_app_conn.hpp>
|
#include <srs_app_conn.hpp>
|
||||||
|
#include <srs_app_http.hpp>
|
||||||
#include <http_parser.h>
|
|
||||||
|
|
||||||
class SrsSocket;
|
class SrsSocket;
|
||||||
class SrsHttpParser;
|
class SrsHttpParser;
|
||||||
class SrsHttpMessage;
|
class SrsHttpMessage;
|
||||||
class SrsHttpHandler;
|
class SrsHttpHandler;
|
||||||
|
|
||||||
|
// for http root.
|
||||||
|
class SrsHttpRoot : public SrsHttpHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SrsHttpRoot();
|
||||||
|
virtual ~SrsHttpRoot();
|
||||||
|
public:
|
||||||
|
virtual int initialize();
|
||||||
|
virtual bool is_handler_valid(SrsHttpMessage* req, int& status_code, std::string& reason_phrase);
|
||||||
|
virtual bool can_handle(const char* path, int length, const char** pchild);
|
||||||
|
virtual int do_process_request(SrsSocket* skt, SrsHttpMessage* req);
|
||||||
|
};
|
||||||
|
|
||||||
|
class SrsHttpVhost : public SrsHttpHandler
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::string _vhost;
|
||||||
|
std::string _mount;
|
||||||
|
std::string _dir;
|
||||||
|
public:
|
||||||
|
SrsHttpVhost(std::string vhost, std::string mount, std::string dir);
|
||||||
|
virtual ~SrsHttpVhost();
|
||||||
|
public:
|
||||||
|
virtual bool can_handle(const char* path, int length, const char** pchild);
|
||||||
|
virtual int do_process_request(SrsSocket* skt, SrsHttpMessage* req);
|
||||||
|
public:
|
||||||
|
virtual std::string vhost();
|
||||||
|
virtual std::string mount();
|
||||||
|
virtual std::string dir();
|
||||||
|
};
|
||||||
|
|
||||||
class SrsHttpConn : public SrsConnection
|
class SrsHttpConn : public SrsConnection
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
SrsHttpParser* parser;
|
SrsHttpParser* parser;
|
||||||
SrsHttpHandler* handler;
|
SrsHttpHandler* handler;
|
||||||
|
bool requires_crossdomain;
|
||||||
public:
|
public:
|
||||||
SrsHttpConn(SrsServer* srs_server, st_netfd_t client_stfd, SrsHttpHandler* _handler);
|
SrsHttpConn(SrsServer* srs_server, st_netfd_t client_stfd, SrsHttpHandler* _handler);
|
||||||
virtual ~SrsHttpConn();
|
virtual ~SrsHttpConn();
|
||||||
|
|
|
@ -36,5 +36,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#define JFIELD_ERROR(ret) "\"" << "code" << "\":" << ret
|
#define JFIELD_ERROR(ret) "\"" << "code" << "\":" << ret
|
||||||
#define JFIELD_CONT ","
|
#define JFIELD_CONT ","
|
||||||
#define JOBJECT_END "}"
|
#define JOBJECT_END "}"
|
||||||
|
#define JARRAY_START "["
|
||||||
|
#define JARRAY_END "]"
|
||||||
|
|
||||||
#endif
|
#endif
|
Loading…
Add table
Add a link
Reference in a new issue