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

Side by Side Diff: sdk/lib/io/http_impl.dart

Issue 11498010: Improve the handling of HTTP requests with empty body (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Update status file Created 8 years 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
« no previous file with comments | « no previous file | sdk/lib/io/http_parser.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 // The close queue handles graceful closing of HTTP connections. When 5 // The close queue handles graceful closing of HTTP connections. When
6 // a connection is added to the queue it will enter a wait state 6 // a connection is added to the queue it will enter a wait state
7 // waiting for all data written and possibly socket shutdown from 7 // waiting for all data written and possibly socket shutdown from
8 // peer. 8 // peer.
9 class _CloseQueue { 9 class _CloseQueue {
10 _CloseQueue() : _q = new Set<_HttpConnectionBase>(); 10 _CloseQueue() : _q = new Set<_HttpConnectionBase>();
(...skipping 814 matching lines...) Expand 10 before | Expand all | Expand 10 after
825 while (!_buffer.isEmpty) { 825 while (!_buffer.isEmpty) {
826 var data = _buffer.first; 826 var data = _buffer.first;
827 _socket.outputStream.write(data, false); 827 _socket.outputStream.write(data, false);
828 _buffer.removeBytes(data.length); 828 _buffer.removeBytes(data.length);
829 } 829 }
830 _buffer = null; 830 _buffer = null;
831 } 831 }
832 } 832 }
833 833
834 bool _write(List<int> data, [bool copyBuffer = false]) { 834 bool _write(List<int> data, [bool copyBuffer = false]) {
835 if (_isRequestDone) { 835 if (_isRequestDone || !_hasBody || _httpParser.upgrade) {
836 return _socket.outputStream.write(data, copyBuffer); 836 return _socket.outputStream.write(data, copyBuffer);
837 } else { 837 } else {
838 _bufferData(data, copyBuffer); 838 _bufferData(data, copyBuffer);
839 return false; 839 return false;
840 } 840 }
841 } 841 }
842 842
843 bool _writeFrom(List<int> data, [int offset, int len]) { 843 bool _writeFrom(List<int> data, [int offset, int len]) {
844 if (_isRequestDone) { 844 if (_isRequestDone || !_hasBody || _httpParser.upgrade) {
845 return _socket.outputStream.writeFrom(data, offset, len); 845 return _socket.outputStream.writeFrom(data, offset, len);
846 } else { 846 } else {
847 if (offset == null) offset = 0; 847 if (offset == null) offset = 0;
848 if (len == null) len = buffer.length - offset; 848 if (len == null) len = buffer.length - offset;
849 _bufferData(data.getRange(offset, len), false); 849 _bufferData(data.getRange(offset, len), false);
850 return false; 850 return false;
851 } 851 }
852 } 852 }
853 853
854 bool _flush() { 854 bool _flush() {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
888 } 888 }
889 if (_response != null && _response._streamErrorHandler != null) { 889 if (_response != null && _response._streamErrorHandler != null) {
890 _response._streamErrorHandler(e); 890 _response._streamErrorHandler(e);
891 } 891 }
892 if (_socket != null) _socket.close(); 892 if (_socket != null) _socket.close();
893 } 893 }
894 894
895 void _onRequestReceived(String method, 895 void _onRequestReceived(String method,
896 String uri, 896 String uri,
897 String version, 897 String version,
898 _HttpHeaders headers) { 898 _HttpHeaders headers,
899 bool hasBody) {
899 _state = _HttpConnectionBase.ACTIVE; 900 _state = _HttpConnectionBase.ACTIVE;
900 // Create new request and response objects for this request. 901 // Create new request and response objects for this request.
901 _request = new _HttpRequest(this); 902 _request = new _HttpRequest(this);
902 _response = new _HttpResponse(this); 903 _response = new _HttpResponse(this);
903 _request._onRequestReceived(method, uri, version, headers); 904 _request._onRequestReceived(method, uri, version, headers);
904 _request._protocolVersion = version; 905 _request._protocolVersion = version;
905 _response._protocolVersion = version; 906 _response._protocolVersion = version;
906 _response._headResponse = method == "HEAD"; 907 _response._headResponse = method == "HEAD";
907 _response.persistentConnection = _httpParser.persistentConnection; 908 _response.persistentConnection = _httpParser.persistentConnection;
909 _hasBody = hasBody;
908 if (onRequestReceived != null) { 910 if (onRequestReceived != null) {
909 onRequestReceived(_request, _response); 911 onRequestReceived(_request, _response);
910 } 912 }
913 _checkDone();
911 } 914 }
912 915
913 void _onDataReceived(List<int> data) { 916 void _onDataReceived(List<int> data) {
914 _request._onDataReceived(data); 917 _request._onDataReceived(data);
918 _checkDone();
915 } 919 }
916 920
917 void _checkDone() { 921 void _checkDone() {
918 if (_isReadClosed) { 922 if (_isReadClosed) {
919 // If the client closes the conversation is ended. 923 // If the client closes the conversation is ended.
920 _server._closeQueue.add(this); 924 _server._closeQueue.add(this);
921 } else if (_isAllDone) { 925 } else if (_isAllDone) {
922 // If we are done writing the response, and the connection is 926 // If we are done writing the response, and the connection is
923 // not persistent, we must close. Also if using HTTP 1.0 and the 927 // not persistent, we must close. Also if using HTTP 1.0 and the
924 // content length was not known we must close to indicate end of 928 // content length was not known we must close to indicate end of
925 // body. 929 // body.
926 bool close = 930 bool close =
927 !_response.persistentConnection || 931 !_response.persistentConnection ||
928 (_response._protocolVersion == "1.0" && _response._contentLength < 0); 932 (_response._protocolVersion == "1.0" && _response._contentLength < 0);
929 _request = null; 933 _request = null;
930 _response = null; 934 _response = null;
931 if (close) { 935 if (close) {
932 _server._closeQueue.add(this); 936 _server._closeQueue.add(this);
933 } else { 937 } else {
934 _state = _HttpConnectionBase.IDLE; 938 _state = _HttpConnectionBase.IDLE;
935 } 939 }
936 } else if (_isResponseDone) { 940 } else if (_isResponseDone && _hasBody) {
937 // If the response is closed before the request is fully read 941 // If the response is closed before the request is fully read
938 // close this connection. If there is buffered output 942 // close this connection. If there is buffered output
939 // (e.g. error response for invalid request where the server did 943 // (e.g. error response for invalid request where the server did
940 // not care to read the request body) this is send. 944 // not care to read the request body) this is send.
941 assert(!_isRequestDone); 945 assert(!_isRequestDone);
942 _writeBufferedResponse(); 946 _writeBufferedResponse();
943 _close(); 947 _close();
944 _server._closeQueue.add(this); 948 _server._closeQueue.add(this);
945 } 949 }
946 } 950 }
947 951
948 void _onDataEnd(bool close) { 952 void _onDataEnd(bool close) {
949 // Start sending queued response if any. 953 // Start sending queued response if any.
954 _state |= _HttpConnectionBase.REQUEST_DONE;
950 _writeBufferedResponse(); 955 _writeBufferedResponse();
951 _state |= _HttpConnectionBase.REQUEST_DONE;
952 _request._onDataEnd(); 956 _request._onDataEnd();
957 _checkDone();
953 } 958 }
954 959
955 void _responseClosed() { 960 void _responseClosed() {
956 _state |= _HttpConnectionBase.RESPONSE_DONE; 961 _state |= _HttpConnectionBase.RESPONSE_DONE;
957 _checkDone();
958 } 962 }
959 963
960 HttpServer _server; 964 HttpServer _server;
961 HttpRequest _request; 965 HttpRequest _request;
962 HttpResponse _response; 966 HttpResponse _response;
967 bool _hasBody = false;
963 968
964 // Buffer for data written before full response has been processed. 969 // Buffer for data written before full response has been processed.
965 _BufferList _buffer; 970 _BufferList _buffer;
966 971
967 // Callbacks. 972 // Callbacks.
968 Function onRequestReceived; 973 Function onRequestReceived;
969 Function onError; 974 Function onError;
970 } 975 }
971 976
972 977
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
1307 InputStream get inputStream { 1312 InputStream get inputStream {
1308 if (_inputStream == null) { 1313 if (_inputStream == null) {
1309 _inputStream = new _HttpInputStream(this); 1314 _inputStream = new _HttpInputStream(this);
1310 } 1315 }
1311 return _inputStream; 1316 return _inputStream;
1312 } 1317 }
1313 1318
1314 void _onResponseReceived(int statusCode, 1319 void _onResponseReceived(int statusCode,
1315 String reasonPhrase, 1320 String reasonPhrase,
1316 String version, 1321 String version,
1317 _HttpHeaders headers) { 1322 _HttpHeaders headers,
1323 bool hasBody) {
1318 _statusCode = statusCode; 1324 _statusCode = statusCode;
1319 _reasonPhrase = reasonPhrase; 1325 _reasonPhrase = reasonPhrase;
1320 _headers = headers; 1326 _headers = headers;
1321 // Get parsed content length. 1327 // Get parsed content length.
1322 _contentLength = _httpConnection._httpParser.contentLength; 1328 _contentLength = _httpConnection._httpParser.contentLength;
1323 1329
1324 // Prepare for receiving data. 1330 // Prepare for receiving data.
1325 _headers._mutable = false; 1331 _headers._mutable = false;
1326 _buffer = new _BufferList(); 1332 _buffer = new _BufferList();
1327
1328 if (isRedirect && _connection.followRedirects) { 1333 if (isRedirect && _connection.followRedirects) {
1329 if (_connection._redirects == null || 1334 if (_connection._redirects == null ||
1330 _connection._redirects.length < _connection.maxRedirects) { 1335 _connection._redirects.length < _connection.maxRedirects) {
1331 // Check the location header. 1336 // Check the location header.
1332 List<String> location = headers[HttpHeaders.LOCATION]; 1337 List<String> location = headers[HttpHeaders.LOCATION];
1333 if (location == null || location.length > 1) { 1338 if (location == null || location.length > 1) {
1334 throw new RedirectException("Invalid redirect", 1339 throw new RedirectException("Invalid redirect",
1335 _connection._redirects); 1340 _connection._redirects);
1336 } 1341 }
1337 // Check for redirect loop 1342 // Check for redirect loop
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
1608 _onErrorCallback(e); 1613 _onErrorCallback(e);
1609 } else { 1614 } else {
1610 throw e; 1615 throw e;
1611 } 1616 }
1612 } 1617 }
1613 } 1618 }
1614 1619
1615 void _onResponseReceived(int statusCode, 1620 void _onResponseReceived(int statusCode,
1616 String reasonPhrase, 1621 String reasonPhrase,
1617 String version, 1622 String version,
1618 _HttpHeaders headers) { 1623 _HttpHeaders headers,
1619 _response._onResponseReceived(statusCode, reasonPhrase, version, headers); 1624 bool hasBody) {
Mads Ager (google) 2012/12/11 07:04:34 indentation off by 1 space?
Søren Gjesse 2012/12/11 07:26:31 Done.
1625 _response._onResponseReceived(
1626 statusCode, reasonPhrase, version, headers, hasBody);
1620 } 1627 }
1621 1628
1622 void _onDataReceived(List<int> data) { 1629 void _onDataReceived(List<int> data) {
1623 _response._onDataReceived(data); 1630 _response._onDataReceived(data);
1624 } 1631 }
1625 1632
1626 void _onDataEnd(bool close) { 1633 void _onDataEnd(bool close) {
1627 _state |= _HttpConnectionBase.RESPONSE_DONE; 1634 _state |= _HttpConnectionBase.RESPONSE_DONE;
1628 _response._onDataEnd(); 1635 _response._onDataEnd();
1629 _checkSocketDone(); 1636 _checkSocketDone();
(...skipping 648 matching lines...) Expand 10 before | Expand all | Expand 10 after
2278 2285
2279 2286
2280 class _RedirectInfo implements RedirectInfo { 2287 class _RedirectInfo implements RedirectInfo {
2281 const _RedirectInfo(int this.statusCode, 2288 const _RedirectInfo(int this.statusCode,
2282 String this.method, 2289 String this.method,
2283 Uri this.location); 2290 Uri this.location);
2284 final int statusCode; 2291 final int statusCode;
2285 final String method; 2292 final String method;
2286 final Uri location; 2293 final Uri location;
2287 } 2294 }
OLDNEW
« no previous file with comments | « no previous file | sdk/lib/io/http_parser.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698