mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
merge from srs2
This commit is contained in:
commit
266397acee
4 changed files with 88 additions and 15 deletions
|
@ -1414,8 +1414,12 @@ int SrsHttpApi::process_request(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
srs_trace("HTTP %s %s, content-length=%"PRId64"",
|
SrsHttpMessage* hm = dynamic_cast<SrsHttpMessage*>(r);
|
||||||
r->method_str().c_str(), r->url().c_str(), r->content_length());
|
srs_assert(hm);
|
||||||
|
|
||||||
|
srs_trace("HTTP API %s %s, content-length=%"PRId64", chunked=%d/%d",
|
||||||
|
r->method_str().c_str(), r->url().c_str(), r->content_length(),
|
||||||
|
hm->is_chunked(), hm->is_infinite_chunked());
|
||||||
|
|
||||||
// method is OPTIONS and enable crossdomain, required crossdomain header.
|
// method is OPTIONS and enable crossdomain, required crossdomain header.
|
||||||
if (r->is_http_options() && _srs_config->get_http_api_crossdomain()) {
|
if (r->is_http_options() && _srs_config->get_http_api_crossdomain()) {
|
||||||
|
|
|
@ -357,6 +357,7 @@ int SrsHttpResponseReader::read(char* data, int nb_data, int* nb_read)
|
||||||
}
|
}
|
||||||
|
|
||||||
// read by specified content-length
|
// read by specified content-length
|
||||||
|
if (owner->content_length() != -1) {
|
||||||
int max = (int)owner->content_length() - (int)nb_total_read;
|
int max = (int)owner->content_length() - (int)nb_total_read;
|
||||||
if (max <= 0) {
|
if (max <= 0) {
|
||||||
is_eof = true;
|
is_eof = true;
|
||||||
|
@ -366,6 +367,19 @@ int SrsHttpResponseReader::read(char* data, int nb_data, int* nb_read)
|
||||||
// change the max to read.
|
// change the max to read.
|
||||||
nb_data = srs_min(nb_data, max);
|
nb_data = srs_min(nb_data, max);
|
||||||
return read_specified(data, nb_data, nb_read);
|
return read_specified(data, nb_data, nb_read);
|
||||||
|
}
|
||||||
|
|
||||||
|
// infinite chunked mode, directly read.
|
||||||
|
if (owner->is_infinite_chunked()) {
|
||||||
|
srs_assert(!owner->is_chunked() && owner->content_length() == -1);
|
||||||
|
return read_specified(data, nb_data, nb_read);
|
||||||
|
}
|
||||||
|
|
||||||
|
// infinite chunked mode, but user not set it,
|
||||||
|
// we think there is no data left.
|
||||||
|
is_eof = true;
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsHttpResponseReader::read_chunked(char* data, int nb_data, int* nb_read)
|
int SrsHttpResponseReader::read_chunked(char* data, int nb_data, int* nb_read)
|
||||||
|
@ -505,6 +519,7 @@ SrsHttpMessage::SrsHttpMessage(ISrsProtocolReaderWriter* io, SrsConnection* c) :
|
||||||
{
|
{
|
||||||
conn = c;
|
conn = c;
|
||||||
chunked = false;
|
chunked = false;
|
||||||
|
infinite_chunked = false;
|
||||||
keep_alive = true;
|
keep_alive = true;
|
||||||
_uri = new SrsHttpUri();
|
_uri = new SrsHttpUri();
|
||||||
_body = new SrsHttpResponseReader(this, io);
|
_body = new SrsHttpResponseReader(this, io);
|
||||||
|
@ -660,6 +675,11 @@ bool SrsHttpMessage::is_keep_alive()
|
||||||
return keep_alive;
|
return keep_alive;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SrsHttpMessage::is_infinite_chunked()
|
||||||
|
{
|
||||||
|
return infinite_chunked;
|
||||||
|
}
|
||||||
|
|
||||||
string SrsHttpMessage::uri()
|
string SrsHttpMessage::uri()
|
||||||
{
|
{
|
||||||
std::string uri = _uri->get_schema();
|
std::string uri = _uri->get_schema();
|
||||||
|
@ -714,6 +734,25 @@ int SrsHttpMessage::parse_rest_id(string pattern)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SrsHttpMessage::enter_infinite_chunked()
|
||||||
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
if (infinite_chunked) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_chunked() || content_length() != -1) {
|
||||||
|
ret = ERROR_HTTP_DATA_INVALID;
|
||||||
|
srs_error("infinite chunkted not supported in specified codec. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
infinite_chunked = true;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int SrsHttpMessage::body_read_all(string& body)
|
int SrsHttpMessage::body_read_all(string& body)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
|
@ -152,9 +152,6 @@ typedef std::pair<std::string, std::string> SrsHttpHeaderField;
|
||||||
// The field semantics differ slightly between client and server
|
// The field semantics differ slightly between client and server
|
||||||
// usage. In addition to the notes on the fields below, see the
|
// usage. In addition to the notes on the fields below, see the
|
||||||
// documentation for Request.Write and RoundTripper.
|
// documentation for Request.Write and RoundTripper.
|
||||||
/**
|
|
||||||
* the http message, request or response.
|
|
||||||
*/
|
|
||||||
class SrsHttpMessage : public ISrsHttpMessage
|
class SrsHttpMessage : public ISrsHttpMessage
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
@ -179,6 +176,10 @@ private:
|
||||||
* whether the body is chunked.
|
* whether the body is chunked.
|
||||||
*/
|
*/
|
||||||
bool chunked;
|
bool chunked;
|
||||||
|
/**
|
||||||
|
* whether the body is infinite chunked.
|
||||||
|
*/
|
||||||
|
bool infinite_chunked;
|
||||||
/**
|
/**
|
||||||
* whether the request indicates should keep alive
|
* whether the request indicates should keep alive
|
||||||
* for the http connection.
|
* for the http connection.
|
||||||
|
@ -231,6 +232,11 @@ public:
|
||||||
* whether body is chunked encoding, for reader only.
|
* whether body is chunked encoding, for reader only.
|
||||||
*/
|
*/
|
||||||
virtual bool is_chunked();
|
virtual bool is_chunked();
|
||||||
|
/**
|
||||||
|
* whether body is infinite chunked encoding.
|
||||||
|
* @remark set by enter_infinite_chunked.
|
||||||
|
*/
|
||||||
|
virtual bool is_infinite_chunked();
|
||||||
/**
|
/**
|
||||||
* whether should keep the connection alive.
|
* whether should keep the connection alive.
|
||||||
*/
|
*/
|
||||||
|
@ -251,6 +257,8 @@ public:
|
||||||
* get the RESTful matched id.
|
* get the RESTful matched id.
|
||||||
*/
|
*/
|
||||||
virtual int parse_rest_id(std::string pattern);
|
virtual int parse_rest_id(std::string pattern);
|
||||||
|
public:
|
||||||
|
virtual int enter_infinite_chunked();
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* read body to string.
|
* read body to string.
|
||||||
|
|
|
@ -231,6 +231,12 @@ public:
|
||||||
* @param nb_data, the max size of data buffer.
|
* @param nb_data, the max size of data buffer.
|
||||||
* @param nb_read, the actual read size of bytes. NULL to ignore.
|
* @param nb_read, the actual read size of bytes. NULL to ignore.
|
||||||
* @remark when eof(), return error.
|
* @remark when eof(), return error.
|
||||||
|
* @remark for some server, the content-length not specified and not chunked,
|
||||||
|
* which is actually the infinite chunked encoding, which after http header
|
||||||
|
* is http response data, it's ok for browser. that is,
|
||||||
|
* when user call this read, please ensure there is data to read(by content-length
|
||||||
|
* or by chunked), because the sdk never know whether there is no data or
|
||||||
|
* infinite chunked.
|
||||||
*/
|
*/
|
||||||
virtual int read(char* data, int nb_data, int* nb_read) = 0;
|
virtual int read(char* data, int nb_data, int* nb_read) = 0;
|
||||||
};
|
};
|
||||||
|
@ -445,9 +451,19 @@ typedef std::pair<std::string, std::string> SrsHttpHeaderField;
|
||||||
// The field semantics differ slightly between client and server
|
// The field semantics differ slightly between client and server
|
||||||
// usage. In addition to the notes on the fields below, see the
|
// usage. In addition to the notes on the fields below, see the
|
||||||
// documentation for Request.Write and RoundTripper.
|
// documentation for Request.Write and RoundTripper.
|
||||||
/**
|
//
|
||||||
* the http message, request or response.
|
// There are some modes to determine the length of body:
|
||||||
*/
|
// 1. content-length and chunked.
|
||||||
|
// 2. user confirmed infinite chunked.
|
||||||
|
// 3. no body or user not confirmed infinite chunked.
|
||||||
|
// For example:
|
||||||
|
// ISrsHttpMessage* r = ...;
|
||||||
|
// while (!r->eof()) r->read(); // read in mode 1 or 3.
|
||||||
|
// For some server, we can confirm the body is infinite chunked:
|
||||||
|
// ISrsHttpMessage* r = ...;
|
||||||
|
// r->enter_infinite_chunked();
|
||||||
|
// while (!r->eof()) r->read(); // read in mode 2
|
||||||
|
// @rmark for mode 2, the infinite chunked, all left data is body.
|
||||||
class ISrsHttpMessage
|
class ISrsHttpMessage
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
@ -502,6 +518,12 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual int parse_rest_id(std::string pattern) = 0;
|
virtual int parse_rest_id(std::string pattern) = 0;
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* the left all data is chunked body, the infinite chunked mode,
|
||||||
|
* which is chunked encoding without chunked header.
|
||||||
|
* @remark error when message is in chunked or content-length specified.
|
||||||
|
*/
|
||||||
|
virtual int enter_infinite_chunked() = 0;
|
||||||
/**
|
/**
|
||||||
* read body to string.
|
* read body to string.
|
||||||
* @remark for small http body.
|
* @remark for small http body.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue