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

Unified Diff: sdk/lib/io/http_parser.dart

Issue 11410003: Refactoring of the HTTP library (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Addressed review comments Created 8 years, 1 month 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 | « sdk/lib/io/http_impl.dart ('k') | tests/standalone/io/http_connection_close_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/io/http_parser.dart
diff --git a/sdk/lib/io/http_parser.dart b/sdk/lib/io/http_parser.dart
index 61e0a64a588e34fc9111455ccda531969c1bc8bb..45a2d4f0a43296c949e0922c9af2775b1f9a33b3 100644
--- a/sdk/lib/io/http_parser.dart
+++ b/sdk/lib/io/http_parser.dart
@@ -103,6 +103,7 @@ class _MessageType {
* [:headersComplete:]
* [:dataReceived:]
* [:dataEnd:]
+ * [:closed:]
* [:error:]
*
* If an HTTP parser error occours it is possible to get an exception
@@ -124,7 +125,12 @@ class _MessageType {
* upgraded to.
*/
class _HttpParser {
- _HttpParser() {
+ _HttpParser.requestParser() {
+ _requestParser = true;
+ _reset();
+ }
+ _HttpParser.responseParser() {
+ _requestParser = false;
_reset();
}
@@ -165,6 +171,9 @@ class _HttpParser {
throw new HttpParserException("Invalid request method");
}
_method_or_status_code.addCharCode(byte);
+ if (!_requestParser) {
+ throw new HttpParserException("Invalid response line");
+ }
_state = _State.REQUEST_LINE_METHOD;
}
break;
@@ -179,6 +188,9 @@ class _HttpParser {
// HTTP/ parsed. As method is a token this cannot be a
// method anymore.
_httpVersionIndex++;
+ if (_requestParser) {
+ throw new HttpParserException("Invalid request line");
+ }
_state = _State.RESPONSE_HTTP_VERSION;
} else {
// Did not parse HTTP version. Expect method instead.
@@ -190,6 +202,9 @@ class _HttpParser {
} else {
_method_or_status_code.addCharCode(byte);
_httpVersion = _HttpVersion.UNDETERMINED;
+ if (!_requestParser) {
+ throw new HttpParserException("Invalid response line");
+ }
_state = _State.REQUEST_LINE_METHOD;
}
}
@@ -274,11 +289,9 @@ class _HttpParser {
case _State.REQUEST_LINE_ENDING:
_expect(byte, _CharCode.LF);
_messageType = _MessageType.REQUEST;
- if (requestStart != null) {
- requestStart(_method_or_status_code.toString(),
- _uri_or_reason_phrase.toString(),
- version);
- }
+ requestStart(_method_or_status_code.toString(),
+ _uri_or_reason_phrase.toString(),
+ version);
_method_or_status_code.clear();
_uri_or_reason_phrase.clear();
_state = _State.HEADER_START;
@@ -324,11 +337,9 @@ class _HttpParser {
_noMessageBody =
statusCode <= 199 || statusCode == 204 || statusCode == 304;
}
- if (responseStart != null) {
- responseStart(statusCode,
- _uri_or_reason_phrase.toString(),
- version);
- }
+ responseStart(statusCode,
+ _uri_or_reason_phrase.toString(),
+ version);
_method_or_status_code.clear();
_uri_or_reason_phrase.clear();
_state = _State.HEADER_START;
@@ -400,9 +411,7 @@ class _HttpParser {
} else if (token == "upgrade") {
_connectionUpgrade = true;
}
- if (headerReceived != null) {
- headerReceived(headerField, token);
- }
+ headerReceived(headerField, token);
}
reportHeader = false;
} else if (headerField == "transfer-encoding" &&
@@ -412,7 +421,7 @@ class _HttpParser {
_chunked = true;
_contentLength = -1;
}
- if (reportHeader && headerReceived != null) {
+ if (reportHeader) {
headerReceived(headerField, headerValue);
}
_headerField.clear();
@@ -440,9 +449,9 @@ class _HttpParser {
}
if (_connectionUpgrade) {
_state = _State.UPGRADED;
- if (headersComplete != null) headersComplete();
+ headersComplete();
} else {
- if (headersComplete != null) headersComplete();
+ headersComplete();
if (_chunked) {
_state = _State.CHUNK_SIZE;
_remainingContent = 0;
@@ -525,7 +534,7 @@ class _HttpParser {
data.setRange(0, _remainingContent, _buffer, _index);
}
- if (dataReceived != null) dataReceived(data);
+ dataReceived(data);
if (_remainingContent != null) {
_remainingContent -= data.length;
}
@@ -552,14 +561,8 @@ class _HttpParser {
}
}
} catch (e) {
- // Report the error through the error callback if any. Otherwise
- // throw the error.
- if (error != null) {
- error(e);
- _state = _State.FAILURE;
- } else {
- throw e;
- }
+ _state = _State.FAILURE;
+ error(e);
}
// If all data is parsed or not needed due to failure there is no
@@ -567,45 +570,60 @@ class _HttpParser {
if (_state != _State.UPGRADED) _releaseBuffer();
}
- void writeList(List<int> buffer, int offset, int count) {
+ void streamData(List<int> buffer) {
assert(_buffer == null);
_buffer = buffer;
- _index = offset;
- _lastIndex = offset + count;
+ _index = 0;
+ _lastIndex = buffer.length;
_parse();
}
- void connectionClosed() {
+ void streamDone() {
+ // If the connection is idle the HTTP stream is closed.
+ if (_state == _State.START) {
+ if (_requestParser) {
+ closed();
+ } else {
+ error(
+ new HttpParserException(
+ "Connection closed before full header was received"));
+ }
+ return;
+ }
+
if (_state < _State.FIRST_BODY_STATE) {
_state = _State.FAILURE;
// Report the error through the error callback if any. Otherwise
// throw the error.
- var e = new HttpParserException(
- "Connection closed before full header was received");
- if (error != null) {
- error(e);
- return;
- }
- throw e;
+ error(
+ new HttpParserException(
+ "Connection closed before full header was received"));
+ return;
}
if (!_chunked && _contentLength == -1) {
- if (_state != _State.START) {
- if (dataEnd != null) dataEnd(true);
- }
+ dataEnd(true);
_state = _State.CLOSED;
+ closed();
} else {
_state = _State.FAILURE;
// Report the error through the error callback if any. Otherwise
// throw the error.
- var e = new HttpParserException(
- "Connection closed before full body was received");
- if (error != null) {
- error(e);
- return;
- }
- throw e;
+ error(
+ new HttpParserException(
+ "Connection closed before full body was received"));
+ }
+ }
+
+ void streamError(e) {
+ // Don't report errors when HTTP parser is in idle state. Clients
+ // can close the connection and cause a connection reset by peer
+ // error which is OK.
+ if (_state == _State.START) {
+ closed();
+ return;
}
+ error(e);
}
String get version {
@@ -625,8 +643,6 @@ class _HttpParser {
void set responseToMethod(String method) { _responseToMethod = method; }
- bool get isIdle => _state == _State.START;
-
List<int> readUnparsedData() {
if (_buffer == null) return [];
if (_index == _lastIndex) return [];
@@ -636,9 +652,7 @@ class _HttpParser {
}
void _bodyEnd() {
- if (dataEnd != null) {
- dataEnd(_messageType == _MessageType.RESPONSE && !_persistentConnection);
- }
+ dataEnd(_messageType == _MessageType.RESPONSE && !_persistentConnection);
}
_reset() {
@@ -717,6 +731,7 @@ class _HttpParser {
int _index;
int _lastIndex;
+ bool _requestParser;
int _state;
int _httpVersionIndex;
int _messageType;
@@ -743,6 +758,7 @@ class _HttpParser {
Function dataReceived;
Function dataEnd;
Function error;
+ Function closed;
}
« no previous file with comments | « sdk/lib/io/http_impl.dart ('k') | tests/standalone/io/http_connection_close_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698