Skip to content

Commit cfbbe30

Browse files
committed
HTTP: Skip body and left message by upgrade. v5.0.73
1 parent d4ce877 commit cfbbe30

File tree

4 files changed

+16
-52
lines changed

4 files changed

+16
-52
lines changed

trunk/doc/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ The changelog for SRS.
77

88
## SRS 5.0 Changelog
99

10+
* v5.0, 2022-10-05, HTTP: Skip body and left message by upgrade. v5.0.73
1011
* v5.0, 2022-10-02, ST: Support set context id while thread running. v5.0.72
1112
* v5.0, 2022-09-30, RTC: Refine SDP to support GB28181 SSRC spec. v5.0.71
1213
* v5.0, 2022-09-30, GB28181: Refine HTTP parser to support SIP. v5.0.70

trunk/src/core/srs_core_version5.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@
99

1010
#define VERSION_MAJOR 5
1111
#define VERSION_MINOR 0
12-
#define VERSION_REVISION 72
12+
#define VERSION_REVISION 73
1313

1414
#endif

trunk/src/protocol/srs_protocol_http_conn.cpp

Lines changed: 14 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ SrsHttpParser::SrsHttpParser()
2626
buffer = new SrsFastStream();
2727
header = NULL;
2828

29-
p_body_start = p_header_tail = NULL;
3029
type_ = HTTP_REQUEST;
3130
parsed_type_ = HTTP_BOTH;
3231
}
@@ -74,8 +73,6 @@ srs_error_t SrsHttpParser::parse_message(ISrsReader* reader, ISrsHttpMessage** p
7473
// Reset parser data and state.
7574
state = SrsHttpParseStateInit;
7675
memset(&hp_header, 0, sizeof(http_parser));
77-
// The body that we have read from cache.
78-
p_body_start = p_header_tail = NULL;
7976
// We must reset the field name and value, because we may get a partial value in on_header_value.
8077
field_name = field_value = "";
8178
// Reset the url.
@@ -98,6 +95,8 @@ srs_error_t SrsHttpParser::parse_message(ISrsReader* reader, ISrsHttpMessage** p
9895
parsed_type_ = HTTP_BOTH;
9996
// callback object ptr.
10097
parser.data = (void*)this;
98+
// Always skip body, because we only want to parse the header.
99+
parser.flags |= F_SKIPBODY;
101100

102101
// do parse
103102
if ((err = parse_message_imp(reader)) != srs_success) {
@@ -131,23 +130,10 @@ srs_error_t SrsHttpParser::parse_message_imp(ISrsReader* reader)
131130
ssize_t consumed = http_parser_execute(&parser, &settings, buffer->bytes(), buffer->size());
132131

133132
// The error is set in http_errno.
134-
enum http_errno code;
135-
if ((code = HTTP_PARSER_ERRNO(&parser)) != HPE_OK) {
136-
return srs_error_new(ERROR_HTTP_PARSE_HEADER, "parse %dB, nparsed=%d, err=%d/%s %s",
137-
buffer->size(), (int)consumed, code, http_errno_name(code), http_errno_description(code));
138-
}
139-
140-
// When buffer consumed these bytes, it's dropped so the new ptr is actually the HTTP body. But http-parser
141-
// doesn't indicate the specific sizeof header, so we must finger it out.
142-
// @remark We shouldn't use on_body, because it only works for normal case, and losts the chunk header and length.
143-
// @see https://github.com/ossrs/srs/issues/1508
144-
if (p_header_tail && buffer->bytes() < p_body_start) {
145-
for (const char* p = p_header_tail; p <= p_body_start - 4; p++) {
146-
if (p[0] == SRS_CONSTS_CR && p[1] == SRS_CONSTS_LF && p[2] == SRS_CONSTS_CR && p[3] == SRS_CONSTS_LF) {
147-
consumed = p + 4 - buffer->bytes();
148-
break;
149-
}
150-
}
133+
enum http_errno code = HTTP_PARSER_ERRNO(&parser);
134+
if (code != HPE_OK) {
135+
return srs_error_new(ERROR_HTTP_PARSE_HEADER, "parse %dB, nparsed=%d, err=%d/%s %s",
136+
buffer->size(), (int)consumed, code, http_errno_name(code), http_errno_description(code));
151137
}
152138

153139
srs_info("size=%d, nparsed=%d", buffer->size(), (int)consumed);
@@ -201,14 +187,15 @@ int SrsHttpParser::on_headers_complete(http_parser* parser)
201187
// save the parser when header parse completed.
202188
obj->state = SrsHttpParseStateHeaderComplete;
203189

204-
// We must update the body start when header complete, because sometimes we only got header.
205-
// When we got the body start event, we will update it to much precious position.
206-
obj->p_body_start = obj->buffer->bytes() + obj->buffer->size();
207-
208190
srs_info("***HEADERS COMPLETE***");
209-
210-
// see http_parser.c:1570, return 1 to skip body.
211-
return 0;
191+
192+
// The return code of this callback:
193+
// 0: Continue to process body.
194+
// 1: Skip body, but continue to parse util all data parsed.
195+
// 2: Upgrade and skip body and left message, because it is in a different protocol.
196+
// N: Error and failed as HPE_CB_headers_complete.
197+
// We choose 2 because we only want to parse the header, not the body.
198+
return 2;
212199
}
213200

214201
int SrsHttpParser::on_message_complete(http_parser* parser)
@@ -233,11 +220,6 @@ int SrsHttpParser::on_url(http_parser* parser, const char* at, size_t length)
233220
// Note that this function might be called for multiple times, and we got pieces of content.
234221
obj->url.append(at, (int)length);
235222
}
236-
237-
// When header parsed, we must save the position of start for body,
238-
// because we have to consume the header in buffer.
239-
// @see https://github.com/ossrs/srs/issues/1508
240-
obj->p_header_tail = at;
241223

242224
srs_info("Method: %d, Url: %.*s", parser->method, (int)length, at);
243225

@@ -257,11 +239,6 @@ int SrsHttpParser::on_header_field(http_parser* parser, const char* at, size_t l
257239
if (length > 0) {
258240
obj->field_name.append(at, (int)length);
259241
}
260-
261-
// When header parsed, we must save the position of start for body,
262-
// because we have to consume the header in buffer.
263-
// @see https://github.com/ossrs/srs/issues/1508
264-
obj->p_header_tail = at;
265242

266243
srs_info("Header field(%d bytes): %.*s", (int)length, (int)length, at);
267244
return 0;
@@ -274,11 +251,6 @@ int SrsHttpParser::on_header_value(http_parser* parser, const char* at, size_t l
274251

275252
if (length > 0) {
276253
obj->field_value.append(at, (int)length);
277-
278-
// When header parsed, we must save the position of start for body,
279-
// because we have to consume the header in buffer.
280-
// @see https://github.com/ossrs/srs/issues/1508
281-
obj->p_header_tail = at;
282254
}
283255

284256
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)
293265
// save the parser when body parsed.
294266
obj->state = SrsHttpParseStateBody;
295267

296-
// Used to discover the header length.
297-
// @see https://github.com/ossrs/srs/issues/1508
298-
obj->p_body_start = at;
299-
300268
srs_info("Body: %.*s", (int)length, at);
301269

302270
return 0;

trunk/src/protocol/srs_protocol_http_conn.hpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,6 @@ class SrsHttpParser
4141
SrsHttpHeader* header;
4242
enum http_parser_type type_;
4343
enum http_parser_type parsed_type_;
44-
private:
45-
// Point to the start of body.
46-
const char* p_body_start;
47-
// To discover the length of header, point to the last few bytes in header.
48-
const char* p_header_tail;
4944
public:
5045
SrsHttpParser();
5146
virtual ~SrsHttpParser();

0 commit comments

Comments
 (0)