1
0
Fork 0
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:
winlin 2014-04-01 12:36:56 +08:00
parent 5aa0043934
commit 51c1615173
8 changed files with 214 additions and 37 deletions

View file

@ -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;
}