@@ -26,7 +26,6 @@ SrsHttpParser::SrsHttpParser()
26
26
buffer = new SrsFastStream ();
27
27
header = NULL ;
28
28
29
- p_body_start = p_header_tail = NULL ;
30
29
type_ = HTTP_REQUEST;
31
30
parsed_type_ = HTTP_BOTH;
32
31
}
@@ -74,8 +73,6 @@ srs_error_t SrsHttpParser::parse_message(ISrsReader* reader, ISrsHttpMessage** p
74
73
// Reset parser data and state.
75
74
state = SrsHttpParseStateInit;
76
75
memset (&hp_header, 0 , sizeof (http_parser));
77
- // The body that we have read from cache.
78
- p_body_start = p_header_tail = NULL ;
79
76
// We must reset the field name and value, because we may get a partial value in on_header_value.
80
77
field_name = field_value = " " ;
81
78
// Reset the url.
@@ -98,6 +95,8 @@ srs_error_t SrsHttpParser::parse_message(ISrsReader* reader, ISrsHttpMessage** p
98
95
parsed_type_ = HTTP_BOTH;
99
96
// callback object ptr.
100
97
parser.data = (void *)this ;
98
+ // Always skip body, because we only want to parse the header.
99
+ parser.flags |= F_SKIPBODY;
101
100
102
101
// do parse
103
102
if ((err = parse_message_imp (reader)) != srs_success) {
@@ -131,23 +130,10 @@ srs_error_t SrsHttpParser::parse_message_imp(ISrsReader* reader)
131
130
ssize_t consumed = http_parser_execute (&parser, &settings, buffer->bytes (), buffer->size ());
132
131
133
132
// 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));
151
137
}
152
138
153
139
srs_info (" size=%d, nparsed=%d" , buffer->size (), (int )consumed);
@@ -201,14 +187,15 @@ int SrsHttpParser::on_headers_complete(http_parser* parser)
201
187
// save the parser when header parse completed.
202
188
obj->state = SrsHttpParseStateHeaderComplete;
203
189
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
-
208
190
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 ;
212
199
}
213
200
214
201
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)
233
220
// Note that this function might be called for multiple times, and we got pieces of content.
234
221
obj->url .append (at, (int )length);
235
222
}
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;
241
223
242
224
srs_info (" Method: %d, Url: %.*s" , parser->method , (int )length, at);
243
225
@@ -257,11 +239,6 @@ int SrsHttpParser::on_header_field(http_parser* parser, const char* at, size_t l
257
239
if (length > 0 ) {
258
240
obj->field_name .append (at, (int )length);
259
241
}
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;
265
242
266
243
srs_info (" Header field(%d bytes): %.*s" , (int )length, (int )length, at);
267
244
return 0 ;
@@ -274,11 +251,6 @@ int SrsHttpParser::on_header_value(http_parser* parser, const char* at, size_t l
274
251
275
252
if (length > 0 ) {
276
253
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;
282
254
}
283
255
284
256
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)
293
265
// save the parser when body parsed.
294
266
obj->state = SrsHttpParseStateBody;
295
267
296
- // Used to discover the header length.
297
- // @see https://github.com/ossrs/srs/issues/1508
298
- obj->p_body_start = at;
299
-
300
268
srs_info (" Body: %.*s" , (int )length, at);
301
269
302
270
return 0 ;
0 commit comments