Skip to content

Commit

Permalink
for ossrs#179, enable http api crossdomain for dvr api.
Browse files Browse the repository at this point in the history
  • Loading branch information
winlinvip committed Feb 21, 2015
1 parent 1445086 commit c67a4fd
Show file tree
Hide file tree
Showing 11 changed files with 267 additions and 3 deletions.
28 changes: 28 additions & 0 deletions trunk/conf/full.conf
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ http_api {
# the http api port
# default: 1985
listen 1985;
# whether enable crossdomain request.
# default: on
crossdomain on;
}
# embeded http server in srs.
# the http streaming config, for HLS/HDS/DASH/HTTPProgressive
Expand Down Expand Up @@ -286,6 +289,31 @@ vhost dvr.srs.com {
# segment reap flv when flv duration exceed the specified dvr_duration.
# append always append to flv file, never reap it.
# 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
dvr_plan session;
# the dvr output path.
Expand Down
18 changes: 17 additions & 1 deletion trunk/src/app/srs_app_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1334,7 +1334,7 @@ int SrsConfig::check_config()
SrsConfDirective* conf = get_http_api();
for (int i = 0; conf && i < (int)conf->directives.size(); i++) {
string n = conf->at(i)->name;
if (n != "enabled" && n != "listen") {
if (n != "enabled" && n != "listen" && n != "crossdomain") {
ret = ERROR_SYSTEM_CONFIG_INVALID;
srs_error("unsupported http_api directive %s, ret=%d", n.c_str(), ret);
return ret;
Expand Down Expand Up @@ -3453,6 +3453,22 @@ int SrsConfig::get_http_api_listen()
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()
{
SrsConfDirective* conf = get_http_stream();
Expand Down
5 changes: 5 additions & 0 deletions trunk/src/app/srs_app_config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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_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_INTERVAL 9.9
Expand Down Expand Up @@ -957,6 +958,10 @@ class SrsConfig
* get the http api listen port.
*/
virtual int get_http_api_listen();
/**
* whether enable crossdomain for http api.
*/
virtual bool get_http_api_crossdomain();
// http stream section
private:
/**
Expand Down
76 changes: 76 additions & 0 deletions trunk/src/app/srs_app_dvr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ using namespace std;
#include <srs_kernel_file.hpp>
#include <srs_rtmp_amf0.hpp>
#include <srs_kernel_stream.hpp>
#include <srs_app_json.hpp>

// update the flv duration and filesize every this interval in ms.
#define __SRS_DVR_UPDATE_DURATION_INTERVAL 60000
Expand Down Expand Up @@ -665,6 +666,8 @@ SrsDvrPlan* SrsDvrPlan::create_plan(string vhost)
return new SrsDvrSessionPlan();
} else if (plan == SRS_CONF_DEFAULT_DVR_PLAN_APPEND) {
return new SrsDvrAppendPlan();
} else if (plan == SRS_CONF_DEFAULT_DVR_PLAN_API) {
return new SrsDvrApiPlan();
} else {
srs_error("invalid dvr plan=%s, vhost=%s", plan.c_str(), vhost.c_str());
srs_assert(false);
Expand Down Expand Up @@ -721,6 +724,56 @@ void SrsDvrSessionPlan::on_unpublish()
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()
{
last_update_time = 0;
Expand Down Expand Up @@ -977,6 +1030,29 @@ int SrsDvrSegmentPlan::update_duration(SrsSharedPtrMessage* msg)
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)
{
source = s;
Expand Down
30 changes: 30 additions & 0 deletions trunk/src/app/srs_app_dvr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <srs_core.hpp>

#include <string>
#include <sstream>

#ifdef SRS_AUTO_DVR

Expand Down Expand Up @@ -223,6 +224,19 @@ class SrsDvrSessionPlan : public SrsDvrPlan
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.
*/
Expand Down Expand Up @@ -282,6 +296,22 @@ class SrsDvrSegmentPlan : public SrsDvrPlan
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.
* TODO: FIXME: add utest for it.
Expand Down
12 changes: 10 additions & 2 deletions trunk/src/app/srs_app_http.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ bool srs_go_http_body_allowd(int status)
// returns "application/octet-stream".
string srs_go_http_detect(char* data, int size)
{
// detect only when data specified.
if (data) {
}
return "application/octet-stream"; // fallback
}

Expand Down Expand Up @@ -715,8 +718,8 @@ int SrsGoHttpResponseWriter::final_request()
return skt->write((void*)ch.data(), (int)ch.length(), NULL);
}

// ignore when send with content length
return ERROR_SUCCESS;
// flush when send with content length
return write(NULL, 0);
}

SrsGoHttpHeader* SrsGoHttpResponseWriter::header()
Expand All @@ -743,6 +746,11 @@ int SrsGoHttpResponseWriter::write(char* data, int size)
srs_error("http: send header failed. ret=%d", ret);
return ret;
}

// ignore NULL content.
if (!data) {
return ret;
}

// directly send with content length
if (content_length != -1) {
Expand Down
24 changes: 24 additions & 0 deletions trunk/src/app/srs_app_http.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,29 @@ class SrsGoHttpHeader

// A ResponseWriter interface is used by an HTTP handler to
// 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
{
public:
Expand All @@ -143,6 +166,7 @@ class ISrsGoHttpResponseWriter
// 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
// 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;

// WriteHeader sends an HTTP response header with status code.
Expand Down
Loading

0 comments on commit c67a4fd

Please sign in to comment.