1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-03-09 15:49:59 +00:00

For #913, Service support complex error.

This commit is contained in:
winlin 2018-01-01 11:41:15 +08:00
parent 15aea686c3
commit aebbbadf42
7 changed files with 151 additions and 208 deletions

View file

@ -3028,9 +3028,9 @@ SrsHttpUri::~SrsHttpUri()
{ {
} }
int SrsHttpUri::initialize(string _url) srs_error_t SrsHttpUri::initialize(string _url)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
schema = host = path = query = ""; schema = host = path = query = "";
@ -3038,12 +3038,9 @@ int SrsHttpUri::initialize(string _url)
const char* purl = url.c_str(); const char* purl = url.c_str();
http_parser_url hp_u; http_parser_url hp_u;
if((ret = http_parser_parse_url(purl, url.length(), 0, &hp_u)) != 0){ int r0;
int code = ret; if((r0 = http_parser_parse_url(purl, url.length(), 0, &hp_u)) != 0){
ret = ERROR_HTTP_PARSE_URI; return srs_error_new(ERROR_HTTP_PARSE_URI, "parse url %s failed, code=%d", purl, r0);
srs_error("parse url %s failed, code=%d, ret=%d", purl, code, ret);
return ret;
} }
std::string field = get_uri_field(url, &hp_u, UF_SCHEMA); std::string field = get_uri_field(url, &hp_u, UF_SCHEMA);
@ -3062,12 +3059,9 @@ int SrsHttpUri::initialize(string _url)
} }
path = get_uri_field(url, &hp_u, UF_PATH); path = get_uri_field(url, &hp_u, UF_PATH);
srs_info("parse url %s success", purl);
query = get_uri_field(url, &hp_u, UF_QUERY); query = get_uri_field(url, &hp_u, UF_QUERY);
srs_info("parse query %s success", query.c_str());
return ret; return err;
} }
string SrsHttpUri::get_url() string SrsHttpUri::get_url()
@ -3106,12 +3100,6 @@ string SrsHttpUri::get_uri_field(string uri, http_parser_url* hp_u, http_parser_
return ""; return "";
} }
srs_verbose("uri field matched, off=%d, len=%d, value=%.*s",
hp_u->field_data[field].off,
hp_u->field_data[field].len,
hp_u->field_data[field].len,
uri.c_str() + hp_u->field_data[field].off);
int offset = hp_u->field_data[field].off; int offset = hp_u->field_data[field].off;
int len = hp_u->field_data[field].len; int len = hp_u->field_data[field].len;

View file

@ -900,7 +900,7 @@ public:
/** /**
* initialize the http uri. * initialize the http uri.
*/ */
virtual int initialize(std::string _url); virtual srs_error_t initialize(std::string _url);
public: public:
virtual std::string get_url(); virtual std::string get_url();
virtual std::string get_schema(); virtual std::string get_schema();

View file

@ -55,14 +55,13 @@ SrsHttpClient::~SrsHttpClient()
// TODO: FIXME: use ms for timeout. // TODO: FIXME: use ms for timeout.
srs_error_t SrsHttpClient::initialize(string h, int p, int64_t tm) srs_error_t SrsHttpClient::initialize(string h, int p, int64_t tm)
{ {
int ret = ERROR_SUCCESS;
srs_error_t err = srs_success; srs_error_t err = srs_success;
srs_freep(parser); srs_freep(parser);
parser = new SrsHttpParser(); parser = new SrsHttpParser();
if ((ret = parser->initialize(HTTP_RESPONSE, false)) != ERROR_SUCCESS) { if ((err = parser->initialize(HTTP_RESPONSE, false)) != srs_success) {
return srs_error_new(ret, "http: init parser"); return srs_error_wrap(err, "http: init parser");
} }
// Always disconnect the transport. // Always disconnect the transport.
@ -97,7 +96,6 @@ srs_error_t SrsHttpClient::post(string path, string req, ISrsHttpMessage** ppmsg
{ {
*ppmsg = NULL; *ppmsg = NULL;
int ret = ERROR_SUCCESS;
srs_error_t err = srs_success; srs_error_t err = srs_success;
// always set the content length. // always set the content length.
@ -119,15 +117,15 @@ srs_error_t SrsHttpClient::post(string path, string req, ISrsHttpMessage** ppmsg
ss << SRS_HTTP_CRLF << req; ss << SRS_HTTP_CRLF << req;
std::string data = ss.str(); std::string data = ss.str();
if ((ret = transport->write((void*)data.c_str(), data.length(), NULL)) != ERROR_SUCCESS) { if ((err = transport->write((void*)data.c_str(), data.length(), NULL)) != srs_success) {
// Disconnect the transport when channel error, reconnect for next operation. // Disconnect the transport when channel error, reconnect for next operation.
disconnect(); disconnect();
return srs_error_new(ret, "http: write"); return srs_error_wrap(err, "http: write");
} }
ISrsHttpMessage* msg = NULL; ISrsHttpMessage* msg = NULL;
if ((ret = parser->parse_message(transport, NULL, &msg)) != ERROR_SUCCESS) { if ((err = parser->parse_message(transport, NULL, &msg)) != srs_success) {
return srs_error_new(ret, "http: parse response"); return srs_error_wrap(err, "http: parse response");
} }
srs_assert(msg); srs_assert(msg);
@ -136,7 +134,6 @@ srs_error_t SrsHttpClient::post(string path, string req, ISrsHttpMessage** ppmsg
} else { } else {
srs_freep(msg); srs_freep(msg);
} }
srs_info("parse http post response success.");
return err; return err;
} }
@ -145,7 +142,6 @@ srs_error_t SrsHttpClient::get(string path, string req, ISrsHttpMessage** ppmsg)
{ {
*ppmsg = NULL; *ppmsg = NULL;
int ret = ERROR_SUCCESS;
srs_error_t err = srs_success; srs_error_t err = srs_success;
// always set the content length. // always set the content length.
@ -167,15 +163,15 @@ srs_error_t SrsHttpClient::get(string path, string req, ISrsHttpMessage** ppmsg)
ss << SRS_HTTP_CRLF << req; ss << SRS_HTTP_CRLF << req;
std::string data = ss.str(); std::string data = ss.str();
if ((ret = transport->write((void*)data.c_str(), data.length(), NULL)) != ERROR_SUCCESS) { if ((err = transport->write((void*)data.c_str(), data.length(), NULL)) != srs_success) {
// Disconnect the transport when channel error, reconnect for next operation. // Disconnect the transport when channel error, reconnect for next operation.
disconnect(); disconnect();
return srs_error_new(ret, "http: write"); return srs_error_wrap(err, "http: write");
} }
ISrsHttpMessage* msg = NULL; ISrsHttpMessage* msg = NULL;
if ((ret = parser->parse_message(transport, NULL, &msg)) != ERROR_SUCCESS) { if ((err = parser->parse_message(transport, NULL, &msg)) != srs_success) {
return srs_error_new(ret, "http: parse response"); return srs_error_wrap(err, "http: parse response");
} }
srs_assert(msg); srs_assert(msg);
@ -184,7 +180,6 @@ srs_error_t SrsHttpClient::get(string path, string req, ISrsHttpMessage** ppmsg)
} else { } else {
srs_freep(msg); srs_freep(msg);
} }
srs_info("parse http get response success.");
return err; return err;
} }
@ -228,7 +223,6 @@ srs_error_t SrsHttpClient::connect()
disconnect(); disconnect();
return srs_error_wrap(err, "http: tcp connect %s:%d to=%d", host.c_str(), port, (int)timeout); return srs_error_wrap(err, "http: tcp connect %s:%d to=%d", host.c_str(), port, (int)timeout);
} }
srs_info("connect to server success. server=%s, port=%d", host.c_str(), port);
// Set the recv/send timeout in ms. // Set the recv/send timeout in ms.
transport->set_recv_timeout(timeout); transport->set_recv_timeout(timeout);

View file

@ -46,9 +46,9 @@ SrsHttpParser::~SrsHttpParser()
srs_freep(buffer); srs_freep(buffer);
} }
int SrsHttpParser::initialize(enum http_parser_type type, bool allow_jsonp) srs_error_t SrsHttpParser::initialize(enum http_parser_type type, bool allow_jsonp)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
jsonp = allow_jsonp; jsonp = allow_jsonp;
@ -65,14 +65,14 @@ int SrsHttpParser::initialize(enum http_parser_type type, bool allow_jsonp)
// callback object ptr. // callback object ptr.
parser.data = (void*)this; parser.data = (void*)this;
return ret; return err;
} }
int SrsHttpParser::parse_message(ISrsProtocolReaderWriter* io, SrsConnection* conn, ISrsHttpMessage** ppmsg) srs_error_t SrsHttpParser::parse_message(ISrsProtocolReaderWriter* io, SrsConnection* conn, ISrsHttpMessage** ppmsg)
{ {
*ppmsg = NULL; *ppmsg = NULL;
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
// reset request data. // reset request data.
field_name = ""; field_name = "";
@ -85,32 +85,28 @@ int SrsHttpParser::parse_message(ISrsProtocolReaderWriter* io, SrsConnection* co
header_parsed = 0; header_parsed = 0;
// do parse // do parse
if ((ret = parse_message_imp(io)) != ERROR_SUCCESS) { if ((err = parse_message_imp(io)) != srs_success) {
if (!srs_is_client_gracefully_close(ret)) { return srs_error_wrap(err, "parse message");
srs_error("parse http msg failed. ret=%d", ret);
}
return ret;
} }
// create msg // create msg
SrsHttpMessage* msg = new SrsHttpMessage(io, conn); SrsHttpMessage* msg = new SrsHttpMessage(io, conn);
// initalize http msg, parse url. // initalize http msg, parse url.
if ((ret = msg->update(url, jsonp, &header, buffer, headers)) != ERROR_SUCCESS) { if ((err = msg->update(url, jsonp, &header, buffer, headers)) != srs_success) {
srs_error("initialize http msg failed. ret=%d", ret);
srs_freep(msg); srs_freep(msg);
return ret; return srs_error_wrap(err, "update message");
} }
// parse ok, return the msg. // parse ok, return the msg.
*ppmsg = msg; *ppmsg = msg;
return ret; return err;
} }
int SrsHttpParser::parse_message_imp(ISrsProtocolReaderWriter* io) srs_error_t SrsHttpParser::parse_message_imp(ISrsProtocolReaderWriter* io)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
while (true) { while (true) {
ssize_t nparsed = 0; ssize_t nparsed = 0;
@ -142,11 +138,8 @@ int SrsHttpParser::parse_message_imp(ISrsProtocolReaderWriter* io)
// when nothing parsed, read more to parse. // when nothing parsed, read more to parse.
if (nparsed == 0) { if (nparsed == 0) {
// when requires more, only grow 1bytes, but the buffer will cache more. // when requires more, only grow 1bytes, but the buffer will cache more.
if ((ret = buffer->grow(io, buffer->size() + 1)) != ERROR_SUCCESS) { if ((err = buffer->grow(io, buffer->size() + 1)) != srs_success) {
if (!srs_is_client_gracefully_close(ret)) { return srs_error_wrap(err, "grow buffer");
srs_error("read body from server failed. ret=%d", ret);
}
return ret;
} }
} }
} }
@ -156,7 +149,7 @@ int SrsHttpParser::parse_message_imp(ISrsProtocolReaderWriter* io)
headers.push_back(std::make_pair(field_name, field_value)); headers.push_back(std::make_pair(field_name, field_value));
} }
return ret; return err;
} }
int SrsHttpParser::on_message_begin(http_parser* parser) int SrsHttpParser::on_message_begin(http_parser* parser)
@ -280,9 +273,9 @@ SrsHttpMessage::~SrsHttpMessage()
srs_freepa(_http_ts_send_buffer); srs_freepa(_http_ts_send_buffer);
} }
int SrsHttpMessage::update(string url, bool allow_jsonp, http_parser* header, SrsFastStream* body, vector<SrsHttpHeaderField>& headers) srs_error_t SrsHttpMessage::update(string url, bool allow_jsonp, http_parser* header, SrsFastStream* body, vector<SrsHttpHeaderField>& headers)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
_url = url; _url = url;
_header = *header; _header = *header;
@ -296,8 +289,8 @@ int SrsHttpMessage::update(string url, bool allow_jsonp, http_parser* header, Sr
keep_alive = http_should_keep_alive(header); keep_alive = http_should_keep_alive(header);
// set the buffer. // set the buffer.
if ((ret = _body->initialize(body)) != ERROR_SUCCESS) { if ((err = _body->initialize(body)) != srs_success) {
return ret; return srs_error_wrap(err, "init body");
} }
// parse uri from url. // parse uri from url.
@ -311,8 +304,8 @@ int SrsHttpMessage::update(string url, bool allow_jsonp, http_parser* header, Sr
// parse uri to schema/server:port/path?query // parse uri to schema/server:port/path?query
std::string uri = "http://" + host + _url; std::string uri = "http://" + host + _url;
if ((ret = _uri->initialize(uri)) != ERROR_SUCCESS) { if ((err = _uri->initialize(uri)) != srs_success) {
return ret; return srs_error_wrap(err, "init uri");
} }
// parse ext. // parse ext.
@ -331,7 +324,7 @@ int SrsHttpMessage::update(string url, bool allow_jsonp, http_parser* header, Sr
} }
} }
return ret; return err;
} }
SrsConnection* SrsHttpMessage::connection() SrsConnection* SrsHttpMessage::connection()
@ -480,28 +473,26 @@ int SrsHttpMessage::parse_rest_id(string pattern)
return -1; return -1;
} }
int SrsHttpMessage::enter_infinite_chunked() srs_error_t SrsHttpMessage::enter_infinite_chunked()
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
if (infinite_chunked) { if (infinite_chunked) {
return ret; return err;
} }
if (is_chunked() || content_length() != -1) { if (is_chunked() || content_length() != -1) {
ret = ERROR_HTTP_DATA_INVALID; return srs_error_new(ERROR_HTTP_DATA_INVALID, "not infinited chunked");
srs_error("infinite chunkted not supported in specified codec. ret=%d", ret);
return ret;
} }
infinite_chunked = true; infinite_chunked = true;
return ret; return err;
} }
int SrsHttpMessage::body_read_all(string& body) srs_error_t SrsHttpMessage::body_read_all(string& body)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
// cache to read. // cache to read.
char* buf = new char[SRS_HTTP_READ_CACHE_BYTES]; char* buf = new char[SRS_HTTP_READ_CACHE_BYTES];
@ -510,8 +501,8 @@ int SrsHttpMessage::body_read_all(string& body)
// whatever, read util EOF. // whatever, read util EOF.
while (!_body->eof()) { while (!_body->eof()) {
int nb_read = 0; int nb_read = 0;
if ((ret = _body->read(buf, SRS_HTTP_READ_CACHE_BYTES, &nb_read)) != ERROR_SUCCESS) { if ((err = _body->read(buf, SRS_HTTP_READ_CACHE_BYTES, &nb_read)) != srs_success) {
return ret; return srs_error_wrap(err, "read body");
} }
if (nb_read > 0) { if (nb_read > 0) {
@ -519,7 +510,7 @@ int SrsHttpMessage::body_read_all(string& body)
} }
} }
return ret; return err;
} }
ISrsHttpResponseReader* SrsHttpMessage::body_reader() ISrsHttpResponseReader* SrsHttpMessage::body_reader()
@ -633,7 +624,7 @@ SrsHttpResponseWriter::~SrsHttpResponseWriter()
srs_freepa(iovss_cache); srs_freepa(iovss_cache);
} }
int SrsHttpResponseWriter::final_request() srs_error_t SrsHttpResponseWriter::final_request()
{ {
// write the header data in memory. // write the header data in memory.
if (!header_wrote) { if (!header_wrote) {
@ -657,9 +648,9 @@ SrsHttpHeader* SrsHttpResponseWriter::header()
return hdr; return hdr;
} }
int SrsHttpResponseWriter::write(char* data, int size) srs_error_t SrsHttpResponseWriter::write(char* data, int size)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
// write the header data in memory. // write the header data in memory.
if (!header_wrote) { if (!header_wrote) {
@ -667,22 +658,19 @@ int SrsHttpResponseWriter::write(char* data, int size)
} }
// whatever header is wrote, we should try to send header. // whatever header is wrote, we should try to send header.
if ((ret = send_header(data, size)) != ERROR_SUCCESS) { if ((err = send_header(data, size)) != srs_success) {
srs_error("http: send header failed. ret=%d", ret); return srs_error_wrap(err, "send header");
return ret;
} }
// check the bytes send and content length. // check the bytes send and content length.
written += size; written += size;
if (content_length != -1 && written > content_length) { if (content_length != -1 && written > content_length) {
ret = ERROR_HTTP_CONTENT_LENGTH; return srs_error_new(ERROR_HTTP_CONTENT_LENGTH, "overflow writen=%d, max=%d", (int)written, (int)content_length);
srs_error("http: exceed content length. ret=%d", ret);
return ret;
} }
// ignore NULL content. // ignore NULL content.
if (!data) { if (!data) {
return ret; return err;
} }
// directly send with content length // directly send with content length
@ -704,16 +692,16 @@ int SrsHttpResponseWriter::write(char* data, int size)
iovs[3].iov_len = 2; iovs[3].iov_len = 2;
ssize_t nwrite; ssize_t nwrite;
if ((ret = skt->writev(iovs, 4, &nwrite)) != ERROR_SUCCESS) { if ((err = skt->writev(iovs, 4, &nwrite)) != srs_success) {
return ret; return srs_error_wrap(err, "write chunk");
} }
return ret; return err;
} }
int SrsHttpResponseWriter::writev(const iovec* iov, int iovcnt, ssize_t* pnwrite) srs_error_t SrsHttpResponseWriter::writev(const iovec* iov, int iovcnt, ssize_t* pnwrite)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
// when header not ready, or not chunked, send one by one. // when header not ready, or not chunked, send one by one.
if (!header_wrote || content_length != -1) { if (!header_wrote || content_length != -1) {
@ -721,8 +709,8 @@ int SrsHttpResponseWriter::writev(const iovec* iov, int iovcnt, ssize_t* pnwrite
for (int i = 0; i < iovcnt; i++) { for (int i = 0; i < iovcnt; i++) {
const iovec* piovc = iov + i; const iovec* piovc = iov + i;
nwrite += piovc->iov_len; nwrite += piovc->iov_len;
if ((ret = write((char*)piovc->iov_base, (int)piovc->iov_len)) != ERROR_SUCCESS) { if ((err = write((char*)piovc->iov_base, (int)piovc->iov_len)) != srs_success) {
return ret; return srs_error_wrap(err, "writev");
} }
} }
@ -730,12 +718,12 @@ int SrsHttpResponseWriter::writev(const iovec* iov, int iovcnt, ssize_t* pnwrite
*pnwrite = nwrite; *pnwrite = nwrite;
} }
return ret; return err;
} }
// ignore NULL content. // ignore NULL content.
if (iovcnt <= 0) { if (iovcnt <= 0) {
return ret; return err;
} }
// send in chunked encoding. // send in chunked encoding.
@ -784,15 +772,15 @@ int SrsHttpResponseWriter::writev(const iovec* iov, int iovcnt, ssize_t* pnwrite
// sendout all ioves. // sendout all ioves.
ssize_t nwrite; ssize_t nwrite;
if ((ret = srs_write_large_iovs(skt, iovss, nb_iovss, &nwrite)) != ERROR_SUCCESS) { if ((err = srs_write_large_iovs(skt, iovss, nb_iovss, &nwrite)) != srs_success) {
return ret; return srs_error_wrap(err, "writev large iovs");
} }
if (pnwrite) { if (pnwrite) {
*pnwrite = nwrite; *pnwrite = nwrite;
} }
return ret; return err;
} }
void SrsHttpResponseWriter::write_header(int code) void SrsHttpResponseWriter::write_header(int code)
@ -809,12 +797,12 @@ void SrsHttpResponseWriter::write_header(int code)
content_length = hdr->content_length(); content_length = hdr->content_length();
} }
int SrsHttpResponseWriter::send_header(char* data, int size) srs_error_t SrsHttpResponseWriter::send_header(char* data, int size)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
if (header_sent) { if (header_sent) {
return ret; return err;
} }
header_sent = true; header_sent = true;
@ -868,16 +856,16 @@ SrsHttpResponseReader::~SrsHttpResponseReader()
{ {
} }
int SrsHttpResponseReader::initialize(SrsFastStream* body) srs_error_t SrsHttpResponseReader::initialize(SrsFastStream* body)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
nb_chunk = 0; nb_chunk = 0;
nb_left_chunk = 0; nb_left_chunk = 0;
nb_total_read = 0; nb_total_read = 0;
buffer = body; buffer = body;
return ret; return err;
} }
bool SrsHttpResponseReader::eof() bool SrsHttpResponseReader::eof()
@ -885,14 +873,12 @@ bool SrsHttpResponseReader::eof()
return is_eof; return is_eof;
} }
int SrsHttpResponseReader::read(char* data, int nb_data, int* nb_read) srs_error_t SrsHttpResponseReader::read(char* data, int nb_data, int* nb_read)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
if (is_eof) { if (is_eof) {
ret = ERROR_HTTP_RESPONSE_EOF; return srs_error_new(ERROR_HTTP_RESPONSE_EOF, "EOF");
srs_error("http: response EOF. ret=%d", ret);
return ret;
} }
// chunked encoding. // chunked encoding.
@ -905,7 +891,7 @@ int SrsHttpResponseReader::read(char* data, int nb_data, int* nb_read)
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;
return ret; return err;
} }
// change the max to read. // change the max to read.
@ -923,12 +909,12 @@ int SrsHttpResponseReader::read(char* data, int nb_data, int* nb_read)
// we think there is no data left. // we think there is no data left.
is_eof = true; is_eof = true;
return ret; return err;
} }
int SrsHttpResponseReader::read_chunked(char* data, int nb_data, int* nb_read) srs_error_t SrsHttpResponseReader::read_chunked(char* data, int nb_data, int* nb_read)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
// when no bytes left in chunk, // when no bytes left in chunk,
// parse the chunk length first. // parse the chunk length first.
@ -943,9 +929,7 @@ int SrsHttpResponseReader::read_chunked(char* data, int nb_data, int* nb_read)
if (p[0] == SRS_HTTP_CR && p[1] == SRS_HTTP_LF) { if (p[0] == SRS_HTTP_CR && p[1] == SRS_HTTP_LF) {
// invalid chunk, ignore. // invalid chunk, ignore.
if (p == start) { if (p == start) {
ret = ERROR_HTTP_INVALID_CHUNK_HEADER; return srs_error_new(ERROR_HTTP_INVALID_CHUNK_HEADER, "chunk header");
srs_error("chunk header start with CRLF. ret=%d", ret);
return ret;
} }
length = (int)(p - start + 2); length = (int)(p - start + 2);
at = buffer->read_slice(length); at = buffer->read_slice(length);
@ -959,11 +943,8 @@ int SrsHttpResponseReader::read_chunked(char* data, int nb_data, int* nb_read)
} }
// when empty, only grow 1bytes, but the buffer will cache more. // when empty, only grow 1bytes, but the buffer will cache more.
if ((ret = buffer->grow(skt, buffer->size() + 1)) != ERROR_SUCCESS) { if ((err = buffer->grow(skt, buffer->size() + 1)) != srs_success) {
if (!srs_is_client_gracefully_close(ret)) { return srs_error_wrap(err, "grow buffer");
srs_error("read body from server failed. ret=%d", ret);
}
return ret;
} }
} }
srs_assert(length >= 3); srs_assert(length >= 3);
@ -975,9 +956,7 @@ int SrsHttpResponseReader::read_chunked(char* data, int nb_data, int* nb_read)
// size is the bytes size, excludes the chunk header and end CRLF. // size is the bytes size, excludes the chunk header and end CRLF.
int ilength = (int)::strtol(at, NULL, 16); int ilength = (int)::strtol(at, NULL, 16);
if (ilength < 0) { if (ilength < 0) {
ret = ERROR_HTTP_INVALID_CHUNK_HEADER; return srs_error_new(ERROR_HTTP_INVALID_CHUNK_HEADER, "invalid length=%d", ilength);
srs_error("chunk header negative, length=%d. ret=%d", ilength, ret);
return ret;
} }
// all bytes in chunk is left now. // all bytes in chunk is left now.
@ -993,45 +972,40 @@ int SrsHttpResponseReader::read_chunked(char* data, int nb_data, int* nb_read)
srs_assert(nb_left_chunk); srs_assert(nb_left_chunk);
int nb_bytes = srs_min(nb_left_chunk, nb_data); int nb_bytes = srs_min(nb_left_chunk, nb_data);
ret = read_specified(data, nb_bytes, &nb_bytes); err = read_specified(data, nb_bytes, &nb_bytes);
// the nb_bytes used for output already read size of bytes. // the nb_bytes used for output already read size of bytes.
if (nb_read) { if (nb_read) {
*nb_read = nb_bytes; *nb_read = nb_bytes;
} }
nb_left_chunk -= nb_bytes; nb_left_chunk -= nb_bytes;
srs_info("http: read %d bytes of chunk", nb_bytes);
// error or still left bytes in chunk, ignore and read in future. // error or still left bytes in chunk, ignore and read in future.
if (nb_left_chunk > 0 || (ret != ERROR_SUCCESS)) { if (err != srs_success) {
return ret; return srs_error_wrap(err, "read specified");
}
if (nb_left_chunk > 0) {
return srs_error_new(ERROR_HTTP_INVALID_CHUNK_HEADER, "read specified left=%d", nb_left_chunk);
} }
srs_info("http: read total chunk %dB", nb_chunk);
} }
// for both the last or not, the CRLF of chunk payload end. // for both the last or not, the CRLF of chunk payload end.
if ((ret = buffer->grow(skt, 2)) != ERROR_SUCCESS) { if ((err = buffer->grow(skt, 2)) != srs_success) {
if (!srs_is_client_gracefully_close(ret)) { return srs_error_wrap(err, "grow buffer");
srs_error("read EOF of chunk from server failed. ret=%d", ret);
}
return ret;
} }
buffer->read_slice(2); buffer->read_slice(2);
return ret; return err;
} }
int SrsHttpResponseReader::read_specified(char* data, int nb_data, int* nb_read) srs_error_t SrsHttpResponseReader::read_specified(char* data, int nb_data, int* nb_read)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
if (buffer->size() <= 0) { if (buffer->size() <= 0) {
// when empty, only grow 1bytes, but the buffer will cache more. // when empty, only grow 1bytes, but the buffer will cache more.
if ((ret = buffer->grow(skt, 1)) != ERROR_SUCCESS) { if ((err = buffer->grow(skt, 1)) != srs_success) {
if (!srs_is_client_gracefully_close(ret)) { return srs_error_wrap(err, "grow buffer");
srs_error("read body from server failed. ret=%d", ret);
}
return ret;
} }
} }
@ -1056,6 +1030,6 @@ int SrsHttpResponseReader::read_specified(char* data, int nb_data, int* nb_read)
} }
} }
return ret; return err;
} }

View file

@ -69,7 +69,7 @@ public:
* one parser can only parse request or response messages. * one parser can only parse request or response messages.
* @param allow_jsonp whether allow jsonp parser, which indicates the method in query string. * @param allow_jsonp whether allow jsonp parser, which indicates the method in query string.
*/ */
virtual int initialize(enum http_parser_type type, bool allow_jsonp); virtual srs_error_t initialize(enum http_parser_type type, bool allow_jsonp);
/** /**
* always parse a http message, * always parse a http message,
* that is, the *ppmsg always NOT-NULL when return success. * that is, the *ppmsg always NOT-NULL when return success.
@ -77,12 +77,12 @@ public:
* @remark, if success, *ppmsg always NOT-NULL, *ppmsg always is_complete(). * @remark, if success, *ppmsg always NOT-NULL, *ppmsg always is_complete().
* @remark user must free the ppmsg if not NULL. * @remark user must free the ppmsg if not NULL.
*/ */
virtual int parse_message(ISrsProtocolReaderWriter* io, SrsConnection* conn, ISrsHttpMessage** ppmsg); virtual srs_error_t parse_message(ISrsProtocolReaderWriter* io, SrsConnection* conn, ISrsHttpMessage** ppmsg);
private: private:
/** /**
* parse the HTTP message to member field: msg. * parse the HTTP message to member field: msg.
*/ */
virtual int parse_message_imp(ISrsProtocolReaderWriter* io); virtual srs_error_t parse_message_imp(ISrsProtocolReaderWriter* io);
private: private:
static int on_message_begin(http_parser* parser); static int on_message_begin(http_parser* parser);
static int on_headers_complete(http_parser* parser); static int on_headers_complete(http_parser* parser);
@ -161,7 +161,7 @@ public:
/** /**
* set the original messages, then update the message. * set the original messages, then update the message.
*/ */
virtual int update(std::string url, bool allow_jsonp, http_parser* header, SrsFastStream* body, std::vector<SrsHttpHeaderField>& headers); virtual srs_error_t update(std::string url, bool allow_jsonp, http_parser* header, SrsFastStream* body, std::vector<SrsHttpHeaderField>& headers);
public: public:
virtual SrsConnection* connection(); virtual SrsConnection* connection();
public: public:
@ -206,13 +206,13 @@ public:
*/ */
virtual int parse_rest_id(std::string pattern); virtual int parse_rest_id(std::string pattern);
public: public:
virtual int enter_infinite_chunked(); virtual srs_error_t enter_infinite_chunked();
public: public:
/** /**
* read body to string. * read body to string.
* @remark for small http body. * @remark for small http body.
*/ */
virtual int body_read_all(std::string& body); virtual srs_error_t body_read_all(std::string& body);
/** /**
* get the body reader, to read one by one. * get the body reader, to read one by one.
* @remark when body is very large, or chunked, use this. * @remark when body is very large, or chunked, use this.
@ -281,12 +281,12 @@ public:
SrsHttpResponseWriter(SrsStSocket* io); SrsHttpResponseWriter(SrsStSocket* io);
virtual ~SrsHttpResponseWriter(); virtual ~SrsHttpResponseWriter();
public: public:
virtual int final_request(); virtual srs_error_t final_request();
virtual SrsHttpHeader* header(); virtual SrsHttpHeader* header();
virtual int write(char* data, int size); virtual srs_error_t write(char* data, int size);
virtual int writev(const iovec* iov, int iovcnt, ssize_t* pnwrite); virtual srs_error_t writev(const iovec* iov, int iovcnt, ssize_t* pnwrite);
virtual void write_header(int code); virtual void write_header(int code);
virtual int send_header(char* data, int size); virtual srs_error_t send_header(char* data, int size);
}; };
/** /**
@ -312,14 +312,14 @@ public:
/** /**
* initialize the response reader with buffer. * initialize the response reader with buffer.
*/ */
virtual int initialize(SrsFastStream* buffer); virtual srs_error_t initialize(SrsFastStream* buffer);
// interface ISrsHttpResponseReader // interface ISrsHttpResponseReader
public: public:
virtual bool eof(); virtual bool eof();
virtual int read(char* data, int nb_data, int* nb_read); virtual srs_error_t read(char* data, int nb_data, int* nb_read);
private: private:
virtual int read_chunked(char* data, int nb_data, int* nb_read); virtual srs_error_t read_chunked(char* data, int nb_data, int* nb_read);
virtual int read_specified(char* data, int nb_data, int* nb_read); virtual srs_error_t read_specified(char* data, int nb_data, int* nb_read);
}; };
#endif #endif

View file

@ -57,9 +57,8 @@ SrsBasicRtmpClient::~SrsBasicRtmpClient()
srs_freep(kbps); srs_freep(kbps);
} }
int SrsBasicRtmpClient::connect() srs_error_t SrsBasicRtmpClient::connect()
{ {
int ret = ERROR_SUCCESS;
srs_error_t err = srs_success; srs_error_t err = srs_success;
close(); close();
@ -70,30 +69,24 @@ int SrsBasicRtmpClient::connect()
if ((err = transport->connect()) != srs_success) { if ((err = transport->connect()) != srs_success) {
close(); close();
// TODO: FIXME: Use error return srs_error_wrap(err, "connect");
ret = srs_error_code(err);
srs_freep(err);
return ret;
} }
client->set_recv_timeout(stream_timeout); client->set_recv_timeout(stream_timeout);
client->set_send_timeout(stream_timeout); client->set_send_timeout(stream_timeout);
// connect to vhost/app // connect to vhost/app
if ((ret = client->handshake()) != ERROR_SUCCESS) { if ((err = client->handshake()) != srs_success) {
srs_error("sdk: handshake with server failed. ret=%d", ret); return srs_error_wrap(err, "handshake");
return ret;
} }
if ((ret = connect_app()) != ERROR_SUCCESS) { if ((err = connect_app()) != srs_success) {
srs_error("sdk: connect with server failed. ret=%d", ret); return srs_error_wrap(err, "connect app");
return ret;
} }
if ((ret = client->create_stream(stream_id)) != ERROR_SUCCESS) { if ((err = client->create_stream(stream_id)) != srs_success) {
srs_error("sdk: connect with server failed, stream_id=%d. ret=%d", stream_id, ret); return srs_error_wrap(err, "create stream_id=%d", stream_id);
return ret;
} }
return ret; return err;
} }
void SrsBasicRtmpClient::close() void SrsBasicRtmpClient::close()
@ -103,14 +96,14 @@ void SrsBasicRtmpClient::close()
srs_freep(transport); srs_freep(transport);
} }
int SrsBasicRtmpClient::connect_app() srs_error_t SrsBasicRtmpClient::connect_app()
{ {
return do_connect_app(srs_get_public_internet_address(), false); return do_connect_app(srs_get_public_internet_address(), false);
} }
int SrsBasicRtmpClient::do_connect_app(string local_ip, bool debug) srs_error_t SrsBasicRtmpClient::do_connect_app(string local_ip, bool debug)
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
// args of request takes the srs info. // args of request takes the srs info.
if (req->args == NULL) { if (req->args == NULL) {
@ -150,40 +143,34 @@ int SrsBasicRtmpClient::do_connect_app(string local_ip, bool debug)
// upnode server identity will show in the connect_app of client. // upnode server identity will show in the connect_app of client.
// @see https://github.com/ossrs/srs/issues/160 // @see https://github.com/ossrs/srs/issues/160
// the debug_srs_upnode is config in vhost and default to true. // the debug_srs_upnode is config in vhost and default to true.
if ((ret = client->connect_app(req->app, tc_url, req, debug, NULL)) != ERROR_SUCCESS) { if ((err = client->connect_app(req->app, tc_url, req, debug, NULL)) != srs_success) {
srs_error("sdk: connect with server failed, tcUrl=%s, dsu=%d. ret=%d", return srs_error_wrap(err, "connect app tcUrl=%s, debug=%d", tc_url.c_str(), debug);
tc_url.c_str(), debug, ret);
return ret;
} }
return ret; return err;
} }
int SrsBasicRtmpClient::publish() srs_error_t SrsBasicRtmpClient::publish()
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
// publish. // publish.
if ((ret = client->publish(req->stream, stream_id)) != ERROR_SUCCESS) { if ((err = client->publish(req->stream, stream_id)) != srs_success) {
srs_error("sdk: publish failed, stream=%s, stream_id=%d. ret=%d", return srs_error_wrap(err, "publish failed, stream=%s, stream_id=%d", req->stream.c_str(), stream_id);
req->stream.c_str(), stream_id, ret);
return ret;
} }
return ret; return err;
} }
int SrsBasicRtmpClient::play() srs_error_t SrsBasicRtmpClient::play()
{ {
int ret = ERROR_SUCCESS; srs_error_t err = srs_success;
if ((ret = client->play(req->stream, stream_id)) != ERROR_SUCCESS) { if ((err = client->play(req->stream, stream_id)) != srs_success) {
srs_error("connect with server failed, stream=%s, stream_id=%d. ret=%d", return srs_error_wrap(err, "connect with server failed, stream=%s, stream_id=%d", req->stream.c_str(), stream_id);
req->stream.c_str(), stream_id, ret);
return ret;
} }
return ret; return err;
} }
void SrsBasicRtmpClient::kbps_sample(const char* label, int64_t age) void SrsBasicRtmpClient::kbps_sample(const char* label, int64_t age)
@ -219,22 +206,22 @@ int SrsBasicRtmpClient::sid()
return stream_id; return stream_id;
} }
int SrsBasicRtmpClient::recv_message(SrsCommonMessage** pmsg) srs_error_t SrsBasicRtmpClient::recv_message(SrsCommonMessage** pmsg)
{ {
return client->recv_message(pmsg); return client->recv_message(pmsg);
} }
int SrsBasicRtmpClient::decode_message(SrsCommonMessage* msg, SrsPacket** ppacket) srs_error_t SrsBasicRtmpClient::decode_message(SrsCommonMessage* msg, SrsPacket** ppacket)
{ {
return client->decode_message(msg, ppacket); return client->decode_message(msg, ppacket);
} }
int SrsBasicRtmpClient::send_and_free_messages(SrsSharedPtrMessage** msgs, int nb_msgs) srs_error_t SrsBasicRtmpClient::send_and_free_messages(SrsSharedPtrMessage** msgs, int nb_msgs)
{ {
return client->send_and_free_messages(msgs, nb_msgs, stream_id); return client->send_and_free_messages(msgs, nb_msgs, stream_id);
} }
int SrsBasicRtmpClient::send_and_free_message(SrsSharedPtrMessage* msg) srs_error_t SrsBasicRtmpClient::send_and_free_message(SrsSharedPtrMessage* msg)
{ {
return client->send_and_free_message(msg, stream_id); return client->send_and_free_message(msg, stream_id);
} }

View file

@ -68,22 +68,22 @@ public:
public: public:
// Connect, handshake and connect app to RTMP server. // Connect, handshake and connect app to RTMP server.
// @remark We always close the transport. // @remark We always close the transport.
virtual int connect(); virtual srs_error_t connect();
virtual void close(); virtual void close();
protected: protected:
virtual int connect_app(); virtual srs_error_t connect_app();
virtual int do_connect_app(std::string local_ip, bool debug); virtual srs_error_t do_connect_app(std::string local_ip, bool debug);
public: public:
virtual int publish(); virtual srs_error_t publish();
virtual int play(); virtual srs_error_t play();
virtual void kbps_sample(const char* label, int64_t age); virtual void kbps_sample(const char* label, int64_t age);
virtual void kbps_sample(const char* label, int64_t age, int msgs); virtual void kbps_sample(const char* label, int64_t age, int msgs);
virtual int sid(); virtual int sid();
public: public:
virtual int recv_message(SrsCommonMessage** pmsg); virtual srs_error_t recv_message(SrsCommonMessage** pmsg);
virtual int decode_message(SrsCommonMessage* msg, SrsPacket** ppacket); virtual srs_error_t decode_message(SrsCommonMessage* msg, SrsPacket** ppacket);
virtual int send_and_free_messages(SrsSharedPtrMessage** msgs, int nb_msgs); virtual srs_error_t send_and_free_messages(SrsSharedPtrMessage** msgs, int nb_msgs);
virtual int send_and_free_message(SrsSharedPtrMessage* msg); virtual srs_error_t send_and_free_message(SrsSharedPtrMessage* msg);
public: public:
virtual void set_recv_timeout(int64_t timeout); virtual void set_recv_timeout(int64_t timeout);
}; };