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

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

Issue 173683002: Slightly speed up http-parser and http-header-writing. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Limit status code length. Created 6 years, 10 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 | « sdk/lib/io/http_impl.dart ('k') | no next file » | 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 4e3ede1d0be829e57ba573a1901bb873ef32cb85..2888138174a0c1b0fd665256d6202b2d1ea9987c 100644
--- a/sdk/lib/io/http_parser.dart
+++ b/sdk/lib/io/http_parser.dart
@@ -247,10 +247,11 @@ class _HttpParser extends Stream<_HttpIncoming> {
int _httpVersionIndex;
int _messageType;
int _statusCode = 0;
- List _method_or_status_code;
- List _uri_or_reason_phrase;
- List _headerField;
- List _headerValue;
+ int _statusCodeLength = 0;
+ final List<int> _method = [];
+ final List<int> _uri_or_reason_phrase = [];
+ final List<int> _headerField = [];
+ final List<int> _headerValue = [];
int _httpVersion;
int _transferLength = -1;
@@ -258,8 +259,7 @@ class _HttpParser extends Stream<_HttpIncoming> {
bool _connectionUpgrade;
bool _chunked;
- bool _noMessageBody;
- String _responseToMethod; // Indicates the method used for the request.
+ bool _noMessageBody = false;
int _remainingContent = -1;
_HttpHeaders _headers;
@@ -374,7 +374,7 @@ class _HttpParser extends Stream<_HttpIncoming> {
if (!_isTokenChar(byte)) {
throw new HttpException("Invalid request method");
}
- _method_or_status_code.add(byte);
+ _method.add(byte);
if (!_requestParser) {
throw new HttpException("Invalid response line");
}
@@ -399,12 +399,12 @@ class _HttpParser extends Stream<_HttpIncoming> {
} else {
// Did not parse HTTP version. Expect method instead.
for (int i = 0; i < _httpVersionIndex; i++) {
- _method_or_status_code.add(_Const.HTTP[i]);
+ _method.add(_Const.HTTP[i]);
}
if (byte == _CharCode.SP) {
_state = _State.REQUEST_LINE_URI;
} else {
- _method_or_status_code.add(byte);
+ _method.add(byte);
_httpVersion = _HttpVersion.UNDETERMINED;
if (!_requestParser) {
throw new HttpException("Invalid response line");
@@ -449,7 +449,7 @@ class _HttpParser extends Stream<_HttpIncoming> {
byte == _CharCode.LF) {
throw new HttpException("Invalid request method");
}
- _method_or_status_code.add(byte);
+ _method.add(byte);
}
break;
@@ -500,19 +500,17 @@ class _HttpParser extends Stream<_HttpIncoming> {
case _State.RESPONSE_LINE_STATUS_CODE:
if (byte == _CharCode.SP) {
- if (_method_or_status_code.length != 3) {
- throw new HttpException("Invalid response status code");
- }
_state = _State.RESPONSE_LINE_REASON_PHRASE;
} else if (byte == _CharCode.CR) {
// Some HTTP servers does not follow the spec. and send
// \r\n right after the status code.
_state = _State.RESPONSE_LINE_ENDING;
} else {
- if (byte < 0x30 && 0x39 < byte) {
+ _statusCodeLength++;
+ if ((byte < 0x30 && 0x39 < byte) || _statusCodeLength > 3) {
throw new HttpException("Invalid response status code");
} else {
- _method_or_status_code.add(byte);
+ _statusCode = _statusCode * 10 + byte - 0x30;
}
}
break;
@@ -531,14 +529,14 @@ class _HttpParser extends Stream<_HttpIncoming> {
case _State.RESPONSE_LINE_ENDING:
_expect(byte, _CharCode.LF);
_messageType == _MessageType.RESPONSE;
- _statusCode = int.parse(
- new String.fromCharCodes(_method_or_status_code));
if (_statusCode < 100 || _statusCode > 599) {
throw new HttpException("Invalid response status code");
} else {
// Check whether this response will never have a body.
- _noMessageBody = _statusCode <= 199 || _statusCode == 204 ||
- _statusCode == 304;
+ if (_statusCode <= 199 || _statusCode == 204 ||
+ _statusCode == 304) {
+ _noMessageBody = true;
+ }
}
_state = _State.HEADER_START;
break;
@@ -595,13 +593,14 @@ class _HttpParser extends Stream<_HttpIncoming> {
String headerField = new String.fromCharCodes(_headerField);
String headerValue = new String.fromCharCodes(_headerValue);
if (headerField == "transfer-encoding" &&
- headerValue.toLowerCase() == "chunked") {
+ _caseInsensitiveCompare("chunked".codeUnits, _headerValue)) {
_chunked = true;
}
if (headerField == "connection") {
List<String> tokens = _tokenizeFieldValue(headerValue);
for (int i = 0; i < tokens.length; i++) {
- if (tokens[i].toLowerCase() == "upgrade") {
+ if (_caseInsensitiveCompare("upgrade".codeUnits,
+ tokens[i].codeUnits)) {
_connectionUpgrade = true;
}
_headers._add(headerField, tokens[i]);
@@ -646,7 +645,7 @@ class _HttpParser extends Stream<_HttpIncoming> {
_createIncoming(_transferLength);
if (_requestParser) {
_incoming.method =
- new String.fromCharCodes(_method_or_status_code);
+ new String.fromCharCodes(_method);
_incoming.uri =
Uri.parse(
new String.fromCharCodes(_uri_or_reason_phrase));
@@ -655,7 +654,7 @@ class _HttpParser extends Stream<_HttpIncoming> {
_incoming.reasonPhrase =
new String.fromCharCodes(_uri_or_reason_phrase);
}
- _method_or_status_code.clear();
+ _method.clear();
_uri_or_reason_phrase.clear();
if (_connectionUpgrade) {
_incoming.upgraded = true;
@@ -666,8 +665,7 @@ class _HttpParser extends Stream<_HttpIncoming> {
return;
}
if (_transferLength == 0 ||
- (_messageType == _MessageType.RESPONSE &&
- (_noMessageBody || _responseToMethod == "HEAD"))) {
+ (_messageType == _MessageType.RESPONSE && _noMessageBody)) {
_reset();
var tmp = _incoming;
_closeIncoming();
@@ -866,7 +864,9 @@ class _HttpParser extends Stream<_HttpIncoming> {
bool get upgrade => _connectionUpgrade && _state == _State.UPGRADED;
bool get persistentConnection => _persistentConnection;
- void set responseToMethod(String method) { _responseToMethod = method; }
+ void set isHead(bool value) {
+ if (value) _noMessageBody = true;
+ }
_HttpDetachedIncoming detachIncoming() {
// Simulate detached by marking as upgraded.
@@ -887,12 +887,13 @@ class _HttpParser extends Stream<_HttpIncoming> {
if (_state == _State.UPGRADED) return;
_state = _State.START;
_messageType = _MessageType.UNDETERMINED;
- _headerField = new List();
- _headerValue = new List();
- _method_or_status_code = new List();
- _uri_or_reason_phrase = new List();
+ _headerField.clear();
+ _headerValue.clear();
+ _method.clear();
+ _uri_or_reason_phrase.clear();
_statusCode = 0;
+ _statusCodeLength = 0;
_httpVersion = _HttpVersion.UNDETERMINED;
_transferLength = -1;
@@ -901,7 +902,6 @@ class _HttpParser extends Stream<_HttpIncoming> {
_chunked = false;
_noMessageBody = false;
- _responseToMethod = null;
_remainingContent = -1;
_headers = null;
@@ -940,6 +940,15 @@ class _HttpParser extends Stream<_HttpIncoming> {
return (aCode <= byte && byte <= zCode) ? byte + delta : byte;
}
+ // expected should already be lowercase.
+ bool _caseInsensitiveCompare(List<int> expected, List<int> value) {
+ if (expected.length != value.length) return false;
+ for (int i = 0; i < expected.length; i++) {
+ if (expected[i] != _toLowerCase(value[i])) return false;
+ }
+ return true;
+ }
+
int _expect(int val1, int val2) {
if (val1 != val2) {
throw new HttpException("Failed to parse HTTP");
« no previous file with comments | « sdk/lib/io/http_impl.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698