Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(303)

Unified Diff: runtime/bin/http_parser.dart

Issue 9704009: Support parsing HTTP responses where the body length is not known (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | tests/standalone/src/io/HttpParserTest.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/bin/http_parser.dart
diff --git a/runtime/bin/http_parser.dart b/runtime/bin/http_parser.dart
index 9e59ddec323ff0dfc3d61c1839c1e86f0a984af8..fc873278fc72cf797ee168d14ee68370ed27f52a 100644
--- a/runtime/bin/http_parser.dart
+++ b/runtime/bin/http_parser.dart
@@ -64,13 +64,9 @@ class _State {
* Currently only HTTP requests with Content-Length header are supported.
*/
class _HttpParser {
- _HttpParser()
- : _state = _State.START,
- _failure = false,
- _headerField = new StringBuffer(),
- _headerValue = new StringBuffer(),
- _method_or_status_code = new StringBuffer(),
- _uri_or_reason_phrase = new StringBuffer();
+ _HttpParser() {
+ _reset();
+ }
// From RFC 2616.
// generic-message = start-line
@@ -88,10 +84,6 @@ class _HttpParser {
int byte = buffer[index];
switch (_state) {
case _State.START:
- _contentLength = 0;
- _keepAlive = false;
- _chunked = false;
-
if (byte == _Const.HTTP11[0]) {
// Start parsing HTTP method.
_httpVersionIndex = 1;
@@ -164,6 +156,7 @@ class _HttpParser {
_state = _State.RESPONSE_LINE_REASON_PHRASE;
} else {
if (byte < 0x30 && 0x39 < byte) {
+ if (error != null) error("Failed to parse HTTP");
_failure = true;
} else {
_method_or_status_code.addCharCode(byte);
@@ -279,7 +272,9 @@ class _HttpParser {
_remainingContent = _contentLength;
_state = _State.BODY;
} else {
- // TODO(sgjesse): Error handling.
+ // Neither chunked nor content length. End of body
+ // indicated by close.
+ _state = _State.BODY;
}
break;
@@ -319,14 +314,14 @@ class _HttpParser {
case _State.CHUNKED_BODY_DONE_LF:
_expect(byte, _CharCode.LF);
if (dataEnd != null) dataEnd();
- _state = _State.START;
+ _reset();
break;
case _State.BODY:
// The body is not handled one byte at the time but in blocks.
int dataAvailable = lastIndex - index;
ByteArray data;
- if (dataAvailable <= _remainingContent) {
+ if (_remainingContent == null || dataAvailable <= _remainingContent) {
data = new ByteArray(dataAvailable);
data.setRange(0, dataAvailable, buffer, index);
} else {
@@ -335,12 +330,14 @@ class _HttpParser {
}
if (dataReceived != null) dataReceived(data);
- _remainingContent -= data.length;
+ if (_remainingContent != null) {
+ _remainingContent -= data.length;
+ }
index += data.length;
- if (_remainingContent == 0) {
+ if (_remainingContent != null && _remainingContent == 0) {
Anders Johnsen 2012/03/15 11:24:04 == 0 should be sufficient.
Søren Gjesse 2012/03/19 11:31:48 Done.
if (!_chunked) {
if (dataEnd != null) dataEnd();
- _state = _State.START;
+ _reset();
} else {
_state = _State.CHUNK_SIZE_STARTING_CR;
}
@@ -363,9 +360,33 @@ class _HttpParser {
return index - offset;
}
+ int connectionClosed() {
+ if (!_chunked && _contentLength == -1) {
+ if (dataEnd != null) dataEnd();
+ } else {
+ if (error != null) {
+ error("Connection closed before full body was received");
+ }
+ }
+ }
+
int get contentLength() => _contentLength;
bool get keepAlive() => _keepAlive;
+ _reset() {
+ _state = _State.START;
+ _failure = false;
+ _headerField = new StringBuffer();
+ _headerValue = new StringBuffer();
+ _method_or_status_code = new StringBuffer();
+ _uri_or_reason_phrase = new StringBuffer();
+
+ _contentLength = -1;
+ _keepAlive = false;
+ _chunked = false;
+ _remainingContent = null;
+ }
+
int _toLowerCase(int byte) {
final int aCode = "A".charCodeAt(0);
final int zCode = "Z".charCodeAt(0);
@@ -375,6 +396,7 @@ class _HttpParser {
int _expect(int val1, int val2) {
if (val1 != val2) {
+ if (error != null) error("Failed to parse HTTP");
_failure = true;
}
}
@@ -413,4 +435,5 @@ class _HttpParser {
Function headersComplete;
Function dataReceived;
Function dataEnd;
+ Function error;
}
« no previous file with comments | « no previous file | tests/standalone/src/io/HttpParserTest.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698