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

Side by Side Diff: runtime/bin/http_parser.dart

Issue 10008083: Add HTTP/1.0 support and simplify persistent connections handling (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 8 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 // Global constants. 5 // Global constants.
6 class _Const { 6 class _Const {
7 // Bytes for "HTTP".
8 static final HTTP = const [72, 84, 84, 80];
9 // Bytes for "HTTP/1.".
10 static final HTTP1DOT = const [72, 84, 84, 80, 47, 49, 46];
7 // Bytes for "HTTP/1.0". 11 // Bytes for "HTTP/1.0".
8 static final HTTP10 = const [72, 84, 84, 80, 47, 49, 46, 48]; 12 static final HTTP10 = const [72, 84, 84, 80, 47, 49, 46, 48];
9 // Bytes for "HTTP/1.1". 13 // Bytes for "HTTP/1.1".
10 static final HTTP11 = const [72, 84, 84, 80, 47, 49, 46, 49]; 14 static final HTTP11 = const [72, 84, 84, 80, 47, 49, 46, 49];
11 15
12 static final END_CHUNKED = const [0x30, 13, 10, 13, 10]; 16 static final END_CHUNKED = const [0x30, 13, 10, 13, 10];
13 17
14 // Bytes for '()<>@,;:\\"/[]?={} \t'. 18 // Bytes for '()<>@,;:\\"/[]?={} \t'.
15 static final SEPARATORS = const [40, 41, 60, 62, 64, 44, 59, 58, 92, 34, 47, 19 static final SEPARATORS = const [40, 41, 60, 62, 64, 44, 59, 58, 92, 34, 47,
16 91, 93, 63, 61, 123, 125, 32, 9]; 20 91, 93, 63, 61, 123, 125, 32, 9];
17 21
18 // Bytes for '()<>@,;:\\"/[]?={} \t\r\n'. 22 // Bytes for '()<>@,;:\\"/[]?={} \t\r\n'.
19 static final SEPARATORS_AND_CR_LF = const [40, 41, 60, 62, 64, 44, 59, 58, 92, 23 static final SEPARATORS_AND_CR_LF = const [40, 41, 60, 62, 64, 44, 59, 58, 92,
20 34, 47, 91, 93, 63, 61, 123, 125, 24 34, 47, 91, 93, 63, 61, 123, 125,
21 32, 9, 13, 10]; 25 32, 9, 13, 10];
22 } 26 }
23 27
24 28
25 // Frequently used character codes. 29 // Frequently used character codes.
26 class _CharCode { 30 class _CharCode {
27 static final int HT = 9; 31 static final int HT = 9;
28 static final int LF = 10; 32 static final int LF = 10;
29 static final int CR = 13; 33 static final int CR = 13;
30 static final int SP = 32; 34 static final int SP = 32;
35 static final int SLASH = 47;
36 static final int ZERO = 48;
37 static final int ONE = 49;
31 static final int COLON = 58; 38 static final int COLON = 58;
32 static final int SEMI_COLON = 59; 39 static final int SEMI_COLON = 59;
33 } 40 }
34 41
35 42
36 // States of the HTTP parser state machine. 43 // States of the HTTP parser state machine.
37 class _State { 44 class _State {
38 static final int START = 0; 45 static final int START = 0;
39 static final int METHOD_OR_HTTP_VERSION = 1; 46 static final int METHOD_OR_RESPONSE_HTTP_VERSION = 1;
40 static final int REQUEST_LINE_METHOD = 2; 47 static final int RESPONSE_HTTP_VERSION = 2;
41 static final int REQUEST_LINE_URI = 3; 48 static final int REQUEST_LINE_METHOD = 3;
42 static final int REQUEST_LINE_HTTP_VERSION = 4; 49 static final int REQUEST_LINE_URI = 4;
43 static final int REQUEST_LINE_ENDING = 5; 50 static final int REQUEST_LINE_HTTP_VERSION = 5;
44 static final int RESPONSE_LINE_STATUS_CODE = 6; 51 static final int REQUEST_LINE_ENDING = 6;
45 static final int RESPONSE_LINE_REASON_PHRASE = 7; 52 static final int RESPONSE_LINE_STATUS_CODE = 7;
46 static final int RESPONSE_LINE_ENDING = 8; 53 static final int RESPONSE_LINE_REASON_PHRASE = 8;
47 static final int HEADER_START = 9; 54 static final int RESPONSE_LINE_ENDING = 9;
48 static final int HEADER_FIELD = 10; 55 static final int HEADER_START = 10;
49 static final int HEADER_VALUE_START = 11; 56 static final int HEADER_FIELD = 11;
50 static final int HEADER_VALUE = 12; 57 static final int HEADER_VALUE_START = 12;
51 static final int HEADER_VALUE_FOLDING_OR_ENDING = 13; 58 static final int HEADER_VALUE = 13;
52 static final int HEADER_VALUE_FOLD_OR_END = 14; 59 static final int HEADER_VALUE_FOLDING_OR_ENDING = 14;
53 static final int HEADER_ENDING = 15; 60 static final int HEADER_VALUE_FOLD_OR_END = 15;
61 static final int HEADER_ENDING = 16;
54 62
55 static final int CHUNK_SIZE_STARTING_CR = 16; 63 static final int CHUNK_SIZE_STARTING_CR = 17;
56 static final int CHUNK_SIZE_STARTING_LF = 17; 64 static final int CHUNK_SIZE_STARTING_LF = 18;
57 static final int CHUNK_SIZE = 18; 65 static final int CHUNK_SIZE = 19;
58 static final int CHUNK_SIZE_EXTENSION = 19; 66 static final int CHUNK_SIZE_EXTENSION = 20;
59 static final int CHUNK_SIZE_ENDING = 20; 67 static final int CHUNK_SIZE_ENDING = 21;
60 static final int CHUNKED_BODY_DONE_CR = 21; 68 static final int CHUNKED_BODY_DONE_CR = 22;
61 static final int CHUNKED_BODY_DONE_LF = 22; 69 static final int CHUNKED_BODY_DONE_LF = 23;
62 static final int BODY = 23; 70 static final int BODY = 24;
63 static final int CLOSED = 24; 71 static final int CLOSED = 25;
64 static final int UPGRADED = 25; 72 static final int UPGRADED = 26;
65 static final int FAILURE = 26; 73 static final int FAILURE = 27;
66 74
67 static final int FIRST_BODY_STATE = CHUNK_SIZE_STARTING_CR; 75 static final int FIRST_BODY_STATE = CHUNK_SIZE_STARTING_CR;
68 } 76 }
69 77
78 // HTTP version of the request or response being parsed.
79 class _HttpVersion {
80 static final int UNDETERMINED = 0;
81 static final int HTTP10 = 1;
82 static final int HTTP11 = 2;
83 }
70 84
71 // States of the HTTP parser state machine. 85 // States of the HTTP parser state machine.
72 class _MessageType { 86 class _MessageType {
73 static final int UNDETERMINED = 0; 87 static final int UNDETERMINED = 0;
74 static final int REQUEST = 1; 88 static final int REQUEST = 1;
75 static final int RESPONSE = 0; 89 static final int RESPONSE = 0;
76 } 90 }
77 91
78 92
79 /** 93 /**
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 if (_state == _State.CLOSED) { 141 if (_state == _State.CLOSED) {
128 throw new HttpParserException("Data on closed connection"); 142 throw new HttpParserException("Data on closed connection");
129 } 143 }
130 if (_state == _State.UPGRADED) { 144 if (_state == _State.UPGRADED) {
131 throw new HttpParserException("Data on upgraded connection"); 145 throw new HttpParserException("Data on upgraded connection");
132 } 146 }
133 while ((index < lastIndex) && _state != _State.FAILURE && _state != _State .UPGRADED) { 147 while ((index < lastIndex) && _state != _State.FAILURE && _state != _State .UPGRADED) {
134 int byte = buffer[index]; 148 int byte = buffer[index];
135 switch (_state) { 149 switch (_state) {
136 case _State.START: 150 case _State.START:
137 if (byte == _Const.HTTP11[0]) { 151 if (byte == _Const.HTTP[0]) {
138 // Start parsing HTTP method. 152 // Start parsing method or HTTP version.
139 _httpVersionIndex = 1; 153 _httpVersionIndex = 1;
140 _state = _State.METHOD_OR_HTTP_VERSION; 154 _state = _State.METHOD_OR_RESPONSE_HTTP_VERSION;
141 } else { 155 } else {
142 // Start parsing method. 156 // Start parsing method.
143 if (_Const.SEPARATORS_AND_CR_LF.indexOf(byte) != -1) { 157 if (!_isTokenChar(byte)) {
144 throw new HttpParserException("Invalid request method"); 158 throw new HttpParserException("Invalid request method");
145 } 159 }
146 _method_or_status_code.addCharCode(byte); 160 _method_or_status_code.addCharCode(byte);
147 _state = _State.REQUEST_LINE_METHOD; 161 _state = _State.REQUEST_LINE_METHOD;
148 } 162 }
149 break; 163 break;
150 164
151 case _State.METHOD_OR_HTTP_VERSION: 165 case _State.METHOD_OR_RESPONSE_HTTP_VERSION:
152 if (_httpVersionIndex < _Const.HTTP11.length && 166 if (_httpVersionIndex < _Const.HTTP.length &&
153 byte == _Const.HTTP11[_httpVersionIndex]) { 167 byte == _Const.HTTP[_httpVersionIndex]) {
154 // Continue parsing HTTP version. 168 // Continue parsing HTTP version.
155 _httpVersionIndex++; 169 _httpVersionIndex++;
156 } else if (_httpVersionIndex == _Const.HTTP11.length && 170 } else if (_httpVersionIndex == _Const.HTTP.length &&
157 byte == _CharCode.SP) { 171 byte == _CharCode.SLASH) {
172 // HTTP/ parsed. As method is a token this cannot be a method anym ore.
173 _httpVersionIndex++;
174 _state = _State.RESPONSE_HTTP_VERSION;
175 } else {
176 // Did not parse HTTP version. Expect method instead.
177 for (int i = 0; i < _httpVersionIndex; i++) {
178 _method_or_status_code.addCharCode(_Const.HTTP[i]);
179 }
180 //_method_or_status_code.addCharCode(byte);
181 _httpVersion = _HttpVersion.UNDETERMINED;
182 _state = _State.REQUEST_LINE_URI;
183 }
184 break;
185
186 case _State.RESPONSE_HTTP_VERSION:
187 if (_httpVersionIndex < _Const.HTTP1DOT.length) {
188 // Continue parsing HTTP version.
189 _expect(byte, _Const.HTTP1DOT[_httpVersionIndex]);
190 _httpVersionIndex++;
191 } else if (_httpVersionIndex == _Const.HTTP1DOT.length &&
192 byte == _CharCode.ONE) {
193 // HTTP/1.1 parsed.
194 _httpVersion = _HttpVersion.HTTP11;
195 _persistentConnection = true;
196 _httpVersionIndex++;
197 } else if (_httpVersionIndex == _Const.HTTP1DOT.length &&
198 byte == _CharCode.ZERO) {
199 // HTTP/1.0 parsed.
200 _httpVersion = _HttpVersion.HTTP10;
201 _persistentConnection = false;
202 _httpVersionIndex++;
203 } else if (_httpVersionIndex == _Const.HTTP1DOT.length + 1) {
204 _expect(byte, _CharCode.SP);
158 // HTTP version parsed. 205 // HTTP version parsed.
159 _state = _State.RESPONSE_LINE_STATUS_CODE; 206 _state = _State.RESPONSE_LINE_STATUS_CODE;
160 } else { 207 } else {
161 // Did not parse HTTP version. Expect method instead. 208 throw new HttpParserException("Invalid response line");
162 for (int i = 0; i < _httpVersionIndex; i++) {
163 _method_or_status_code.addCharCode(_Const.HTTP11[i]);
164 }
165 _state = _State.REQUEST_LINE_URI;
166 } 209 }
167 break; 210 break;
168 211
169 case _State.REQUEST_LINE_METHOD: 212 case _State.REQUEST_LINE_METHOD:
170 if (byte == _CharCode.SP) { 213 if (byte == _CharCode.SP) {
171 _state = _State.REQUEST_LINE_URI; 214 _state = _State.REQUEST_LINE_URI;
172 } else { 215 } else {
173 if (_Const.SEPARATORS_AND_CR_LF.indexOf(byte) != -1) { 216 if (_Const.SEPARATORS_AND_CR_LF.indexOf(byte) != -1) {
174 throw new HttpParserException("Invalid request method"); 217 throw new HttpParserException("Invalid request method");
175 } 218 }
176 _method_or_status_code.addCharCode(byte); 219 _method_or_status_code.addCharCode(byte);
177 } 220 }
178 break; 221 break;
179 222
180 case _State.REQUEST_LINE_URI: 223 case _State.REQUEST_LINE_URI:
181 if (byte == _CharCode.SP) { 224 if (byte == _CharCode.SP) {
182 _state = _State.REQUEST_LINE_HTTP_VERSION; 225 _state = _State.REQUEST_LINE_HTTP_VERSION;
183 _httpVersionIndex = 0; 226 _httpVersionIndex = 0;
184 } else { 227 } else {
185 if (byte == _CharCode.CR || byte == _CharCode.LF) { 228 if (byte == _CharCode.CR || byte == _CharCode.LF) {
186 throw new HttpParserException("Invalid request URI"); 229 throw new HttpParserException("Invalid request URI");
187 } 230 }
188 _uri_or_reason_phrase.addCharCode(byte); 231 _uri_or_reason_phrase.addCharCode(byte);
189 } 232 }
190 break; 233 break;
191 234
192 case _State.REQUEST_LINE_HTTP_VERSION: 235 case _State.REQUEST_LINE_HTTP_VERSION:
193 if (_httpVersionIndex < _Const.HTTP11.length) { 236 if (_httpVersionIndex < _Const.HTTP1DOT.length) {
194 _expect(byte, _Const.HTTP11[_httpVersionIndex]); 237 _expect(byte, _Const.HTTP11[_httpVersionIndex]);
195 _httpVersionIndex++; 238 _httpVersionIndex++;
239 } else if (_httpVersionIndex == _Const.HTTP1DOT.length) {
240 if (byte == _CharCode.ONE) {
241 // HTTP/1.1 parsed.
242 _httpVersion = _HttpVersion.HTTP11;
243 _persistentConnection = true;
244 _httpVersionIndex++;
245 } else if (byte == _CharCode.ZERO) {
246 // HTTP/1.0 parsed.
247 _httpVersion = _HttpVersion.HTTP10;
248 _persistentConnection = false;
249 _httpVersionIndex++;
250 } else {
251 throw new HttpParserException("Invalid response line");
252 }
196 } else { 253 } else {
197 _expect(byte, _CharCode.CR); 254 _expect(byte, _CharCode.CR);
198 _state = _State.REQUEST_LINE_ENDING; 255 _state = _State.REQUEST_LINE_ENDING;
199 } 256 }
200 break; 257 break;
201 258
202 case _State.REQUEST_LINE_ENDING: 259 case _State.REQUEST_LINE_ENDING:
203 _expect(byte, _CharCode.LF); 260 _expect(byte, _CharCode.LF);
204 _messageType = _MessageType.REQUEST; 261 _messageType = _MessageType.REQUEST;
205 if (requestStart != null) { 262 if (requestStart != null) {
206 requestStart(_method_or_status_code.toString(), 263 requestStart(_method_or_status_code.toString(),
207 _uri_or_reason_phrase.toString()); 264 _uri_or_reason_phrase.toString(),
265 version);
208 } 266 }
209 _method_or_status_code.clear(); 267 _method_or_status_code.clear();
210 _uri_or_reason_phrase.clear(); 268 _uri_or_reason_phrase.clear();
211 _state = _State.HEADER_START; 269 _state = _State.HEADER_START;
212 break; 270 break;
213 271
214 case _State.RESPONSE_LINE_STATUS_CODE: 272 case _State.RESPONSE_LINE_STATUS_CODE:
215 if (byte == _CharCode.SP) { 273 if (byte == _CharCode.SP) {
216 if (_method_or_status_code.length != 3) { 274 if (_method_or_status_code.length != 3) {
217 throw new HttpParserException("Invalid response status code"); 275 throw new HttpParserException("Invalid response status code");
(...skipping 27 matching lines...) Expand all
245 _messageType == _MessageType.RESPONSE; 303 _messageType == _MessageType.RESPONSE;
246 int statusCode = Math.parseInt(_method_or_status_code.toString()); 304 int statusCode = Math.parseInt(_method_or_status_code.toString());
247 if (statusCode < 100 || statusCode > 599) { 305 if (statusCode < 100 || statusCode > 599) {
248 throw new HttpParserException("Invalid response status code"); 306 throw new HttpParserException("Invalid response status code");
249 } else { 307 } else {
250 // Check whether this response will never have a body. 308 // Check whether this response will never have a body.
251 _noMessageBody = 309 _noMessageBody =
252 statusCode <= 199 || statusCode == 204 || statusCode == 304; 310 statusCode <= 199 || statusCode == 204 || statusCode == 304;
253 } 311 }
254 if (responseStart != null) { 312 if (responseStart != null) {
255 responseStart(statusCode, _uri_or_reason_phrase.toString()); 313 responseStart(statusCode, _uri_or_reason_phrase.toString(), versio n);
256 } 314 }
257 _method_or_status_code.clear(); 315 _method_or_status_code.clear();
258 _uri_or_reason_phrase.clear(); 316 _uri_or_reason_phrase.clear();
259 _state = _State.HEADER_START; 317 _state = _State.HEADER_START;
260 break; 318 break;
261 319
262 case _State.HEADER_START: 320 case _State.HEADER_START:
263 if (byte == _CharCode.CR) { 321 if (byte == _CharCode.CR) {
264 _state = _State.HEADER_ENDING; 322 _state = _State.HEADER_ENDING;
265 } else { 323 } else {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 String headerValue =_headerValue.toString(); 369 String headerValue =_headerValue.toString();
312 // Ignore the Content-Length header if Transfer-Encoding 370 // Ignore the Content-Length header if Transfer-Encoding
313 // is chunked (RFC 2616 section 4.4) 371 // is chunked (RFC 2616 section 4.4)
314 if (headerField == "content-length" && !_chunked) { 372 if (headerField == "content-length" && !_chunked) {
315 _contentLength = Math.parseInt(headerValue); 373 _contentLength = Math.parseInt(headerValue);
316 } else if (headerField == "connection") { 374 } else if (headerField == "connection") {
317 List<String> tokens = _tokenizeFieldValue(headerValue); 375 List<String> tokens = _tokenizeFieldValue(headerValue);
318 for (int i = 0; i < tokens.length; i++) { 376 for (int i = 0; i < tokens.length; i++) {
319 String token = tokens[i].toLowerCase(); 377 String token = tokens[i].toLowerCase();
320 if (token == "keep-alive") { 378 if (token == "keep-alive") {
321 _keepAlive = true; 379 _persistentConnection = true;
322 } else if (token == "close") { 380 } else if (token == "close") {
323 _connectionClose = true; 381 _persistentConnection = false;
324 } else if (token == "upgrade") { 382 } else if (token == "upgrade") {
325 _connectionUpgrade = true; 383 _connectionUpgrade = true;
326 } 384 }
327 } 385 }
328 } else if (headerField == "transfer-encoding" && 386 } else if (headerField == "transfer-encoding" &&
Anders Johnsen 2012/04/13 09:02:38 toLowerCase here as well. Actually, maybe we shoul
Søren Gjesse 2012/04/13 10:58:31 This is not required. When the header name is pars
329 headerValue == "chunked") { 387 headerValue.toLowerCase() == "chunked") {
330 _chunked = true; 388 _chunked = true;
331 _contentLength = -1; 389 _contentLength = -1;
332 } 390 }
333 if (headerReceived != null) { 391 if (headerReceived != null) {
334 headerReceived(headerField, headerValue); 392 headerReceived(headerField, headerValue);
335 } 393 }
336 _headerField.clear(); 394 _headerField.clear();
337 _headerValue.clear(); 395 _headerValue.clear();
338 396
339 if (byte == _CharCode.CR) { 397 if (byte == _CharCode.CR) {
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
509 var e = new HttpParserException( 567 var e = new HttpParserException(
510 "Connection closed before full body was received"); 568 "Connection closed before full body was received");
511 if (error != null) { 569 if (error != null) {
512 error(e); 570 error(e);
513 return; 571 return;
514 } 572 }
515 throw e; 573 throw e;
516 } 574 }
517 } 575 }
518 576
577 String get version() {
578 switch (_httpVersion) {
579 case _HttpVersion.HTTP10:
580 return "1.0";
581 break;
582 case _HttpVersion.HTTP11:
583 return "1.1";
584 break;
585 }
586 return null;
587 }
588
519 int get messageType() => _messageType; 589 int get messageType() => _messageType;
520 int get contentLength() => _contentLength; 590 int get contentLength() => _contentLength;
521 bool get keepAlive() => _keepAlive;
522 bool get upgrade() => _connectionUpgrade && _state == _State.UPGRADED; 591 bool get upgrade() => _connectionUpgrade && _state == _State.UPGRADED;
592 bool get persistentConnection() => _persistentConnection;
523 593
524 void set responseToMethod(String method) => _responseToMethod = method; 594 void set responseToMethod(String method) => _responseToMethod = method;
525 595
526 bool get isIdle() => _state == _State.START; 596 bool get isIdle() => _state == _State.START;
527 597
528 void _bodyEnd() { 598 void _bodyEnd() {
529 if (dataEnd != null) { 599 if (dataEnd != null) {
530 dataEnd(_messageType == _MessageType.RESPONSE && _connectionClose); 600 dataEnd(_messageType == _MessageType.RESPONSE && !_persistentConnection);
531 } 601 }
532 } 602 }
533 603
534 _reset() { 604 _reset() {
535 _state = _State.START; 605 _state = _State.START;
536 _messageType = _MessageType.UNDETERMINED; 606 _messageType = _MessageType.UNDETERMINED;
537 _headerField = new StringBuffer(); 607 _headerField = new StringBuffer();
538 _headerValue = new StringBuffer(); 608 _headerValue = new StringBuffer();
539 _method_or_status_code = new StringBuffer(); 609 _method_or_status_code = new StringBuffer();
540 _uri_or_reason_phrase = new StringBuffer(); 610 _uri_or_reason_phrase = new StringBuffer();
541 611
612 _httpVersion = _HttpVersion.UNDETERMINED;
542 _contentLength = -1; 613 _contentLength = -1;
543 _keepAlive = false; 614 _persistentConnection = false;
544 _connectionClose = false;
545 _connectionUpgrade = false; 615 _connectionUpgrade = false;
546 _chunked = false; 616 _chunked = false;
547 617
548 _noMessageBody = false; 618 _noMessageBody = false;
549 _responseToMethod = null; 619 _responseToMethod = null;
550 _remainingContent = null; 620 _remainingContent = null;
551 } 621 }
552 622
553 bool _isTokenChar(int byte) { 623 bool _isTokenChar(int byte) {
554 return byte > 31 && byte < 128 && _Const.SEPARATORS.indexOf(byte) == -1; 624 return byte > 31 && byte < 128 && _Const.SEPARATORS.indexOf(byte) == -1;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
597 } 667 }
598 668
599 int _state; 669 int _state;
600 int _httpVersionIndex; 670 int _httpVersionIndex;
601 int _messageType; 671 int _messageType;
602 StringBuffer _method_or_status_code; 672 StringBuffer _method_or_status_code;
603 StringBuffer _uri_or_reason_phrase; 673 StringBuffer _uri_or_reason_phrase;
604 StringBuffer _headerField; 674 StringBuffer _headerField;
605 StringBuffer _headerValue; 675 StringBuffer _headerValue;
606 676
677 int _httpVersion;
607 int _contentLength; 678 int _contentLength;
608 bool _keepAlive; 679 bool _persistentConnection;
609 bool _connectionClose;
610 bool _connectionUpgrade; 680 bool _connectionUpgrade;
611 bool _chunked; 681 bool _chunked;
612 682
613 bool _noMessageBody; 683 bool _noMessageBody;
614 String _responseToMethod; // Indicates the method used for the request. 684 String _responseToMethod; // Indicates the method used for the request.
615 int _remainingContent; 685 int _remainingContent;
616 686
617 // Callbacks. 687 // Callbacks.
618 Function requestStart; 688 Function requestStart;
619 Function responseStart; 689 Function responseStart;
620 Function headerReceived; 690 Function headerReceived;
621 Function headersComplete; 691 Function headersComplete;
622 Function dataReceived; 692 Function dataReceived;
623 Function dataEnd; 693 Function dataEnd;
624 Function error; 694 Function error;
625 } 695 }
626 696
627 697
628 class HttpParserException implements Exception { 698 class HttpParserException implements Exception {
629 const HttpParserException([String this.message = ""]); 699 const HttpParserException([String this.message = ""]);
630 String toString() => "HttpParserException: $message"; 700 String toString() => "HttpParserException: $message";
631 final String message; 701 final String message;
632 } 702 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698