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 |