mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
change to 0.9.42, add http parse framework
This commit is contained in:
parent
5aa0043934
commit
51c1615173
8 changed files with 214 additions and 37 deletions
|
@ -25,6 +25,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
||||
#include <srs_kernel_log.hpp>
|
||||
#include <srs_kernel_error.hpp>
|
||||
#include <srs_app_socket.hpp>
|
||||
|
||||
#define SRS_HTTP_HEADER_BUFFER 1024
|
||||
|
||||
SrsHttpConn::SrsHttpConn(SrsServer* srs_server, st_netfd_t client_stfd)
|
||||
: SrsConnection(srs_server, client_stfd)
|
||||
|
@ -44,13 +47,151 @@ int SrsHttpConn::do_cycle()
|
|||
return ret;
|
||||
}
|
||||
srs_trace("http get peer ip success. ip=%s", ip);
|
||||
|
||||
// setup http parser
|
||||
http_parser_settings settings;
|
||||
|
||||
memset(&settings, 0, sizeof(settings));
|
||||
settings.on_message_begin = on_message_begin;
|
||||
settings.on_url = on_url;
|
||||
settings.on_header_field = on_header_field;
|
||||
settings.on_header_value = on_header_value;
|
||||
settings.on_headers_complete = on_headers_complete;
|
||||
settings.on_body = on_body;
|
||||
settings.on_message_complete = on_message_complete;
|
||||
|
||||
http_parser parser;
|
||||
http_parser_init(&parser, HTTP_REQUEST);
|
||||
// callback object ptr.
|
||||
parser.data = (void*)this;
|
||||
|
||||
// underlayer socket
|
||||
SrsSocket skt(stfd);
|
||||
|
||||
for (;;) {
|
||||
if ((ret = process_request(&skt, &parser, &settings)) != ERROR_SUCCESS) {
|
||||
if (!srs_is_client_gracefully_close(ret)) {
|
||||
srs_error("http client cycle failed. ret=%d", ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsHttpConn::process_request(SrsSocket* skt, http_parser* parser, http_parser_settings* settings)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
// reset response header.
|
||||
http_header = NULL;
|
||||
|
||||
// parser header.
|
||||
char buf[SRS_HTTP_HEADER_BUFFER];
|
||||
for (;;) {
|
||||
ssize_t nread;
|
||||
if ((ret = skt->read(buf, (size_t)sizeof(buf), &nread)) != ERROR_SUCCESS) {
|
||||
if (!srs_is_client_gracefully_close(ret)) {
|
||||
srs_error("read body from server failed. ret=%d", ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t nparsed = http_parser_execute(parser, settings, buf, nread);
|
||||
srs_info("read_size=%d, nparsed=%d", (int)nread, (int)nparsed);
|
||||
|
||||
// check header size.
|
||||
if (http_header) {
|
||||
int nb_body = nread - nparsed;
|
||||
|
||||
srs_info("http header parsed, size=%d, content-length=%"PRId64", nb_body=%d",
|
||||
http_header->nread, http_header->content_length, nb_body);
|
||||
|
||||
return complete_header(skt, http_header, buf + nparsed, nb_body);
|
||||
}
|
||||
|
||||
if (nparsed != nread) {
|
||||
ret = ERROR_HTTP_PARSE_HEADER;
|
||||
srs_error("parse response error, parsed(%d)!=read(%d), ret=%d", (int)nparsed, (int)nread, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsHttpConn::complete_header(SrsSocket* skt, http_parser* header, char* body, int nb_body)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
char data[] = "HTTP/1.1 200 OK\r\n"
|
||||
"Server: SRS/"RTMP_SIG_SRS_VERSION"\r\n"
|
||||
"Content-Length: 15\r\n"
|
||||
"Content-Type: text/html;charset=utf-8\r\n\r\n"
|
||||
"hello http/1.1~";
|
||||
st_write(stfd, data, sizeof(data), -1);
|
||||
|
||||
skt->write(data, sizeof(data), NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsHttpConn::on_message_begin(http_parser* parser)
|
||||
{
|
||||
SrsHttpConn* obj = (SrsHttpConn*)parser->data;
|
||||
(void)obj;
|
||||
srs_trace("***MESSAGE BEGIN***");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SrsHttpConn::on_headers_complete(http_parser* parser)
|
||||
{
|
||||
SrsHttpConn* obj = (SrsHttpConn*)parser->data;
|
||||
(void)obj;
|
||||
srs_trace("***HEADERS COMPLETE***");
|
||||
|
||||
// see http_parser.c:1570, return 1 to skip body.
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SrsHttpConn::on_message_complete(http_parser* parser)
|
||||
{
|
||||
SrsHttpConn* obj = (SrsHttpConn*)parser->data;
|
||||
srs_trace("***MESSAGE COMPLETE***\n");
|
||||
|
||||
// save the parser when header parse completed.
|
||||
obj->http_header = parser;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SrsHttpConn::on_url(http_parser* parser, const char* at, size_t length)
|
||||
{
|
||||
SrsHttpConn* obj = (SrsHttpConn*)parser->data;
|
||||
(void)obj;
|
||||
srs_trace("Method: %d, Url: %.*s", parser->method, (int)length, at);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SrsHttpConn::on_header_field(http_parser* parser, const char* at, size_t length)
|
||||
{
|
||||
SrsHttpConn* obj = (SrsHttpConn*)parser->data;
|
||||
(void)obj;
|
||||
srs_trace("Header field: %.*s", (int)length, at);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SrsHttpConn::on_header_value(http_parser* parser, const char* at, size_t length)
|
||||
{
|
||||
SrsHttpConn* obj = (SrsHttpConn*)parser->data;
|
||||
(void)obj;
|
||||
srs_trace("Header value: %.*s", (int)length, at);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SrsHttpConn::on_body(http_parser* parser, const char* at, size_t length)
|
||||
{
|
||||
SrsHttpConn* obj = (SrsHttpConn*)parser->data;
|
||||
(void)obj;
|
||||
srs_trace("Body: %.*s", (int)length, at);
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue