| 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"); | 
|  |