mirror of
https://github.com/ossrs/srs.git
synced 2025-02-13 11:51:57 +00:00
HTTP: Skip body and left message by upgrade. v5.0.73
This commit is contained in:
parent
d4ce877407
commit
cfbbe3044f
4 changed files with 16 additions and 52 deletions
|
@ -7,6 +7,7 @@ The changelog for SRS.
|
||||||
|
|
||||||
## SRS 5.0 Changelog
|
## SRS 5.0 Changelog
|
||||||
|
|
||||||
|
* v5.0, 2022-10-05, HTTP: Skip body and left message by upgrade. v5.0.73
|
||||||
* v5.0, 2022-10-02, ST: Support set context id while thread running. v5.0.72
|
* v5.0, 2022-10-02, ST: Support set context id while thread running. v5.0.72
|
||||||
* v5.0, 2022-09-30, RTC: Refine SDP to support GB28181 SSRC spec. v5.0.71
|
* v5.0, 2022-09-30, RTC: Refine SDP to support GB28181 SSRC spec. v5.0.71
|
||||||
* v5.0, 2022-09-30, GB28181: Refine HTTP parser to support SIP. v5.0.70
|
* v5.0, 2022-09-30, GB28181: Refine HTTP parser to support SIP. v5.0.70
|
||||||
|
|
|
@ -9,6 +9,6 @@
|
||||||
|
|
||||||
#define VERSION_MAJOR 5
|
#define VERSION_MAJOR 5
|
||||||
#define VERSION_MINOR 0
|
#define VERSION_MINOR 0
|
||||||
#define VERSION_REVISION 72
|
#define VERSION_REVISION 73
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -26,7 +26,6 @@ SrsHttpParser::SrsHttpParser()
|
||||||
buffer = new SrsFastStream();
|
buffer = new SrsFastStream();
|
||||||
header = NULL;
|
header = NULL;
|
||||||
|
|
||||||
p_body_start = p_header_tail = NULL;
|
|
||||||
type_ = HTTP_REQUEST;
|
type_ = HTTP_REQUEST;
|
||||||
parsed_type_ = HTTP_BOTH;
|
parsed_type_ = HTTP_BOTH;
|
||||||
}
|
}
|
||||||
|
@ -74,8 +73,6 @@ srs_error_t SrsHttpParser::parse_message(ISrsReader* reader, ISrsHttpMessage** p
|
||||||
// Reset parser data and state.
|
// Reset parser data and state.
|
||||||
state = SrsHttpParseStateInit;
|
state = SrsHttpParseStateInit;
|
||||||
memset(&hp_header, 0, sizeof(http_parser));
|
memset(&hp_header, 0, sizeof(http_parser));
|
||||||
// The body that we have read from cache.
|
|
||||||
p_body_start = p_header_tail = NULL;
|
|
||||||
// We must reset the field name and value, because we may get a partial value in on_header_value.
|
// We must reset the field name and value, because we may get a partial value in on_header_value.
|
||||||
field_name = field_value = "";
|
field_name = field_value = "";
|
||||||
// Reset the url.
|
// Reset the url.
|
||||||
|
@ -98,6 +95,8 @@ srs_error_t SrsHttpParser::parse_message(ISrsReader* reader, ISrsHttpMessage** p
|
||||||
parsed_type_ = HTTP_BOTH;
|
parsed_type_ = HTTP_BOTH;
|
||||||
// callback object ptr.
|
// callback object ptr.
|
||||||
parser.data = (void*)this;
|
parser.data = (void*)this;
|
||||||
|
// Always skip body, because we only want to parse the header.
|
||||||
|
parser.flags |= F_SKIPBODY;
|
||||||
|
|
||||||
// do parse
|
// do parse
|
||||||
if ((err = parse_message_imp(reader)) != srs_success) {
|
if ((err = parse_message_imp(reader)) != srs_success) {
|
||||||
|
@ -131,25 +130,12 @@ srs_error_t SrsHttpParser::parse_message_imp(ISrsReader* reader)
|
||||||
ssize_t consumed = http_parser_execute(&parser, &settings, buffer->bytes(), buffer->size());
|
ssize_t consumed = http_parser_execute(&parser, &settings, buffer->bytes(), buffer->size());
|
||||||
|
|
||||||
// The error is set in http_errno.
|
// The error is set in http_errno.
|
||||||
enum http_errno code;
|
enum http_errno code = HTTP_PARSER_ERRNO(&parser);
|
||||||
if ((code = HTTP_PARSER_ERRNO(&parser)) != HPE_OK) {
|
if (code != HPE_OK) {
|
||||||
return srs_error_new(ERROR_HTTP_PARSE_HEADER, "parse %dB, nparsed=%d, err=%d/%s %s",
|
return srs_error_new(ERROR_HTTP_PARSE_HEADER, "parse %dB, nparsed=%d, err=%d/%s %s",
|
||||||
buffer->size(), (int)consumed, code, http_errno_name(code), http_errno_description(code));
|
buffer->size(), (int)consumed, code, http_errno_name(code), http_errno_description(code));
|
||||||
}
|
}
|
||||||
|
|
||||||
// When buffer consumed these bytes, it's dropped so the new ptr is actually the HTTP body. But http-parser
|
|
||||||
// doesn't indicate the specific sizeof header, so we must finger it out.
|
|
||||||
// @remark We shouldn't use on_body, because it only works for normal case, and losts the chunk header and length.
|
|
||||||
// @see https://github.com/ossrs/srs/issues/1508
|
|
||||||
if (p_header_tail && buffer->bytes() < p_body_start) {
|
|
||||||
for (const char* p = p_header_tail; p <= p_body_start - 4; p++) {
|
|
||||||
if (p[0] == SRS_CONSTS_CR && p[1] == SRS_CONSTS_LF && p[2] == SRS_CONSTS_CR && p[3] == SRS_CONSTS_LF) {
|
|
||||||
consumed = p + 4 - buffer->bytes();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
srs_info("size=%d, nparsed=%d", buffer->size(), (int)consumed);
|
srs_info("size=%d, nparsed=%d", buffer->size(), (int)consumed);
|
||||||
|
|
||||||
// Only consume the header bytes.
|
// Only consume the header bytes.
|
||||||
|
@ -201,14 +187,15 @@ int SrsHttpParser::on_headers_complete(http_parser* parser)
|
||||||
// save the parser when header parse completed.
|
// save the parser when header parse completed.
|
||||||
obj->state = SrsHttpParseStateHeaderComplete;
|
obj->state = SrsHttpParseStateHeaderComplete;
|
||||||
|
|
||||||
// We must update the body start when header complete, because sometimes we only got header.
|
|
||||||
// When we got the body start event, we will update it to much precious position.
|
|
||||||
obj->p_body_start = obj->buffer->bytes() + obj->buffer->size();
|
|
||||||
|
|
||||||
srs_info("***HEADERS COMPLETE***");
|
srs_info("***HEADERS COMPLETE***");
|
||||||
|
|
||||||
// see http_parser.c:1570, return 1 to skip body.
|
// The return code of this callback:
|
||||||
return 0;
|
// 0: Continue to process body.
|
||||||
|
// 1: Skip body, but continue to parse util all data parsed.
|
||||||
|
// 2: Upgrade and skip body and left message, because it is in a different protocol.
|
||||||
|
// N: Error and failed as HPE_CB_headers_complete.
|
||||||
|
// We choose 2 because we only want to parse the header, not the body.
|
||||||
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsHttpParser::on_message_complete(http_parser* parser)
|
int SrsHttpParser::on_message_complete(http_parser* parser)
|
||||||
|
@ -234,11 +221,6 @@ int SrsHttpParser::on_url(http_parser* parser, const char* at, size_t length)
|
||||||
obj->url.append(at, (int)length);
|
obj->url.append(at, (int)length);
|
||||||
}
|
}
|
||||||
|
|
||||||
// When header parsed, we must save the position of start for body,
|
|
||||||
// because we have to consume the header in buffer.
|
|
||||||
// @see https://github.com/ossrs/srs/issues/1508
|
|
||||||
obj->p_header_tail = at;
|
|
||||||
|
|
||||||
srs_info("Method: %d, Url: %.*s", parser->method, (int)length, at);
|
srs_info("Method: %d, Url: %.*s", parser->method, (int)length, at);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -258,11 +240,6 @@ int SrsHttpParser::on_header_field(http_parser* parser, const char* at, size_t l
|
||||||
obj->field_name.append(at, (int)length);
|
obj->field_name.append(at, (int)length);
|
||||||
}
|
}
|
||||||
|
|
||||||
// When header parsed, we must save the position of start for body,
|
|
||||||
// because we have to consume the header in buffer.
|
|
||||||
// @see https://github.com/ossrs/srs/issues/1508
|
|
||||||
obj->p_header_tail = at;
|
|
||||||
|
|
||||||
srs_info("Header field(%d bytes): %.*s", (int)length, (int)length, at);
|
srs_info("Header field(%d bytes): %.*s", (int)length, (int)length, at);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -274,11 +251,6 @@ int SrsHttpParser::on_header_value(http_parser* parser, const char* at, size_t l
|
||||||
|
|
||||||
if (length > 0) {
|
if (length > 0) {
|
||||||
obj->field_value.append(at, (int)length);
|
obj->field_value.append(at, (int)length);
|
||||||
|
|
||||||
// When header parsed, we must save the position of start for body,
|
|
||||||
// because we have to consume the header in buffer.
|
|
||||||
// @see https://github.com/ossrs/srs/issues/1508
|
|
||||||
obj->p_header_tail = at;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
srs_info("Header value(%d bytes): %.*s", (int)length, (int)length, at);
|
srs_info("Header value(%d bytes): %.*s", (int)length, (int)length, at);
|
||||||
|
@ -293,10 +265,6 @@ int SrsHttpParser::on_body(http_parser* parser, const char* at, size_t length)
|
||||||
// save the parser when body parsed.
|
// save the parser when body parsed.
|
||||||
obj->state = SrsHttpParseStateBody;
|
obj->state = SrsHttpParseStateBody;
|
||||||
|
|
||||||
// Used to discover the header length.
|
|
||||||
// @see https://github.com/ossrs/srs/issues/1508
|
|
||||||
obj->p_body_start = at;
|
|
||||||
|
|
||||||
srs_info("Body: %.*s", (int)length, at);
|
srs_info("Body: %.*s", (int)length, at);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -41,11 +41,6 @@ private:
|
||||||
SrsHttpHeader* header;
|
SrsHttpHeader* header;
|
||||||
enum http_parser_type type_;
|
enum http_parser_type type_;
|
||||||
enum http_parser_type parsed_type_;
|
enum http_parser_type parsed_type_;
|
||||||
private:
|
|
||||||
// Point to the start of body.
|
|
||||||
const char* p_body_start;
|
|
||||||
// To discover the length of header, point to the last few bytes in header.
|
|
||||||
const char* p_header_tail;
|
|
||||||
public:
|
public:
|
||||||
SrsHttpParser();
|
SrsHttpParser();
|
||||||
virtual ~SrsHttpParser();
|
virtual ~SrsHttpParser();
|
||||||
|
|
Loading…
Reference in a new issue