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

Refactor HTTP Message by decoupling with http_parser

This commit is contained in:
winlin 2019-12-16 15:12:26 +08:00
parent 547cd4f518
commit dcb7b6aae0
4 changed files with 52 additions and 48 deletions

View file

@ -428,9 +428,6 @@ public:
virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
}; };
// For http header.
typedef std::pair<std::string, std::string> SrsHttpHeaderField;
// A Request represents an HTTP request received by a server // A Request represents an HTTP request received by a server
// or to be sent by a client. // or to be sent by a client.
// //

View file

@ -90,10 +90,14 @@ srs_error_t SrsHttpParser::parse_message(ISrsReader* reader, ISrsHttpMessage** p
} }
// create msg // create msg
SrsHttpMessage* msg = new SrsHttpMessage(reader); SrsHttpMessage* msg = new SrsHttpMessage(reader, buffer);
// Initialize the basic information.
bool keep_alive = http_should_keep_alive(&header);
msg->set_basic(header.method, header.status_code, header.content_length, keep_alive);
// initalize http msg, parse url. // initalize http msg, parse url.
if ((err = msg->update(url, jsonp, &header, buffer, headers)) != srs_success) { if ((err = msg->update(url, jsonp, headers)) != srs_success) {
srs_freep(msg); srs_freep(msg);
return srs_error_wrap(err, "update message"); return srs_error_wrap(err, "update message");
} }
@ -253,16 +257,21 @@ int SrsHttpParser::on_body(http_parser* parser, const char* at, size_t length)
return 0; return 0;
} }
SrsHttpMessage::SrsHttpMessage(ISrsReader* reader) : ISrsHttpMessage() SrsHttpMessage::SrsHttpMessage(ISrsReader* reader, SrsFastStream* buffer) : ISrsHttpMessage()
{ {
owner_conn = NULL; owner_conn = NULL;
chunked = false; chunked = false;
infinite_chunked = false; infinite_chunked = false;
keep_alive = true;
_uri = new SrsHttpUri(); _uri = new SrsHttpUri();
_body = new SrsHttpResponseReader(this, reader); _body = new SrsHttpResponseReader(this, reader, buffer);
_http_ts_send_buffer = new char[SRS_HTTP_TS_SEND_BUFFER_SIZE]; _http_ts_send_buffer = new char[SRS_HTTP_TS_SEND_BUFFER_SIZE];
jsonp = false; jsonp = false;
_method = 0;
_status = 0;
_content_length = 0;
_keep_alive = true;
} }
SrsHttpMessage::~SrsHttpMessage() SrsHttpMessage::~SrsHttpMessage()
@ -272,26 +281,25 @@ SrsHttpMessage::~SrsHttpMessage()
srs_freepa(_http_ts_send_buffer); srs_freepa(_http_ts_send_buffer);
} }
srs_error_t SrsHttpMessage::update(string url, bool allow_jsonp, http_parser* header, SrsFastStream* body, vector<SrsHttpHeaderField>& headers) void SrsHttpMessage::set_basic(uint8_t method, uint16_t status, int64_t content_length, bool keep_alive)
{
_method = method;
_status = status;
_content_length = content_length;
_keep_alive = keep_alive;
}
srs_error_t SrsHttpMessage::update(string url, bool allow_jsonp, vector<SrsHttpHeaderField>& headers)
{ {
srs_error_t err = srs_success; srs_error_t err = srs_success;
_url = url; _url = url;
_header = *header;
_headers = headers; _headers = headers;
// whether chunked. // whether chunked.
std::string transfer_encoding = get_request_header("Transfer-Encoding"); std::string transfer_encoding = get_request_header("Transfer-Encoding");
chunked = (transfer_encoding == "chunked"); chunked = (transfer_encoding == "chunked");
// whether keep alive.
keep_alive = http_should_keep_alive(header);
// set the buffer.
if ((err = _body->initialize(body)) != srs_success) {
return srs_error_wrap(err, "init body");
}
// parse uri from url. // parse uri from url.
std::string host = get_request_header("Host"); std::string host = get_request_header("Host");
@ -350,12 +358,12 @@ uint8_t SrsHttpMessage::method()
} }
} }
return (uint8_t)_header.method; return _method;
} }
uint16_t SrsHttpMessage::status_code() uint16_t SrsHttpMessage::status_code()
{ {
return (uint16_t)_header.status_code; return _status;
} }
string SrsHttpMessage::method_str() string SrsHttpMessage::method_str()
@ -405,7 +413,7 @@ bool SrsHttpMessage::is_http_delete()
bool SrsHttpMessage::is_http_options() bool SrsHttpMessage::is_http_options()
{ {
return _header.method == SRS_CONSTS_HTTP_OPTIONS; return _method == SRS_CONSTS_HTTP_OPTIONS;
} }
bool SrsHttpMessage::is_chunked() bool SrsHttpMessage::is_chunked()
@ -415,7 +423,7 @@ bool SrsHttpMessage::is_chunked()
bool SrsHttpMessage::is_keep_alive() bool SrsHttpMessage::is_keep_alive()
{ {
return keep_alive; return _keep_alive;
} }
bool SrsHttpMessage::is_infinite_chunked() bool SrsHttpMessage::is_infinite_chunked()
@ -524,7 +532,7 @@ ISrsHttpResponseReader* SrsHttpMessage::body_reader()
int64_t SrsHttpMessage::content_length() int64_t SrsHttpMessage::content_length()
{ {
return _header.content_length; return _content_length;
} }
string SrsHttpMessage::query_get(string key) string SrsHttpMessage::query_get(string key)
@ -865,32 +873,20 @@ srs_error_t SrsHttpResponseWriter::send_header(char* data, int size)
return skt->write((void*)buf.c_str(), buf.length(), NULL); return skt->write((void*)buf.c_str(), buf.length(), NULL);
} }
SrsHttpResponseReader::SrsHttpResponseReader(SrsHttpMessage* msg, ISrsReader* reader) SrsHttpResponseReader::SrsHttpResponseReader(SrsHttpMessage* msg, ISrsReader* reader, SrsFastStream* body)
{ {
skt = reader; skt = reader;
owner = msg; owner = msg;
is_eof = false; is_eof = false;
nb_total_read = 0; nb_total_read = 0;
nb_left_chunk = 0; nb_left_chunk = 0;
buffer = NULL; buffer = body;
} }
SrsHttpResponseReader::~SrsHttpResponseReader() SrsHttpResponseReader::~SrsHttpResponseReader()
{ {
} }
srs_error_t SrsHttpResponseReader::initialize(SrsFastStream* body)
{
srs_error_t err = srs_success;
nb_chunk = 0;
nb_left_chunk = 0;
nb_total_read = 0;
buffer = body;
return err;
}
bool SrsHttpResponseReader::eof() bool SrsHttpResponseReader::eof()
{ {
return is_eof; return is_eof;

View file

@ -37,6 +37,9 @@ class ISrsReader;
class SrsHttpResponseReader; class SrsHttpResponseReader;
class ISrsProtocolReadWriter; class ISrsProtocolReadWriter;
// For http header.
typedef std::pair<std::string, std::string> SrsHttpHeaderField;
// A wrapper for http-parser, // A wrapper for http-parser,
// provides HTTP message originted service. // provides HTTP message originted service.
class SrsHttpParser class SrsHttpParser
@ -101,8 +104,6 @@ private:
std::string _url; std::string _url;
// The extension of file, for example, .flv // The extension of file, for example, .flv
std::string _ext; std::string _ext;
// parsed http header.
http_parser _header;
// The body object, reader object. // The body object, reader object.
// @remark, user can get body in string by get_body(). // @remark, user can get body in string by get_body().
SrsHttpResponseReader* _body; SrsHttpResponseReader* _body;
@ -110,8 +111,6 @@ private:
bool chunked; bool chunked;
// Whether the body is infinite chunked. // Whether the body is infinite chunked.
bool infinite_chunked; bool infinite_chunked;
// Whether the request indicates should keep alive for the http connection.
bool keep_alive;
// The uri parser // The uri parser
SrsHttpUri* _uri; SrsHttpUri* _uri;
// Use a buffer to read and send ts file. // Use a buffer to read and send ts file.
@ -123,16 +122,25 @@ private:
std::map<std::string, std::string> _query; std::map<std::string, std::string> _query;
// The transport connection, can be NULL. // The transport connection, can be NULL.
SrsConnection* owner_conn; SrsConnection* owner_conn;
private:
uint8_t _method;
uint16_t _status;
int64_t _content_length;
// Whether the request indicates should keep alive for the http connection.
bool _keep_alive;
private:
// Whether request is jsonp. // Whether request is jsonp.
bool jsonp; bool jsonp;
// The method in QueryString will override the HTTP method. // The method in QueryString will override the HTTP method.
std::string jsonp_method; std::string jsonp_method;
public: public:
SrsHttpMessage(ISrsReader* io); SrsHttpMessage(ISrsReader* reader, SrsFastStream* buffer);
virtual ~SrsHttpMessage(); virtual ~SrsHttpMessage();
public: public:
// Set the basic information for HTTP request.
virtual void set_basic(uint8_t method, uint16_t status, int64_t content_length, bool keep_alive);
// set the original messages, then update the message. // set the original messages, then update the message.
virtual srs_error_t 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, std::vector<SrsHttpHeaderField>& headers);
public: public:
// Get the owner connection, maybe NULL. // Get the owner connection, maybe NULL.
virtual SrsConnection* connection(); virtual SrsConnection* connection();
@ -261,11 +269,10 @@ private:
// Already read total bytes. // Already read total bytes.
int64_t nb_total_read; int64_t nb_total_read;
public: public:
SrsHttpResponseReader(SrsHttpMessage* msg, ISrsReader* reader); // Generally the reader is the under-layer io such as socket,
// while buffer is a fast cache which may have cached some data from reader.
SrsHttpResponseReader(SrsHttpMessage* msg, ISrsReader* reader, SrsFastStream* buffer);
virtual ~SrsHttpResponseReader(); virtual ~SrsHttpResponseReader();
public:
// Initialize the response reader with buffer.
virtual srs_error_t initialize(SrsFastStream* buffer);
// Interface ISrsHttpResponseReader // Interface ISrsHttpResponseReader
public: public:
virtual bool eof(); virtual bool eof();

View file

@ -153,3 +153,7 @@ VOID TEST(ProtocolHTTPTest, HTTPHeader)
h.set_content_type("text/plain"); h.set_content_type("text/plain");
EXPECT_STREQ("text/plain", h.content_type().c_str()); EXPECT_STREQ("text/plain", h.content_type().c_str());
} }
VOID TEST(ProtocolHTTPTest, HTTPCommonHandler)
{
}