OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 part of dart.io; | 5 part of dart.io; |
6 | 6 |
7 // Global constants. | 7 // Global constants. |
8 class _Const { | 8 class _Const { |
9 // Bytes for "HTTP". | 9 // Bytes for "HTTP". |
10 static const HTTP = const [72, 84, 84, 80]; | 10 static const HTTP = const [72, 84, 84, 80]; |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 // CRLF | 266 // CRLF |
267 // [ message-body ] | 267 // [ message-body ] |
268 // start-line = Request-Line | Status-Line | 268 // start-line = Request-Line | Status-Line |
269 // Request-Line = Method SP Request-URI SP HTTP-Version CRLF | 269 // Request-Line = Method SP Request-URI SP HTTP-Version CRLF |
270 // Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF | 270 // Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF |
271 // message-header = field-name ":" [ field-value ] | 271 // message-header = field-name ":" [ field-value ] |
272 void _doParse() { | 272 void _doParse() { |
273 assert(!_parserCalled); | 273 assert(!_parserCalled); |
274 _parserCalled = true; | 274 _parserCalled = true; |
275 if (_state == _State.CLOSED) { | 275 if (_state == _State.CLOSED) { |
276 throw new HttpParserException("Data on closed connection"); | 276 throw new HttpException("Data on closed connection"); |
277 } | 277 } |
278 if (_state == _State.FAILURE) { | 278 if (_state == _State.FAILURE) { |
279 throw new HttpParserException("Data on failed connection"); | 279 throw new HttpException("Data on failed connection"); |
280 } | 280 } |
281 while (_buffer != null && | 281 while (_buffer != null && |
282 _index < _buffer.length && | 282 _index < _buffer.length && |
283 _state != _State.FAILURE && | 283 _state != _State.FAILURE && |
284 _state != _State.UPGRADED) { | 284 _state != _State.UPGRADED) { |
285 // Depending on _incoming, we either break on _bodyPaused or _paused. | 285 // Depending on _incoming, we either break on _bodyPaused or _paused. |
286 if ((_incoming != null && _bodyPaused) || | 286 if ((_incoming != null && _bodyPaused) || |
287 (_incoming == null && _paused)) { | 287 (_incoming == null && _paused)) { |
288 _parserCalled = false; | 288 _parserCalled = false; |
289 return; | 289 return; |
290 } | 290 } |
291 int byte = _buffer[_index++]; | 291 int byte = _buffer[_index++]; |
292 switch (_state) { | 292 switch (_state) { |
293 case _State.START: | 293 case _State.START: |
294 if (byte == _Const.HTTP[0]) { | 294 if (byte == _Const.HTTP[0]) { |
295 // Start parsing method or HTTP version. | 295 // Start parsing method or HTTP version. |
296 _httpVersionIndex = 1; | 296 _httpVersionIndex = 1; |
297 _state = _State.METHOD_OR_RESPONSE_HTTP_VERSION; | 297 _state = _State.METHOD_OR_RESPONSE_HTTP_VERSION; |
298 } else { | 298 } else { |
299 // Start parsing method. | 299 // Start parsing method. |
300 if (!_isTokenChar(byte)) { | 300 if (!_isTokenChar(byte)) { |
301 throw new HttpParserException("Invalid request method"); | 301 throw new HttpException("Invalid request method"); |
302 } | 302 } |
303 _method_or_status_code.add(byte); | 303 _method_or_status_code.add(byte); |
304 if (!_requestParser) { | 304 if (!_requestParser) { |
305 throw new HttpParserException("Invalid response line"); | 305 throw new HttpException("Invalid response line"); |
306 } | 306 } |
307 _state = _State.REQUEST_LINE_METHOD; | 307 _state = _State.REQUEST_LINE_METHOD; |
308 } | 308 } |
309 break; | 309 break; |
310 | 310 |
311 case _State.METHOD_OR_RESPONSE_HTTP_VERSION: | 311 case _State.METHOD_OR_RESPONSE_HTTP_VERSION: |
312 if (_httpVersionIndex < _Const.HTTP.length && | 312 if (_httpVersionIndex < _Const.HTTP.length && |
313 byte == _Const.HTTP[_httpVersionIndex]) { | 313 byte == _Const.HTTP[_httpVersionIndex]) { |
314 // Continue parsing HTTP version. | 314 // Continue parsing HTTP version. |
315 _httpVersionIndex++; | 315 _httpVersionIndex++; |
316 } else if (_httpVersionIndex == _Const.HTTP.length && | 316 } else if (_httpVersionIndex == _Const.HTTP.length && |
317 byte == _CharCode.SLASH) { | 317 byte == _CharCode.SLASH) { |
318 // HTTP/ parsed. As method is a token this cannot be a | 318 // HTTP/ parsed. As method is a token this cannot be a |
319 // method anymore. | 319 // method anymore. |
320 _httpVersionIndex++; | 320 _httpVersionIndex++; |
321 if (_requestParser) { | 321 if (_requestParser) { |
322 throw new HttpParserException("Invalid request line"); | 322 throw new HttpException("Invalid request line"); |
323 } | 323 } |
324 _state = _State.RESPONSE_HTTP_VERSION; | 324 _state = _State.RESPONSE_HTTP_VERSION; |
325 } else { | 325 } else { |
326 // Did not parse HTTP version. Expect method instead. | 326 // Did not parse HTTP version. Expect method instead. |
327 for (int i = 0; i < _httpVersionIndex; i++) { | 327 for (int i = 0; i < _httpVersionIndex; i++) { |
328 _method_or_status_code.add(_Const.HTTP[i]); | 328 _method_or_status_code.add(_Const.HTTP[i]); |
329 } | 329 } |
330 if (byte == _CharCode.SP) { | 330 if (byte == _CharCode.SP) { |
331 _state = _State.REQUEST_LINE_URI; | 331 _state = _State.REQUEST_LINE_URI; |
332 } else { | 332 } else { |
333 _method_or_status_code.add(byte); | 333 _method_or_status_code.add(byte); |
334 _httpVersion = _HttpVersion.UNDETERMINED; | 334 _httpVersion = _HttpVersion.UNDETERMINED; |
335 if (!_requestParser) { | 335 if (!_requestParser) { |
336 throw new HttpParserException("Invalid response line"); | 336 throw new HttpException("Invalid response line"); |
337 } | 337 } |
338 _state = _State.REQUEST_LINE_METHOD; | 338 _state = _State.REQUEST_LINE_METHOD; |
339 } | 339 } |
340 } | 340 } |
341 break; | 341 break; |
342 | 342 |
343 case _State.RESPONSE_HTTP_VERSION: | 343 case _State.RESPONSE_HTTP_VERSION: |
344 if (_httpVersionIndex < _Const.HTTP1DOT.length) { | 344 if (_httpVersionIndex < _Const.HTTP1DOT.length) { |
345 // Continue parsing HTTP version. | 345 // Continue parsing HTTP version. |
346 _expect(byte, _Const.HTTP1DOT[_httpVersionIndex]); | 346 _expect(byte, _Const.HTTP1DOT[_httpVersionIndex]); |
347 _httpVersionIndex++; | 347 _httpVersionIndex++; |
348 } else if (_httpVersionIndex == _Const.HTTP1DOT.length && | 348 } else if (_httpVersionIndex == _Const.HTTP1DOT.length && |
349 byte == _CharCode.ONE) { | 349 byte == _CharCode.ONE) { |
350 // HTTP/1.1 parsed. | 350 // HTTP/1.1 parsed. |
351 _httpVersion = _HttpVersion.HTTP11; | 351 _httpVersion = _HttpVersion.HTTP11; |
352 _persistentConnection = true; | 352 _persistentConnection = true; |
353 _httpVersionIndex++; | 353 _httpVersionIndex++; |
354 } else if (_httpVersionIndex == _Const.HTTP1DOT.length && | 354 } else if (_httpVersionIndex == _Const.HTTP1DOT.length && |
355 byte == _CharCode.ZERO) { | 355 byte == _CharCode.ZERO) { |
356 // HTTP/1.0 parsed. | 356 // HTTP/1.0 parsed. |
357 _httpVersion = _HttpVersion.HTTP10; | 357 _httpVersion = _HttpVersion.HTTP10; |
358 _persistentConnection = false; | 358 _persistentConnection = false; |
359 _httpVersionIndex++; | 359 _httpVersionIndex++; |
360 } else if (_httpVersionIndex == _Const.HTTP1DOT.length + 1) { | 360 } else if (_httpVersionIndex == _Const.HTTP1DOT.length + 1) { |
361 _expect(byte, _CharCode.SP); | 361 _expect(byte, _CharCode.SP); |
362 // HTTP version parsed. | 362 // HTTP version parsed. |
363 _state = _State.RESPONSE_LINE_STATUS_CODE; | 363 _state = _State.RESPONSE_LINE_STATUS_CODE; |
364 } else { | 364 } else { |
365 throw new HttpParserException("Invalid response line"); | 365 throw new HttpException("Invalid response line"); |
366 } | 366 } |
367 break; | 367 break; |
368 | 368 |
369 case _State.REQUEST_LINE_METHOD: | 369 case _State.REQUEST_LINE_METHOD: |
370 if (byte == _CharCode.SP) { | 370 if (byte == _CharCode.SP) { |
371 _state = _State.REQUEST_LINE_URI; | 371 _state = _State.REQUEST_LINE_URI; |
372 } else { | 372 } else { |
373 if (_Const.SEPARATORS_AND_CR_LF.indexOf(byte) != -1) { | 373 if (_Const.SEPARATORS_AND_CR_LF.indexOf(byte) != -1) { |
374 throw new HttpParserException("Invalid request method"); | 374 throw new HttpException("Invalid request method"); |
375 } | 375 } |
376 _method_or_status_code.add(byte); | 376 _method_or_status_code.add(byte); |
377 } | 377 } |
378 break; | 378 break; |
379 | 379 |
380 case _State.REQUEST_LINE_URI: | 380 case _State.REQUEST_LINE_URI: |
381 if (byte == _CharCode.SP) { | 381 if (byte == _CharCode.SP) { |
382 if (_uri_or_reason_phrase.length == 0) { | 382 if (_uri_or_reason_phrase.length == 0) { |
383 throw new HttpParserException("Invalid request URI"); | 383 throw new HttpException("Invalid request URI"); |
384 } | 384 } |
385 _state = _State.REQUEST_LINE_HTTP_VERSION; | 385 _state = _State.REQUEST_LINE_HTTP_VERSION; |
386 _httpVersionIndex = 0; | 386 _httpVersionIndex = 0; |
387 } else { | 387 } else { |
388 if (byte == _CharCode.CR || byte == _CharCode.LF) { | 388 if (byte == _CharCode.CR || byte == _CharCode.LF) { |
389 throw new HttpParserException("Invalid request URI"); | 389 throw new HttpException("Invalid request URI"); |
390 } | 390 } |
391 _uri_or_reason_phrase.add(byte); | 391 _uri_or_reason_phrase.add(byte); |
392 } | 392 } |
393 break; | 393 break; |
394 | 394 |
395 case _State.REQUEST_LINE_HTTP_VERSION: | 395 case _State.REQUEST_LINE_HTTP_VERSION: |
396 if (_httpVersionIndex < _Const.HTTP1DOT.length) { | 396 if (_httpVersionIndex < _Const.HTTP1DOT.length) { |
397 _expect(byte, _Const.HTTP11[_httpVersionIndex]); | 397 _expect(byte, _Const.HTTP11[_httpVersionIndex]); |
398 _httpVersionIndex++; | 398 _httpVersionIndex++; |
399 } else if (_httpVersionIndex == _Const.HTTP1DOT.length) { | 399 } else if (_httpVersionIndex == _Const.HTTP1DOT.length) { |
400 if (byte == _CharCode.ONE) { | 400 if (byte == _CharCode.ONE) { |
401 // HTTP/1.1 parsed. | 401 // HTTP/1.1 parsed. |
402 _httpVersion = _HttpVersion.HTTP11; | 402 _httpVersion = _HttpVersion.HTTP11; |
403 _persistentConnection = true; | 403 _persistentConnection = true; |
404 _httpVersionIndex++; | 404 _httpVersionIndex++; |
405 } else if (byte == _CharCode.ZERO) { | 405 } else if (byte == _CharCode.ZERO) { |
406 // HTTP/1.0 parsed. | 406 // HTTP/1.0 parsed. |
407 _httpVersion = _HttpVersion.HTTP10; | 407 _httpVersion = _HttpVersion.HTTP10; |
408 _persistentConnection = false; | 408 _persistentConnection = false; |
409 _httpVersionIndex++; | 409 _httpVersionIndex++; |
410 } else { | 410 } else { |
411 throw new HttpParserException("Invalid response line"); | 411 throw new HttpException("Invalid response line"); |
412 } | 412 } |
413 } else { | 413 } else { |
414 _expect(byte, _CharCode.CR); | 414 _expect(byte, _CharCode.CR); |
415 _state = _State.REQUEST_LINE_ENDING; | 415 _state = _State.REQUEST_LINE_ENDING; |
416 } | 416 } |
417 break; | 417 break; |
418 | 418 |
419 case _State.REQUEST_LINE_ENDING: | 419 case _State.REQUEST_LINE_ENDING: |
420 _expect(byte, _CharCode.LF); | 420 _expect(byte, _CharCode.LF); |
421 _messageType = _MessageType.REQUEST; | 421 _messageType = _MessageType.REQUEST; |
422 _state = _State.HEADER_START; | 422 _state = _State.HEADER_START; |
423 break; | 423 break; |
424 | 424 |
425 case _State.RESPONSE_LINE_STATUS_CODE: | 425 case _State.RESPONSE_LINE_STATUS_CODE: |
426 if (byte == _CharCode.SP) { | 426 if (byte == _CharCode.SP) { |
427 if (_method_or_status_code.length != 3) { | 427 if (_method_or_status_code.length != 3) { |
428 throw new HttpParserException("Invalid response status code"); | 428 throw new HttpException("Invalid response status code"); |
429 } | 429 } |
430 _state = _State.RESPONSE_LINE_REASON_PHRASE; | 430 _state = _State.RESPONSE_LINE_REASON_PHRASE; |
431 } else { | 431 } else { |
432 if (byte < 0x30 && 0x39 < byte) { | 432 if (byte < 0x30 && 0x39 < byte) { |
433 throw new HttpParserException("Invalid response status code"); | 433 throw new HttpException("Invalid response status code"); |
434 } else { | 434 } else { |
435 _method_or_status_code.add(byte); | 435 _method_or_status_code.add(byte); |
436 } | 436 } |
437 } | 437 } |
438 break; | 438 break; |
439 | 439 |
440 case _State.RESPONSE_LINE_REASON_PHRASE: | 440 case _State.RESPONSE_LINE_REASON_PHRASE: |
441 if (byte == _CharCode.CR) { | 441 if (byte == _CharCode.CR) { |
442 _state = _State.RESPONSE_LINE_ENDING; | 442 _state = _State.RESPONSE_LINE_ENDING; |
443 } else { | 443 } else { |
444 if (byte == _CharCode.CR || byte == _CharCode.LF) { | 444 if (byte == _CharCode.CR || byte == _CharCode.LF) { |
445 throw new HttpParserException("Invalid response reason phrase"); | 445 throw new HttpException("Invalid response reason phrase"); |
446 } | 446 } |
447 _uri_or_reason_phrase.add(byte); | 447 _uri_or_reason_phrase.add(byte); |
448 } | 448 } |
449 break; | 449 break; |
450 | 450 |
451 case _State.RESPONSE_LINE_ENDING: | 451 case _State.RESPONSE_LINE_ENDING: |
452 _expect(byte, _CharCode.LF); | 452 _expect(byte, _CharCode.LF); |
453 _messageType == _MessageType.RESPONSE; | 453 _messageType == _MessageType.RESPONSE; |
454 _statusCode = int.parse( | 454 _statusCode = int.parse( |
455 new String.fromCharCodes(_method_or_status_code)); | 455 new String.fromCharCodes(_method_or_status_code)); |
456 if (_statusCode < 100 || _statusCode > 599) { | 456 if (_statusCode < 100 || _statusCode > 599) { |
457 throw new HttpParserException("Invalid response status code"); | 457 throw new HttpException("Invalid response status code"); |
458 } else { | 458 } else { |
459 // Check whether this response will never have a body. | 459 // Check whether this response will never have a body. |
460 _noMessageBody = _statusCode <= 199 || _statusCode == 204 || | 460 _noMessageBody = _statusCode <= 199 || _statusCode == 204 || |
461 _statusCode == 304; | 461 _statusCode == 304; |
462 } | 462 } |
463 _state = _State.HEADER_START; | 463 _state = _State.HEADER_START; |
464 break; | 464 break; |
465 | 465 |
466 case _State.HEADER_START: | 466 case _State.HEADER_START: |
467 _headers = new _HttpHeaders(version); | 467 _headers = new _HttpHeaders(version); |
468 if (byte == _CharCode.CR) { | 468 if (byte == _CharCode.CR) { |
469 _state = _State.HEADER_ENDING; | 469 _state = _State.HEADER_ENDING; |
470 } else { | 470 } else { |
471 // Start of new header field. | 471 // Start of new header field. |
472 _headerField.add(_toLowerCase(byte)); | 472 _headerField.add(_toLowerCase(byte)); |
473 _state = _State.HEADER_FIELD; | 473 _state = _State.HEADER_FIELD; |
474 } | 474 } |
475 break; | 475 break; |
476 | 476 |
477 case _State.HEADER_FIELD: | 477 case _State.HEADER_FIELD: |
478 if (byte == _CharCode.COLON) { | 478 if (byte == _CharCode.COLON) { |
479 _state = _State.HEADER_VALUE_START; | 479 _state = _State.HEADER_VALUE_START; |
480 } else { | 480 } else { |
481 if (!_isTokenChar(byte)) { | 481 if (!_isTokenChar(byte)) { |
482 throw new HttpParserException("Invalid header field name"); | 482 throw new HttpException("Invalid header field name"); |
483 } | 483 } |
484 _headerField.add(_toLowerCase(byte)); | 484 _headerField.add(_toLowerCase(byte)); |
485 } | 485 } |
486 break; | 486 break; |
487 | 487 |
488 case _State.HEADER_VALUE_START: | 488 case _State.HEADER_VALUE_START: |
489 if (byte == _CharCode.CR) { | 489 if (byte == _CharCode.CR) { |
490 _state = _State.HEADER_VALUE_FOLDING_OR_ENDING; | 490 _state = _State.HEADER_VALUE_FOLDING_OR_ENDING; |
491 } else if (byte != _CharCode.SP && byte != _CharCode.HT) { | 491 } else if (byte != _CharCode.SP && byte != _CharCode.HT) { |
492 // Start of new header value. | 492 // Start of new header value. |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
721 void _onDone() { | 721 void _onDone() { |
722 // onDone cancles the subscription. | 722 // onDone cancles the subscription. |
723 _socketSubscription = null; | 723 _socketSubscription = null; |
724 if (_state == _State.CLOSED || _state == _State.FAILURE) return; | 724 if (_state == _State.CLOSED || _state == _State.FAILURE) return; |
725 | 725 |
726 if (_incoming != null) { | 726 if (_incoming != null) { |
727 if (_state != _State.UPGRADED && | 727 if (_state != _State.UPGRADED && |
728 !(_state == _State.START && !_requestParser) && | 728 !(_state == _State.START && !_requestParser) && |
729 !(_state == _State.BODY && !_chunked && _transferLength == -1)) { | 729 !(_state == _State.BODY && !_chunked && _transferLength == -1)) { |
730 _bodyController.addError( | 730 _bodyController.addError( |
731 new HttpParserException( | 731 new HttpException("Connection closed while receiving data")); |
732 "Connection closed while receiving data")); | |
733 } | 732 } |
734 _closeIncoming(true); | 733 _closeIncoming(true); |
735 _controller.close(); | 734 _controller.close(); |
736 return; | 735 return; |
737 } | 736 } |
738 // If the connection is idle the HTTP stream is closed. | 737 // If the connection is idle the HTTP stream is closed. |
739 if (_state == _State.START) { | 738 if (_state == _State.START) { |
740 if (!_requestParser) { | 739 if (!_requestParser) { |
741 error(new HttpParserException( | 740 error(new HttpException( |
742 "Connection closed before full header was received")); | 741 "Connection closed before full header was received")); |
743 } | 742 } |
744 _controller.close(); | 743 _controller.close(); |
745 return; | 744 return; |
746 } | 745 } |
747 | 746 |
748 if (_state == _State.UPGRADED) { | 747 if (_state == _State.UPGRADED) { |
749 _controller.close(); | 748 _controller.close(); |
750 return; | 749 return; |
751 } | 750 } |
752 | 751 |
753 if (_state < _State.FIRST_BODY_STATE) { | 752 if (_state < _State.FIRST_BODY_STATE) { |
754 _state = _State.FAILURE; | 753 _state = _State.FAILURE; |
755 // Report the error through the error callback if any. Otherwise | 754 // Report the error through the error callback if any. Otherwise |
756 // throw the error. | 755 // throw the error. |
757 error(new HttpParserException( | 756 error(new HttpException( |
758 "Connection closed before full header was received")); | 757 "Connection closed before full header was received")); |
759 _controller.close(); | 758 _controller.close(); |
760 return; | 759 return; |
761 } | 760 } |
762 | 761 |
763 if (!_chunked && _transferLength == -1) { | 762 if (!_chunked && _transferLength == -1) { |
764 _state = _State.CLOSED; | 763 _state = _State.CLOSED; |
765 } else { | 764 } else { |
766 _state = _State.FAILURE; | 765 _state = _State.FAILURE; |
767 // Report the error through the error callback if any. Otherwise | 766 // Report the error through the error callback if any. Otherwise |
768 // throw the error. | 767 // throw the error. |
769 error(new HttpParserException( | 768 error(new HttpException( |
770 "Connection closed before full body was received")); | 769 "Connection closed before full body was received")); |
771 } | 770 } |
772 _controller.close(); | 771 _controller.close(); |
773 } | 772 } |
774 | 773 |
775 void _onError(e) { | 774 void _onError(e) { |
776 _controller.addError(e); | 775 _controller.addError(e); |
777 } | 776 } |
778 | 777 |
779 String get version { | 778 String get version { |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
856 | 855 |
857 int _toLowerCase(int byte) { | 856 int _toLowerCase(int byte) { |
858 final int aCode = "A".codeUnitAt(0); | 857 final int aCode = "A".codeUnitAt(0); |
859 final int zCode = "Z".codeUnitAt(0); | 858 final int zCode = "Z".codeUnitAt(0); |
860 final int delta = "a".codeUnitAt(0) - aCode; | 859 final int delta = "a".codeUnitAt(0) - aCode; |
861 return (aCode <= byte && byte <= zCode) ? byte + delta : byte; | 860 return (aCode <= byte && byte <= zCode) ? byte + delta : byte; |
862 } | 861 } |
863 | 862 |
864 int _expect(int val1, int val2) { | 863 int _expect(int val1, int val2) { |
865 if (val1 != val2) { | 864 if (val1 != val2) { |
866 throw new HttpParserException("Failed to parse HTTP"); | 865 throw new HttpException("Failed to parse HTTP"); |
867 } | 866 } |
868 } | 867 } |
869 | 868 |
870 int _expectHexDigit(int byte) { | 869 int _expectHexDigit(int byte) { |
871 if (0x30 <= byte && byte <= 0x39) { | 870 if (0x30 <= byte && byte <= 0x39) { |
872 return byte - 0x30; // 0 - 9 | 871 return byte - 0x30; // 0 - 9 |
873 } else if (0x41 <= byte && byte <= 0x46) { | 872 } else if (0x41 <= byte && byte <= 0x46) { |
874 return byte - 0x41 + 10; // A - F | 873 return byte - 0x41 + 10; // A - F |
875 } else if (0x61 <= byte && byte <= 0x66) { | 874 } else if (0x61 <= byte && byte <= 0x66) { |
876 return byte - 0x61 + 10; // a - f | 875 return byte - 0x61 + 10; // a - f |
877 } else { | 876 } else { |
878 throw new HttpParserException("Failed to parse HTTP"); | 877 throw new HttpException("Failed to parse HTTP"); |
879 } | 878 } |
880 } | 879 } |
881 | 880 |
882 void _createIncoming(int transferLength) { | 881 void _createIncoming(int transferLength) { |
883 assert(_incoming == null); | 882 assert(_incoming == null); |
884 assert(_bodyController == null); | 883 assert(_bodyController == null); |
885 assert(!_bodyPaused); | 884 assert(!_bodyPaused); |
886 var incoming; | 885 var incoming; |
887 _bodyController = new StreamController<List<int>>( | 886 _bodyController = new StreamController<List<int>>( |
888 sync: true, | 887 sync: true, |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
981 _HttpHeaders _headers; | 980 _HttpHeaders _headers; |
982 | 981 |
983 // The current incoming connection. | 982 // The current incoming connection. |
984 _HttpIncoming _incoming; | 983 _HttpIncoming _incoming; |
985 StreamSubscription _socketSubscription; | 984 StreamSubscription _socketSubscription; |
986 bool _paused = true; | 985 bool _paused = true; |
987 bool _bodyPaused = false; | 986 bool _bodyPaused = false; |
988 StreamController<_HttpIncoming> _controller; | 987 StreamController<_HttpIncoming> _controller; |
989 StreamController<List<int>> _bodyController; | 988 StreamController<List<int>> _bodyController; |
990 } | 989 } |
991 | |
992 | |
993 class HttpParserException implements Exception { | |
994 const HttpParserException([String this.message = ""]); | |
995 String toString() => "HttpParserException: $message"; | |
996 final String message; | |
997 } | |
OLD | NEW |