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

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

Issue 10315002: Improve the handling of the connection header (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Addressed review comments from ajohnsen@ Created 8 years, 7 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 class _HttpHeaders implements HttpHeaders { 5 class _HttpHeaders implements HttpHeaders {
6 _HttpHeaders() : _headers = new Map<String, List<String>>(); 6 _HttpHeaders() : _headers = new Map<String, List<String>>();
7 7
8 List<String> operator[](String name) { 8 List<String> operator[](String name) {
9 name = name.toLowerCase(); 9 name = name.toLowerCase();
10 return _headers[name]; 10 return _headers[name];
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 }); 201 });
202 } 202 }
203 203
204 String toString() { 204 String toString() {
205 StringBuffer sb = new StringBuffer(); 205 StringBuffer sb = new StringBuffer();
206 _headers.forEach((String name, List<String> values) { 206 _headers.forEach((String name, List<String> values) {
207 sb.add(name); 207 sb.add(name);
208 sb.add(": "); 208 sb.add(": ");
209 for (int i = 0; i < values.length; i++) { 209 for (int i = 0; i < values.length; i++) {
210 if (i > 0) { 210 if (i > 0) {
211 sb.add(": "); 211 sb.add(", ");
212 } 212 }
213 sb.add(values[i]); 213 sb.add(values[i]);
214 } 214 }
215 sb.add("\n"); 215 sb.add("\n");
216 }); 216 });
217 return sb.toString(); 217 return sb.toString();
218 } 218 }
219 219
220 bool _mutable = true; // Are the headers currently mutable? 220 bool _mutable = true; // Are the headers currently mutable?
221 Map<String, List<String>> _headers; 221 Map<String, List<String>> _headers;
(...skipping 10 matching lines...) Expand all
232 final int UPGRADED = 3; 232 final int UPGRADED = 3;
233 233
234 _HttpRequestResponseBase(_HttpConnectionBase this._httpConnection) 234 _HttpRequestResponseBase(_HttpConnectionBase this._httpConnection)
235 : _headers = new _HttpHeaders() { 235 : _headers = new _HttpHeaders() {
236 _state = START; 236 _state = START;
237 } 237 }
238 238
239 int get contentLength() => _contentLength; 239 int get contentLength() => _contentLength;
240 HttpHeaders get headers() => _headers; 240 HttpHeaders get headers() => _headers;
241 241
242 bool get persistentConnection() {
243 List<String> connection = headers[HttpHeaders.CONNECTION];
244 if (_protocolVersion == "1.1") {
245 if (connection == null) return true;
246 return !headers[HttpHeaders.CONNECTION].some(
247 (value) => value.toLowerCase() == "close");
248 } else {
249 if (connection == null) return false;
250 return headers[HttpHeaders.CONNECTION].some(
251 (value) => value.toLowerCase() == "keep-alive");
252 }
253 }
254
255 void set persistentConnection(bool persistentConnection) {
256 if (_outputStream != null) throw new HttpException("Header already sent");
257
258 // Determine the value of the "Connection" header.
259 headers.remove(HttpHeaders.CONNECTION, "close");
260 headers.remove(HttpHeaders.CONNECTION, "keep-alive");
261 if (_protocolVersion == "1.1" && !persistentConnection) {
262 headers.add(HttpHeaders.CONNECTION, "close");
263 } else if (_protocolVersion == "1.0" && persistentConnection) {
264 headers.add(HttpHeaders.CONNECTION, "keep-alive");
265 }
266 }
267
268
242 bool _write(List<int> data, bool copyBuffer) { 269 bool _write(List<int> data, bool copyBuffer) {
243 _ensureHeadersSent(); 270 _ensureHeadersSent();
244 bool allWritten = true; 271 bool allWritten = true;
245 if (data.length > 0) { 272 if (data.length > 0) {
246 if (_contentLength < 0) { 273 if (_contentLength < 0) {
247 // Write chunk size if transfer encoding is chunked. 274 // Write chunk size if transfer encoding is chunked.
248 _writeHexString(data.length); 275 _writeHexString(data.length);
249 _writeCRLF(); 276 _writeCRLF();
250 _httpConnection._write(data, copyBuffer); 277 _httpConnection._write(data, copyBuffer);
251 allWritten = _writeCRLF(); 278 allWritten = _writeCRLF();
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 if (_bodyBytesWritten + bytes > _contentLength) { 358 if (_bodyBytesWritten + bytes > _contentLength) {
332 throw new HttpException("Writing more than specified content length"); 359 throw new HttpException("Writing more than specified content length");
333 } 360 }
334 _bodyBytesWritten += bytes; 361 _bodyBytesWritten += bytes;
335 } 362 }
336 363
337 int _state; 364 int _state;
338 365
339 _HttpConnectionBase _httpConnection; 366 _HttpConnectionBase _httpConnection;
340 _HttpHeaders _headers; 367 _HttpHeaders _headers;
368 String _protocolVersion = "1.1";
341 369
342 // Length of the content body. If this is set to -1 (default value) 370 // Length of the content body. If this is set to -1 (default value)
343 // when starting to send data chunked transfer encoding will be 371 // when starting to send data chunked transfer encoding will be
344 // used. 372 // used.
345 int _contentLength = -1; 373 int _contentLength = -1;
346 // Number of body bytes written. This is only actual body data not 374 // Number of body bytes written. This is only actual body data not
347 // including headers or chunk information of using chinked transfer 375 // including headers or chunk information of using chinked transfer
348 // encoding. 376 // encoding.
349 int _bodyBytesWritten = 0; 377 int _bodyBytesWritten = 0;
350 } 378 }
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
585 _httpConnection._write(_Const.HTTP10); 613 _httpConnection._write(_Const.HTTP10);
586 } 614 }
587 _writeSP(); 615 _writeSP();
588 data = _statusCode.toString().charCodes(); 616 data = _statusCode.toString().charCodes();
589 _httpConnection._write(data); 617 _httpConnection._write(data);
590 _writeSP(); 618 _writeSP();
591 data = reasonPhrase.charCodes(); 619 data = reasonPhrase.charCodes();
592 _httpConnection._write(data); 620 _httpConnection._write(data);
593 _writeCRLF(); 621 _writeCRLF();
594 622
595 // Determine the value of the "Connection" header.
596 if (_protocolVersion == "1.1" && !_persistentConnection) {
597 _headers.set("Connection", "close");
598 } else if (_protocolVersion == "1.0" && _persistentConnection) {
599 _headers.set("Connection", "keep-alive");
600 }
601 // Determine the value of the "Transfer-Encoding" header based on 623 // Determine the value of the "Transfer-Encoding" header based on
602 // whether the content length is known. 624 // whether the content length is known.
603 if (_contentLength > 0) { 625 if (_contentLength > 0) {
604 _headers.set("Content-Length", _contentLength.toString()); 626 _headers.set(HttpHeaders.CONTENT_LENGTH, _contentLength.toString());
605 } else { 627 } else {
606 _headers.set("Transfer-Encoding", "chunked"); 628 _headers.set(HttpHeaders.TRANSFER_ENCODING, "chunked");
607 } 629 }
608 630
609 // Write headers. 631 // Write headers.
610 bool allWritten = _writeHeaders(); 632 bool allWritten = _writeHeaders();
611 _state = HEADER_SENT; 633 _state = HEADER_SENT;
612 return allWritten; 634 return allWritten;
613 } 635 }
614 636
615 // Response status code. 637 // Response status code.
616 int _statusCode; 638 int _statusCode;
617 String _reasonPhrase; 639 String _reasonPhrase;
618 String _protocolVersion;
619 bool _persistentConnection;
620 _HttpOutputStream _outputStream; 640 _HttpOutputStream _outputStream;
621 Function _streamErrorHandler; 641 Function _streamErrorHandler;
622 } 642 }
623 643
624 644
625 class _HttpInputStream extends _BaseDataInputStream implements InputStream { 645 class _HttpInputStream extends _BaseDataInputStream implements InputStream {
626 _HttpInputStream(_HttpRequestResponseBase this._requestOrResponse) { 646 _HttpInputStream(_HttpRequestResponseBase this._requestOrResponse) {
627 _checkScheduleCallbacks(); 647 _checkScheduleCallbacks();
628 } 648 }
629 649
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
851 // Indicate connection close to the HTTP parser. 871 // Indicate connection close to the HTTP parser.
852 _httpParser.connectionClosed(); 872 _httpParser.connectionClosed();
853 } 873 }
854 } 874 }
855 875
856 void _onRequestStart(String method, String uri, String version) { 876 void _onRequestStart(String method, String uri, String version) {
857 // Create new request and response objects for this request. 877 // Create new request and response objects for this request.
858 _request = new _HttpRequest(this); 878 _request = new _HttpRequest(this);
859 _response = new _HttpResponse(this); 879 _response = new _HttpResponse(this);
860 _request._onRequestStart(method, uri, version); 880 _request._onRequestStart(method, uri, version);
881 _request._protocolVersion = version;
861 _response._protocolVersion = version; 882 _response._protocolVersion = version;
862 } 883 }
863 884
864 void _onResponseStart(int statusCode, String reasonPhrase, String version) { 885 void _onResponseStart(int statusCode, String reasonPhrase, String version) {
865 // TODO(sgjesse): Error handling. 886 // TODO(sgjesse): Error handling.
866 } 887 }
867 888
868 void _onHeaderReceived(String name, String value) { 889 void _onHeaderReceived(String name, String value) {
869 _request._onHeaderReceived(name, value); 890 _request._onHeaderReceived(name, value);
870 } 891 }
871 892
872 void _onHeadersComplete() { 893 void _onHeadersComplete() {
873 _request._onHeadersComplete(); 894 _request._onHeadersComplete();
874 _response._persistentConnection = _httpParser.persistentConnection; 895 _response.persistentConnection = _httpParser.persistentConnection;
875 if (onRequestReceived != null) { 896 if (onRequestReceived != null) {
876 onRequestReceived(_request, _response); 897 onRequestReceived(_request, _response);
877 } 898 }
878 } 899 }
879 900
880 void _onDataReceived(List<int> data) { 901 void _onDataReceived(List<int> data) {
881 _request._onDataReceived(data); 902 _request._onDataReceived(data);
882 } 903 }
883 904
884 void _onDataEnd(bool close) { 905 void _onDataEnd(bool close) {
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
1087 data = _uri.toString().charCodes(); 1108 data = _uri.toString().charCodes();
1088 _httpConnection._write(data); 1109 _httpConnection._write(data);
1089 _writeSP(); 1110 _writeSP();
1090 _httpConnection._write(_Const.HTTP11); 1111 _httpConnection._write(_Const.HTTP11);
1091 _writeCRLF(); 1112 _writeCRLF();
1092 1113
1093 // Determine the value of the "Transfer-Encoding" header based on 1114 // Determine the value of the "Transfer-Encoding" header based on
1094 // whether the content length is known. If there is no content 1115 // whether the content length is known. If there is no content
1095 // neither "Content-Length" nor "Transfer-Encoding" is set 1116 // neither "Content-Length" nor "Transfer-Encoding" is set
1096 if (_contentLength > 0) { 1117 if (_contentLength > 0) {
1097 _headers.set("Content-Length", _contentLength.toString()); 1118 _headers.set(HttpHeaders.CONTENT_LENGTH, _contentLength.toString());
1098 } else if (_contentLength < 0) { 1119 } else if (_contentLength < 0) {
1099 _headers.set("Transfer-Encoding", "chunked"); 1120 _headers.set(HttpHeaders.TRANSFER_ENCODING, "chunked");
1100 } 1121 }
1101 1122
1102 // Write headers. 1123 // Write headers.
1103 _writeHeaders(); 1124 _writeHeaders();
1104 _state = HEADER_SENT; 1125 _state = HEADER_SENT;
1105 } 1126 }
1106 1127
1107 String _method; 1128 String _method;
1108 String _uri; 1129 String _uri;
1109 _HttpClientConnection _connection; 1130 _HttpClientConnection _connection;
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after
1499 _activeSockets.remove(socketConn); 1520 _activeSockets.remove(socketConn);
1500 sockets.addFirst(socketConn); 1521 sockets.addFirst(socketConn);
1501 } 1522 }
1502 1523
1503 Function _onOpen; 1524 Function _onOpen;
1504 Map<String, Queue<_SocketConnection>> _openSockets; 1525 Map<String, Queue<_SocketConnection>> _openSockets;
1505 Set<_SocketConnection> _activeSockets; 1526 Set<_SocketConnection> _activeSockets;
1506 Timer _evictionTimer; 1527 Timer _evictionTimer;
1507 bool _shutdown; // Has this HTTP client been shutdown? 1528 bool _shutdown; // Has this HTTP client been shutdown?
1508 } 1529 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698