mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
for #179, enable http api crossdomain for dvr api.
This commit is contained in:
parent
1445086451
commit
c67a4fdf97
11 changed files with 267 additions and 3 deletions
|
@ -109,6 +109,9 @@ http_api {
|
||||||
# the http api port
|
# the http api port
|
||||||
# default: 1985
|
# default: 1985
|
||||||
listen 1985;
|
listen 1985;
|
||||||
|
# whether enable crossdomain request.
|
||||||
|
# default: on
|
||||||
|
crossdomain on;
|
||||||
}
|
}
|
||||||
# embeded http server in srs.
|
# embeded http server in srs.
|
||||||
# the http streaming config, for HLS/HDS/DASH/HTTPProgressive
|
# the http streaming config, for HLS/HDS/DASH/HTTPProgressive
|
||||||
|
@ -286,6 +289,31 @@ vhost dvr.srs.com {
|
||||||
# segment reap flv when flv duration exceed the specified dvr_duration.
|
# segment reap flv when flv duration exceed the specified dvr_duration.
|
||||||
# append always append to flv file, never reap it.
|
# append always append to flv file, never reap it.
|
||||||
# api reap flv when api required.
|
# api reap flv when api required.
|
||||||
|
# about the api plan, the HTTP api to dvr,
|
||||||
|
# http url to control dvr, for example, http://dev:1985/api/v1/dvrs
|
||||||
|
# method=GET
|
||||||
|
# to query dvrs of server.
|
||||||
|
# request params, for example ?vhost=__defaultVhost__, where:
|
||||||
|
# vhost, query all dvr of this vhost.
|
||||||
|
# response in json, where:
|
||||||
|
# {code:0, dvrs: [{plan:"api", path:"./objs/nginx/html",
|
||||||
|
# autostart:true, wait_keyframe:true, jitter:"full"
|
||||||
|
# }]}
|
||||||
|
# method=POST
|
||||||
|
# to start dvr of specified vhost.
|
||||||
|
# request should encode in json, specifies the dvr to create, where:
|
||||||
|
# {plan:"api", path:"./objs/nginx/html",
|
||||||
|
# autostart:true, wait_keyframe:true, jitter:"full",
|
||||||
|
# vhost:"__defaultVhost", callback:"http://dvr/callback"
|
||||||
|
# }
|
||||||
|
# response in json, where:
|
||||||
|
# {code:0}
|
||||||
|
# method=DELETE, to stop dvr
|
||||||
|
# to stop dvr of specified vhost.
|
||||||
|
# request params, for example ?vhost=__defaultVhost__, where:
|
||||||
|
# vhost, stop all dvr of this vhost.
|
||||||
|
# response in json, where:
|
||||||
|
# {code:0}
|
||||||
# default: session
|
# default: session
|
||||||
dvr_plan session;
|
dvr_plan session;
|
||||||
# the dvr output path.
|
# the dvr output path.
|
||||||
|
|
|
@ -1334,7 +1334,7 @@ int SrsConfig::check_config()
|
||||||
SrsConfDirective* conf = get_http_api();
|
SrsConfDirective* conf = get_http_api();
|
||||||
for (int i = 0; conf && i < (int)conf->directives.size(); i++) {
|
for (int i = 0; conf && i < (int)conf->directives.size(); i++) {
|
||||||
string n = conf->at(i)->name;
|
string n = conf->at(i)->name;
|
||||||
if (n != "enabled" && n != "listen") {
|
if (n != "enabled" && n != "listen" && n != "crossdomain") {
|
||||||
ret = ERROR_SYSTEM_CONFIG_INVALID;
|
ret = ERROR_SYSTEM_CONFIG_INVALID;
|
||||||
srs_error("unsupported http_api directive %s, ret=%d", n.c_str(), ret);
|
srs_error("unsupported http_api directive %s, ret=%d", n.c_str(), ret);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -3453,6 +3453,22 @@ int SrsConfig::get_http_api_listen()
|
||||||
return ::atoi(conf->arg0().c_str());
|
return ::atoi(conf->arg0().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SrsConfig::get_http_api_crossdomain()
|
||||||
|
{
|
||||||
|
SrsConfDirective* conf = get_http_api();
|
||||||
|
|
||||||
|
if (!conf) {
|
||||||
|
return SRS_CONF_DEFAULT_HTTP_API_CROSSDOMAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
conf = conf->get("crossdomain");
|
||||||
|
if (!conf || conf->arg0().empty()) {
|
||||||
|
return SRS_CONF_DEFAULT_HTTP_API_CROSSDOMAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
return conf->arg0() != "off";
|
||||||
|
}
|
||||||
|
|
||||||
bool SrsConfig::get_http_stream_enabled()
|
bool SrsConfig::get_http_stream_enabled()
|
||||||
{
|
{
|
||||||
SrsConfDirective* conf = get_http_stream();
|
SrsConfDirective* conf = get_http_stream();
|
||||||
|
|
|
@ -79,6 +79,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
#define SRS_CONF_DEFAULT_HTTP_STREAM_PORT 8080
|
#define SRS_CONF_DEFAULT_HTTP_STREAM_PORT 8080
|
||||||
#define SRS_CONF_DEFAULT_HTTP_API_PORT 1985
|
#define SRS_CONF_DEFAULT_HTTP_API_PORT 1985
|
||||||
|
#define SRS_CONF_DEFAULT_HTTP_API_CROSSDOMAIN true
|
||||||
|
|
||||||
#define SRS_CONF_DEFAULT_HTTP_HEAETBEAT_ENABLED false
|
#define SRS_CONF_DEFAULT_HTTP_HEAETBEAT_ENABLED false
|
||||||
#define SRS_CONF_DEFAULT_HTTP_HEAETBEAT_INTERVAL 9.9
|
#define SRS_CONF_DEFAULT_HTTP_HEAETBEAT_INTERVAL 9.9
|
||||||
|
@ -957,6 +958,10 @@ public:
|
||||||
* get the http api listen port.
|
* get the http api listen port.
|
||||||
*/
|
*/
|
||||||
virtual int get_http_api_listen();
|
virtual int get_http_api_listen();
|
||||||
|
/**
|
||||||
|
* whether enable crossdomain for http api.
|
||||||
|
*/
|
||||||
|
virtual bool get_http_api_crossdomain();
|
||||||
// http stream section
|
// http stream section
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -40,6 +40,7 @@ using namespace std;
|
||||||
#include <srs_kernel_file.hpp>
|
#include <srs_kernel_file.hpp>
|
||||||
#include <srs_rtmp_amf0.hpp>
|
#include <srs_rtmp_amf0.hpp>
|
||||||
#include <srs_kernel_stream.hpp>
|
#include <srs_kernel_stream.hpp>
|
||||||
|
#include <srs_app_json.hpp>
|
||||||
|
|
||||||
// update the flv duration and filesize every this interval in ms.
|
// update the flv duration and filesize every this interval in ms.
|
||||||
#define __SRS_DVR_UPDATE_DURATION_INTERVAL 60000
|
#define __SRS_DVR_UPDATE_DURATION_INTERVAL 60000
|
||||||
|
@ -665,6 +666,8 @@ SrsDvrPlan* SrsDvrPlan::create_plan(string vhost)
|
||||||
return new SrsDvrSessionPlan();
|
return new SrsDvrSessionPlan();
|
||||||
} else if (plan == SRS_CONF_DEFAULT_DVR_PLAN_APPEND) {
|
} else if (plan == SRS_CONF_DEFAULT_DVR_PLAN_APPEND) {
|
||||||
return new SrsDvrAppendPlan();
|
return new SrsDvrAppendPlan();
|
||||||
|
} else if (plan == SRS_CONF_DEFAULT_DVR_PLAN_API) {
|
||||||
|
return new SrsDvrApiPlan();
|
||||||
} else {
|
} else {
|
||||||
srs_error("invalid dvr plan=%s, vhost=%s", plan.c_str(), vhost.c_str());
|
srs_error("invalid dvr plan=%s, vhost=%s", plan.c_str(), vhost.c_str());
|
||||||
srs_assert(false);
|
srs_assert(false);
|
||||||
|
@ -721,6 +724,56 @@ void SrsDvrSessionPlan::on_unpublish()
|
||||||
dvr_enabled = false;
|
dvr_enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SrsDvrApiPlan::SrsDvrApiPlan()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsDvrApiPlan::~SrsDvrApiPlan()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int SrsDvrApiPlan::on_publish()
|
||||||
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
// support multiple publish.
|
||||||
|
if (dvr_enabled) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_srs_config->get_dvr_enabled(req->vhost)) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ret = segment->close()) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ret = segment->open()) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
dvr_enabled = true;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SrsDvrApiPlan::on_unpublish()
|
||||||
|
{
|
||||||
|
// support multiple publish.
|
||||||
|
if (!dvr_enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore error.
|
||||||
|
int ret = segment->close();
|
||||||
|
if (ret != ERROR_SUCCESS) {
|
||||||
|
srs_warn("ignore flv close error. ret=%d", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
dvr_enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
SrsDvrAppendPlan::SrsDvrAppendPlan()
|
SrsDvrAppendPlan::SrsDvrAppendPlan()
|
||||||
{
|
{
|
||||||
last_update_time = 0;
|
last_update_time = 0;
|
||||||
|
@ -977,6 +1030,29 @@ int SrsDvrSegmentPlan::update_duration(SrsSharedPtrMessage* msg)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SrsApiDvrPool* SrsApiDvrPool::_instance = new SrsApiDvrPool();
|
||||||
|
|
||||||
|
SrsApiDvrPool* SrsApiDvrPool::instance()
|
||||||
|
{
|
||||||
|
return SrsApiDvrPool::_instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsApiDvrPool::SrsApiDvrPool()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsApiDvrPool::~SrsApiDvrPool()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int SrsApiDvrPool::dumps(stringstream& ss)
|
||||||
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
ss << __SRS_JARRAY_START
|
||||||
|
<< __SRS_JARRAY_END;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
SrsDvr::SrsDvr(SrsSource* s)
|
SrsDvr::SrsDvr(SrsSource* s)
|
||||||
{
|
{
|
||||||
source = s;
|
source = s;
|
||||||
|
|
|
@ -30,6 +30,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#include <srs_core.hpp>
|
#include <srs_core.hpp>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
#ifdef SRS_AUTO_DVR
|
#ifdef SRS_AUTO_DVR
|
||||||
|
|
||||||
|
@ -223,6 +224,19 @@ public:
|
||||||
virtual void on_unpublish();
|
virtual void on_unpublish();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api plan: reap flv by api.
|
||||||
|
*/
|
||||||
|
class SrsDvrApiPlan : public SrsDvrPlan
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SrsDvrApiPlan();
|
||||||
|
virtual ~SrsDvrApiPlan();
|
||||||
|
public:
|
||||||
|
virtual int on_publish();
|
||||||
|
virtual void on_unpublish();
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* always append to flv file, never reap it.
|
* always append to flv file, never reap it.
|
||||||
*/
|
*/
|
||||||
|
@ -282,6 +296,22 @@ private:
|
||||||
virtual int update_duration(SrsSharedPtrMessage* msg);
|
virtual int update_duration(SrsSharedPtrMessage* msg);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the api dvr pool.
|
||||||
|
*/
|
||||||
|
class SrsApiDvrPool
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
static SrsApiDvrPool* _instance;
|
||||||
|
private:
|
||||||
|
SrsApiDvrPool();
|
||||||
|
public:
|
||||||
|
static SrsApiDvrPool* instance();
|
||||||
|
virtual ~SrsApiDvrPool();
|
||||||
|
public:
|
||||||
|
virtual int dumps(std::stringstream& ss);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dvr(digital video recorder) to record RTMP stream to flv file.
|
* dvr(digital video recorder) to record RTMP stream to flv file.
|
||||||
* TODO: FIXME: add utest for it.
|
* TODO: FIXME: add utest for it.
|
||||||
|
|
|
@ -139,6 +139,9 @@ bool srs_go_http_body_allowd(int status)
|
||||||
// returns "application/octet-stream".
|
// returns "application/octet-stream".
|
||||||
string srs_go_http_detect(char* data, int size)
|
string srs_go_http_detect(char* data, int size)
|
||||||
{
|
{
|
||||||
|
// detect only when data specified.
|
||||||
|
if (data) {
|
||||||
|
}
|
||||||
return "application/octet-stream"; // fallback
|
return "application/octet-stream"; // fallback
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -715,8 +718,8 @@ int SrsGoHttpResponseWriter::final_request()
|
||||||
return skt->write((void*)ch.data(), (int)ch.length(), NULL);
|
return skt->write((void*)ch.data(), (int)ch.length(), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ignore when send with content length
|
// flush when send with content length
|
||||||
return ERROR_SUCCESS;
|
return write(NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsGoHttpHeader* SrsGoHttpResponseWriter::header()
|
SrsGoHttpHeader* SrsGoHttpResponseWriter::header()
|
||||||
|
@ -744,6 +747,11 @@ int SrsGoHttpResponseWriter::write(char* data, int size)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ignore NULL content.
|
||||||
|
if (!data) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
// directly send with content length
|
// directly send with content length
|
||||||
if (content_length != -1) {
|
if (content_length != -1) {
|
||||||
return skt->write((void*)data, size, NULL);
|
return skt->write((void*)data, size, NULL);
|
||||||
|
|
|
@ -123,6 +123,29 @@ public:
|
||||||
|
|
||||||
// A ResponseWriter interface is used by an HTTP handler to
|
// A ResponseWriter interface is used by an HTTP handler to
|
||||||
// construct an HTTP response.
|
// construct an HTTP response.
|
||||||
|
// Usage 1, response with specified length content:
|
||||||
|
// ISrsGoHttpResponseWriter* w; // create or get response.
|
||||||
|
// std::string msg = "Hello, HTTP!";
|
||||||
|
// w->header()->set_content_type("text/plain; charset=utf-8");
|
||||||
|
// w->header()->set_content_length(msg.length());
|
||||||
|
// w->write_header(SRS_CONSTS_HTTP_OK);
|
||||||
|
// w->write((char*)msg.data(), (int)msg.length());
|
||||||
|
// w->final_request(); // optional flush.
|
||||||
|
// Usage 2, response with HTTP code only, zero content length.
|
||||||
|
// ISrsGoHttpResponseWriter* w; // create or get response.
|
||||||
|
// w->header()->set_content_length(0);
|
||||||
|
// w->write_header(SRS_CONSTS_HTTP_OK);
|
||||||
|
// w->final_request();
|
||||||
|
// Usage 3, response in chunked encoding.
|
||||||
|
// ISrsGoHttpResponseWriter* w; // create or get response.
|
||||||
|
// std::string msg = "Hello, HTTP!";
|
||||||
|
// w->header()->set_content_type("application/octet-stream");
|
||||||
|
// w->write_header(SRS_CONSTS_HTTP_OK);
|
||||||
|
// w->write((char*)msg.data(), (int)msg.length());
|
||||||
|
// w->write((char*)msg.data(), (int)msg.length());
|
||||||
|
// w->write((char*)msg.data(), (int)msg.length());
|
||||||
|
// w->write((char*)msg.data(), (int)msg.length());
|
||||||
|
// w->final_request(); // required to end the chunked and flush.
|
||||||
class ISrsGoHttpResponseWriter
|
class ISrsGoHttpResponseWriter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -143,6 +166,7 @@ public:
|
||||||
// before writing the data. If the Header does not contain a
|
// before writing the data. If the Header does not contain a
|
||||||
// Content-Type line, Write adds a Content-Type set to the result of passing
|
// Content-Type line, Write adds a Content-Type set to the result of passing
|
||||||
// the initial 512 bytes of written data to DetectContentType.
|
// the initial 512 bytes of written data to DetectContentType.
|
||||||
|
// @param data, the data to send. NULL to flush header only.
|
||||||
virtual int write(char* data, int size) = 0;
|
virtual int write(char* data, int size) = 0;
|
||||||
|
|
||||||
// WriteHeader sends an HTTP response header with status code.
|
// WriteHeader sends an HTTP response header with status code.
|
||||||
|
|
|
@ -37,6 +37,8 @@ using namespace std;
|
||||||
#include <srs_app_utility.hpp>
|
#include <srs_app_utility.hpp>
|
||||||
#include <srs_app_statistic.hpp>
|
#include <srs_app_statistic.hpp>
|
||||||
#include <srs_rtmp_sdk.hpp>
|
#include <srs_rtmp_sdk.hpp>
|
||||||
|
#include <srs_app_dvr.hpp>
|
||||||
|
#include <srs_app_config.hpp>
|
||||||
|
|
||||||
SrsGoApiRoot::SrsGoApiRoot()
|
SrsGoApiRoot::SrsGoApiRoot()
|
||||||
{
|
{
|
||||||
|
@ -472,11 +474,48 @@ int SrsGoApiStreams::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r)
|
||||||
return srs_go_http_response_json(w, ss.str());
|
return srs_go_http_response_json(w, ss.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SrsGoApiDvrs::SrsGoApiDvrs()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsGoApiDvrs::~SrsGoApiDvrs()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int SrsGoApiDvrs::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
|
||||||
|
#ifndef SRS_AUTO_DVR
|
||||||
|
ss << __SRS_JOBJECT_START
|
||||||
|
<< __SRS_JFIELD_ERROR(ERROR_HTTP_DVR_DISABLED)
|
||||||
|
<< __SRS_JOBJECT_END;
|
||||||
|
#else
|
||||||
|
SrsApiDvrPool* pool = SrsApiDvrPool::instance();
|
||||||
|
if (r->is_http_get()) {
|
||||||
|
std::stringstream data;
|
||||||
|
int ret = pool->dumps(data);
|
||||||
|
|
||||||
|
ss << __SRS_JOBJECT_START
|
||||||
|
<< __SRS_JFIELD_ERROR(ret) << __SRS_JFIELD_CONT
|
||||||
|
<< __SRS_JFIELD_ORG("dvrs", data.str())
|
||||||
|
<< __SRS_JOBJECT_END;
|
||||||
|
} else {
|
||||||
|
ss << __SRS_JOBJECT_START
|
||||||
|
<< __SRS_JFIELD_ERROR(ERROR_HTTP_DVR_REQUEST)
|
||||||
|
<< __SRS_JOBJECT_END;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return srs_go_http_response_json(w, ss.str());
|
||||||
|
}
|
||||||
|
|
||||||
SrsHttpApi::SrsHttpApi(SrsServer* svr, st_netfd_t fd, SrsGoHttpServeMux* m)
|
SrsHttpApi::SrsHttpApi(SrsServer* svr, st_netfd_t fd, SrsGoHttpServeMux* m)
|
||||||
: SrsConnection(svr, fd)
|
: SrsConnection(svr, fd)
|
||||||
{
|
{
|
||||||
mux = m;
|
mux = m;
|
||||||
parser = new SrsHttpParser();
|
parser = new SrsHttpParser();
|
||||||
|
crossdomain_required = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsHttpApi::~SrsHttpApi()
|
SrsHttpApi::~SrsHttpApi()
|
||||||
|
@ -549,6 +588,29 @@ int SrsHttpApi::process_request(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r)
|
||||||
srs_trace("HTTP %s %s, content-length=%"PRId64"",
|
srs_trace("HTTP %s %s, content-length=%"PRId64"",
|
||||||
r->method_str().c_str(), r->url().c_str(), r->content_length());
|
r->method_str().c_str(), r->url().c_str(), r->content_length());
|
||||||
|
|
||||||
|
// method is OPTIONS and enable crossdomain, required crossdomain header.
|
||||||
|
if (r->is_http_options() && _srs_config->get_http_api_crossdomain()) {
|
||||||
|
crossdomain_required = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// whenever crossdomain required, set crossdomain header.
|
||||||
|
if (crossdomain_required) {
|
||||||
|
w->header()->set("Access-Control-Allow-Origin", "*");
|
||||||
|
w->header()->set("Access-Control-Allow-Methods", "GET, POST, HEAD, PUT, DELETE");
|
||||||
|
w->header()->set("Access-Control-Allow-Headers", "Cache-Control,X-Proxy-Authorization,X-Requested-With,Content-Type");
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle the http options.
|
||||||
|
if (r->is_http_options()) {
|
||||||
|
w->header()->set_content_length(0);
|
||||||
|
if (_srs_config->get_http_api_crossdomain()) {
|
||||||
|
w->write_header(SRS_CONSTS_HTTP_OK);
|
||||||
|
} else {
|
||||||
|
w->write_header(SRS_CONSTS_HTTP_MethodNotAllowed);
|
||||||
|
}
|
||||||
|
return w->final_request();
|
||||||
|
}
|
||||||
|
|
||||||
// use default server mux to serve http request.
|
// use default server mux to serve http request.
|
||||||
if ((ret = mux->serve_http(w, r)) != ERROR_SUCCESS) {
|
if ((ret = mux->serve_http(w, r)) != ERROR_SUCCESS) {
|
||||||
if (!srs_is_client_gracefully_close(ret)) {
|
if (!srs_is_client_gracefully_close(ret)) {
|
||||||
|
|
|
@ -159,11 +159,21 @@ public:
|
||||||
virtual int serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r);
|
virtual int serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SrsGoApiDvrs : public ISrsGoHttpHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SrsGoApiDvrs();
|
||||||
|
virtual ~SrsGoApiDvrs();
|
||||||
|
public:
|
||||||
|
virtual int serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r);
|
||||||
|
};
|
||||||
|
|
||||||
class SrsHttpApi : public SrsConnection
|
class SrsHttpApi : public SrsConnection
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
SrsHttpParser* parser;
|
SrsHttpParser* parser;
|
||||||
SrsGoHttpServeMux* mux;
|
SrsGoHttpServeMux* mux;
|
||||||
|
bool crossdomain_required;
|
||||||
public:
|
public:
|
||||||
SrsHttpApi(SrsServer* svr, st_netfd_t fd, SrsGoHttpServeMux* m);
|
SrsHttpApi(SrsServer* svr, st_netfd_t fd, SrsGoHttpServeMux* m);
|
||||||
virtual ~SrsHttpApi();
|
virtual ~SrsHttpApi();
|
||||||
|
|
|
@ -529,6 +529,9 @@ int SrsServer::initialize()
|
||||||
if ((ret = http_api_mux->handle("/api/v1/streams", new SrsGoApiStreams())) != ERROR_SUCCESS) {
|
if ((ret = http_api_mux->handle("/api/v1/streams", new SrsGoApiStreams())) != ERROR_SUCCESS) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
if ((ret = http_api_mux->handle("/api/v1/dvrs", new SrsGoApiDvrs())) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef SRS_AUTO_HTTP_SERVER
|
#ifdef SRS_AUTO_HTTP_SERVER
|
||||||
|
|
|
@ -209,6 +209,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#define ERROR_AAC_ADTS_HEADER 3047
|
#define ERROR_AAC_ADTS_HEADER 3047
|
||||||
#define ERROR_AAC_DATA_INVALID 3048
|
#define ERROR_AAC_DATA_INVALID 3048
|
||||||
#define ERROR_HLS_TRY_MP3 3049
|
#define ERROR_HLS_TRY_MP3 3049
|
||||||
|
#define ERROR_HTTP_DVR_DISABLED 3050
|
||||||
|
#define ERROR_HTTP_DVR_REQUEST 3051
|
||||||
|
|
||||||
///////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////
|
||||||
// HTTP/StreamCaster protocol error.
|
// HTTP/StreamCaster protocol error.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue