| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 part of dart.io; | 5 part of dart.io; |
| 6 | 6 |
| 7 const int _HEADERS_BUFFER_SIZE = 8 * 1024; | 7 const int _HEADERS_BUFFER_SIZE = 8 * 1024; |
| 8 | 8 |
| 9 class _HttpIncoming extends Stream<List<int>> { | 9 class _HttpIncoming extends Stream<List<int>> { |
| 10 final int _transferLength; | 10 final int _transferLength; |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 88 | 88 |
| 89 final _HttpConnection _httpConnection; | 89 final _HttpConnection _httpConnection; |
| 90 | 90 |
| 91 _HttpSession _session; | 91 _HttpSession _session; |
| 92 | 92 |
| 93 _HttpRequest(_HttpResponse this.response, | 93 _HttpRequest(_HttpResponse this.response, |
| 94 _HttpIncoming _incoming, | 94 _HttpIncoming _incoming, |
| 95 _HttpServer this._httpServer, | 95 _HttpServer this._httpServer, |
| 96 _HttpConnection this._httpConnection) | 96 _HttpConnection this._httpConnection) |
| 97 : super(_incoming) { | 97 : super(_incoming) { |
| 98 response.headers.persistentConnection = headers.persistentConnection; | 98 if (headers.protocolVersion == "1.1") { |
| 99 response.headers.chunkedTransferEncoding = true; |
| 100 response.headers.persistentConnection = headers.persistentConnection; |
| 101 } |
| 99 | 102 |
| 100 if (_httpServer._sessionManagerInstance != null) { | 103 if (_httpServer._sessionManagerInstance != null) { |
| 101 // Map to session if exists. | 104 // Map to session if exists. |
| 102 var sessionIds = cookies | 105 var sessionIds = cookies |
| 103 .where((cookie) => cookie.name.toUpperCase() == _DART_SESSION_ID) | 106 .where((cookie) => cookie.name.toUpperCase() == _DART_SESSION_ID) |
| 104 .map((cookie) => cookie.value); | 107 .map((cookie) => cookie.value); |
| 105 for (var sessionId in sessionIds) { | 108 for (var sessionId in sessionIds) { |
| 106 _session = _httpServer._sessionManager.getSession(sessionId); | 109 _session = _httpServer._sessionManager.getSession(sessionId); |
| 107 if (_session != null) { | 110 if (_session != null) { |
| 108 _session._markSeen(); | 111 _session._markSeen(); |
| (...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 485 try { | 488 try { |
| 486 _writeHeader(); | 489 _writeHeader(); |
| 487 } catch (error) { | 490 } catch (error) { |
| 488 // Headers too large. | 491 // Headers too large. |
| 489 throw new HttpException( | 492 throw new HttpException( |
| 490 "Headers size exceeded the of '$_HEADERS_BUFFER_SIZE' bytes"); | 493 "Headers size exceeded the of '$_HEADERS_BUFFER_SIZE' bytes"); |
| 491 } | 494 } |
| 492 } | 495 } |
| 493 if (_headersWritten) return new Future.value(); | 496 if (_headersWritten) return new Future.value(); |
| 494 _headersWritten = true; | 497 _headersWritten = true; |
| 495 headers._synchronize(); // Be sure the 'chunked' option is updated. | |
| 496 _dataSink.encoding = encoding; | 498 _dataSink.encoding = encoding; |
| 497 bool isServerSide = this is _HttpResponse; | 499 bool isServerSide = this is _HttpResponse; |
| 498 if (isServerSide) { | 500 if (isServerSide) { |
| 499 var response = this; | 501 var response = this; |
| 500 if (headers.chunkedTransferEncoding) { | 502 if (headers.chunkedTransferEncoding) { |
| 501 List acceptEncodings = | 503 List acceptEncodings = |
| 502 response._httpRequest.headers[HttpHeaders.ACCEPT_ENCODING]; | 504 response._httpRequest.headers[HttpHeaders.ACCEPT_ENCODING]; |
| 503 List contentEncoding = headers[HttpHeaders.CONTENT_ENCODING]; | 505 List contentEncoding = headers[HttpHeaders.CONTENT_ENCODING]; |
| 504 if (acceptEncodings != null && | 506 if (acceptEncodings != null && |
| 505 acceptEncodings | 507 acceptEncodings |
| (...skipping 30 matching lines...) Expand all Loading... |
| 536 stream = stream.transform(const _ChunkedTransformer()); | 538 stream = stream.transform(const _ChunkedTransformer()); |
| 537 } else if (contentLength >= 0) { | 539 } else if (contentLength >= 0) { |
| 538 stream = stream.transform( | 540 stream = stream.transform( |
| 539 new _ContentLengthValidator(contentLength, _uri)); | 541 new _ContentLengthValidator(contentLength, _uri)); |
| 540 } | 542 } |
| 541 return _headersSink.addStream(stream); | 543 return _headersSink.addStream(stream); |
| 542 }); | 544 }); |
| 543 } | 545 } |
| 544 | 546 |
| 545 Future _close() { | 547 Future _close() { |
| 546 // TODO(ajohnsen): Currently, contentLength, chunkedTransferEncoding and | |
| 547 // persistentConnection is not guaranteed to be in sync. | |
| 548 if (!_headersWritten) { | 548 if (!_headersWritten) { |
| 549 if (!_ignoreBody && headers.contentLength == -1) { | 549 if (!_ignoreBody && headers.contentLength == -1) { |
| 550 // If no body was written, _ignoreBody is false (it's not a HEAD | 550 // If no body was written, _ignoreBody is false (it's not a HEAD |
| 551 // request) and the content-length is unspecified, set contentLength to | 551 // request) and the content-length is unspecified, set contentLength to |
| 552 // 0. | 552 // 0. |
| 553 headers.chunkedTransferEncoding = false; | 553 headers.chunkedTransferEncoding = false; |
| 554 headers.contentLength = 0; | 554 headers.contentLength = 0; |
| 555 } else if (!_ignoreBody && headers.contentLength > 0) { | 555 } else if (!_ignoreBody && headers.contentLength > 0) { |
| 556 _headersSink.addError(new HttpException( | 556 _headersSink.addError(new HttpException( |
| 557 "No content while contentLength was specified to be greater " | 557 "No content while contentLength was specified to be greater " |
| (...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 926 Uri uri, | 926 Uri uri, |
| 927 String this.method, | 927 String this.method, |
| 928 _Proxy this._proxy, | 928 _Proxy this._proxy, |
| 929 _HttpClient this._httpClient, | 929 _HttpClient this._httpClient, |
| 930 _HttpClientConnection this._httpClientConnection) | 930 _HttpClientConnection this._httpClientConnection) |
| 931 : super(uri, "1.1", outgoing), | 931 : super(uri, "1.1", outgoing), |
| 932 uri = uri { | 932 uri = uri { |
| 933 // GET and HEAD have 'content-length: 0' by default. | 933 // GET and HEAD have 'content-length: 0' by default. |
| 934 if (method == "GET" || method == "HEAD") { | 934 if (method == "GET" || method == "HEAD") { |
| 935 contentLength = 0; | 935 contentLength = 0; |
| 936 } else { |
| 937 headers.chunkedTransferEncoding = true; |
| 936 } | 938 } |
| 937 } | 939 } |
| 938 | 940 |
| 939 Future<HttpClientResponse> get done { | 941 Future<HttpClientResponse> get done { |
| 940 if (_response == null) { | 942 if (_response == null) { |
| 941 _response = Future.wait([_responseCompleter.future, | 943 _response = Future.wait([_responseCompleter.future, |
| 942 super.done]) | 944 super.done]) |
| 943 .then((list) => list[0]); | 945 .then((list) => list[0]); |
| 944 } | 946 } |
| 945 return _response; | 947 return _response; |
| (...skipping 1606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2552 | 2554 |
| 2553 String _getHttpVersion() { | 2555 String _getHttpVersion() { |
| 2554 var version = Platform.version; | 2556 var version = Platform.version; |
| 2555 // Only include major and minor version numbers. | 2557 // Only include major and minor version numbers. |
| 2556 int index = version.indexOf('.', version.indexOf('.') + 1); | 2558 int index = version.indexOf('.', version.indexOf('.') + 1); |
| 2557 version = version.substring(0, index); | 2559 version = version.substring(0, index); |
| 2558 return 'Dart/$version (dart:io)'; | 2560 return 'Dart/$version (dart:io)'; |
| 2559 } | 2561 } |
| 2560 | 2562 |
| 2561 | 2563 |
| OLD | NEW |