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

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

Issue 11348005: Change the handling og the HTTP content length (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Minor fix Created 8 years, 1 month 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 | runtime/bin/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 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 672 matching lines...) Expand 10 before | Expand all | Expand 10 after
683 bool allWritten = true; 683 bool allWritten = true;
684 if (_contentLength < 0) { 684 if (_contentLength < 0) {
685 // Terminate the content if transfer encoding is chunked. 685 // Terminate the content if transfer encoding is chunked.
686 allWritten = _httpConnection._write(_Const.END_CHUNKED); 686 allWritten = _httpConnection._write(_Const.END_CHUNKED);
687 } else { 687 } else {
688 if (!_headResponse && _bodyBytesWritten < _contentLength) { 688 if (!_headResponse && _bodyBytesWritten < _contentLength) {
689 throw new HttpException("Sending less than specified content length"); 689 throw new HttpException("Sending less than specified content length");
690 } 690 }
691 assert(_headResponse || _bodyBytesWritten == _contentLength); 691 assert(_headResponse || _bodyBytesWritten == _contentLength);
692 } 692 }
693 // If we are done writing the response and the client has closed 693 // If we are done writing the response, and either the client has
694 // or the connection is not persistent we can close. 694 // closed or the connection is not persistent, we can close. Also
695 if (!persistentConnection || _httpConnection._closing) { 695 // if using HTTP 1.0 and the content length was not known we must
696 // close to indicate end of body.
697 if (!persistentConnection || _httpConnection._closing ||
698 (_protocolVersion == "1.0" && _contentLength < 0)) {
696 _httpConnection._close(); 699 _httpConnection._close();
697 } 700 }
698 return allWritten; 701 return allWritten;
699 } 702 }
700 703
701 bool _writeHeaders() { 704 bool _writeHeaders() {
702 _headers._mutable = false; 705 _headers._mutable = false;
703 _headers._write(_httpConnection); 706 _headers._write(_httpConnection);
704 // Terminate header. 707 // Terminate header.
705 return _writeCRLF(); 708 return _writeCRLF();
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
883 }); 886 });
884 if (sessionId != null) { 887 if (sessionId != null) {
885 var sessionManager = _httpConnection._server._sessionManager; 888 var sessionManager = _httpConnection._server._sessionManager;
886 _session = sessionManager.getSession(sessionId); 889 _session = sessionManager.getSession(sessionId);
887 if (_session != null) { 890 if (_session != null) {
888 _session._markSeen(); 891 _session._markSeen();
889 } 892 }
890 } 893 }
891 } 894 }
892 895
896 // Get parsed content length.
897 _contentLength = _httpConnection._httpParser.contentLength;
898
899 // Prepare for receiving data.
893 _headers._mutable = false; 900 _headers._mutable = false;
894 // Prepare for receiving data.
895 _buffer = new _BufferList(); 901 _buffer = new _BufferList();
896 } 902 }
897 903
898 void _onDataReceived(List<int> data) { 904 void _onDataReceived(List<int> data) {
899 _buffer.add(data); 905 _buffer.add(data);
900 if (_inputStream != null) _inputStream._dataReceived(); 906 if (_inputStream != null) _inputStream._dataReceived();
901 } 907 }
902 908
903 void _onDataEnd() { 909 void _onDataEnd() {
904 if (_inputStream != null) _inputStream._closeReceived(); 910 if (_inputStream != null) _inputStream._closeReceived();
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
1091 case HttpStatus.GATEWAY_TIMEOUT: return "Gateway Time-out"; 1097 case HttpStatus.GATEWAY_TIMEOUT: return "Gateway Time-out";
1092 case HttpStatus.HTTP_VERSION_NOT_SUPPORTED: 1098 case HttpStatus.HTTP_VERSION_NOT_SUPPORTED:
1093 return "Http Version not supported"; 1099 return "Http Version not supported";
1094 default: return "Status $statusCode"; 1100 default: return "Status $statusCode";
1095 } 1101 }
1096 } 1102 }
1097 1103
1098 bool _writeHeader() { 1104 bool _writeHeader() {
1099 List<int> data; 1105 List<int> data;
1100 1106
1101 // HTTP/1.0 does not support chunked.
1102 if (_protocolVersion == "1.0" && _contentLength < 0) {
1103 throw new HttpException("Content length required for HTTP 1.0");
1104 }
1105
1106 // Write status line. 1107 // Write status line.
1107 if (_protocolVersion == "1.1") { 1108 if (_protocolVersion == "1.1") {
1108 _httpConnection._write(_Const.HTTP11); 1109 _httpConnection._write(_Const.HTTP11);
1109 } else { 1110 } else {
1110 _httpConnection._write(_Const.HTTP10); 1111 _httpConnection._write(_Const.HTTP10);
1111 } 1112 }
1112 _writeSP(); 1113 _writeSP();
1113 data = _statusCode.toString().charCodes; 1114 data = _statusCode.toString().charCodes;
1114 _httpConnection._write(data); 1115 _httpConnection._write(data);
1115 _writeSP(); 1116 _writeSP();
1116 data = reasonPhrase.charCodes; 1117 data = reasonPhrase.charCodes;
1117 _httpConnection._write(data); 1118 _httpConnection._write(data);
1118 _writeCRLF(); 1119 _writeCRLF();
1119 1120
1120 // Determine the value of the "Transfer-Encoding" header based on 1121 // Determine the value of the "Transfer-Encoding" header based on
1121 // whether the content length is known. 1122 // whether the content length is known. HTTP/1.0 does not support
1123 // chunked.
1122 if (_contentLength >= 0) { 1124 if (_contentLength >= 0) {
1123 _headers.set(HttpHeaders.CONTENT_LENGTH, _contentLength.toString()); 1125 _headers.set(HttpHeaders.CONTENT_LENGTH, _contentLength.toString());
1124 } else if (_contentLength < 0) { 1126 } else if (_contentLength < 0 && _protocolVersion == "1.1") {
1125 _headers.set(HttpHeaders.TRANSFER_ENCODING, "chunked"); 1127 _headers.set(HttpHeaders.TRANSFER_ENCODING, "chunked");
1126 } 1128 }
1127 1129
1128 var session = _httpConnection._request._session; 1130 var session = _httpConnection._request._session;
1129 if (session != null && !session._destroyed) { 1131 if (session != null && !session._destroyed) {
1130 // Make sure we only send the current session id. 1132 // Make sure we only send the current session id.
1131 bool found = false; 1133 bool found = false;
1132 for (int i = 0; i < cookies.length; i++) { 1134 for (int i = 0; i < cookies.length; i++) {
1133 if (cookies[i].name.toUpperCase() == _DART_SESSION_ID) { 1135 if (cookies[i].name.toUpperCase() == _DART_SESSION_ID) {
1134 cookie.value = session.id; 1136 cookie.value = session.id;
(...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after
1688 } else { 1690 } else {
1689 data = _uri.toString().charCodes; 1691 data = _uri.toString().charCodes;
1690 } 1692 }
1691 _httpConnection._write(data); 1693 _httpConnection._write(data);
1692 _writeSP(); 1694 _writeSP();
1693 _httpConnection._write(_Const.HTTP11); 1695 _httpConnection._write(_Const.HTTP11);
1694 _writeCRLF(); 1696 _writeCRLF();
1695 1697
1696 // Determine the value of the "Transfer-Encoding" header based on 1698 // Determine the value of the "Transfer-Encoding" header based on
1697 // whether the content length is known. If there is no content 1699 // whether the content length is known. If there is no content
1698 // neither "Content-Length" nor "Transfer-Encoding" is set 1700 // neither "Content-Length" nor "Transfer-Encoding" is set.
1699 if (_contentLength > 0) { 1701 if (_contentLength > 0) {
1700 _headers.set(HttpHeaders.CONTENT_LENGTH, _contentLength.toString()); 1702 _headers.set(HttpHeaders.CONTENT_LENGTH, _contentLength.toString());
1701 } else if (_contentLength < 0) { 1703 } else if (_contentLength < 0) {
1702 _headers.set(HttpHeaders.TRANSFER_ENCODING, "chunked"); 1704 _headers.set(HttpHeaders.TRANSFER_ENCODING, "chunked");
1703 } 1705 }
1704 1706
1705 // Add the cookies to the headers. 1707 // Add the cookies to the headers.
1706 if (_cookies != null) { 1708 if (_cookies != null) {
1707 StringBuffer sb = new StringBuffer(); 1709 StringBuffer sb = new StringBuffer();
1708 for (int i = 0; i < _cookies.length; i++) { 1710 for (int i = 0; i < _cookies.length; i++) {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1768 // TODO(sgjesse): Error handling 1770 // TODO(sgjesse): Error handling
1769 } 1771 }
1770 1772
1771 void _onResponseStart(int statusCode, String reasonPhrase, String version) { 1773 void _onResponseStart(int statusCode, String reasonPhrase, String version) {
1772 _statusCode = statusCode; 1774 _statusCode = statusCode;
1773 _reasonPhrase = reasonPhrase; 1775 _reasonPhrase = reasonPhrase;
1774 } 1776 }
1775 1777
1776 void _onHeaderReceived(String name, String value) { 1778 void _onHeaderReceived(String name, String value) {
1777 _headers.add(name, value); 1779 _headers.add(name, value);
1778 if (name == "content-length") {
1779 _contentLength = parseInt(value);
1780 }
1781 } 1780 }
1782 1781
1783 void _onHeadersComplete() { 1782 void _onHeadersComplete() {
1783 // Get parsed content length.
1784 _contentLength = _httpConnection._httpParser.contentLength;
1785
1786 // Prepare for receiving data.
1784 _headers._mutable = false; 1787 _headers._mutable = false;
1785 _buffer = new _BufferList(); 1788 _buffer = new _BufferList();
1789
1786 if (isRedirect && _connection.followRedirects) { 1790 if (isRedirect && _connection.followRedirects) {
1787 if (_connection._redirects == null || 1791 if (_connection._redirects == null ||
1788 _connection._redirects.length < _connection.maxRedirects) { 1792 _connection._redirects.length < _connection.maxRedirects) {
1789 // Check the location header. 1793 // Check the location header.
1790 List<String> location = headers[HttpHeaders.LOCATION]; 1794 List<String> location = headers[HttpHeaders.LOCATION];
1791 if (location == null || location.length > 1) { 1795 if (location == null || location.length > 1) {
1792 throw new RedirectException("Invalid redirect", 1796 throw new RedirectException("Invalid redirect",
1793 _connection._redirects); 1797 _connection._redirects);
1794 } 1798 }
1795 // Check for redirect loop 1799 // Check for redirect loop
(...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after
2346 2350
2347 2351
2348 class _RedirectInfo implements RedirectInfo { 2352 class _RedirectInfo implements RedirectInfo {
2349 const _RedirectInfo(int this.statusCode, 2353 const _RedirectInfo(int this.statusCode,
2350 String this.method, 2354 String this.method,
2351 Uri this.location); 2355 Uri this.location);
2352 final int statusCode; 2356 final int statusCode;
2353 final String method; 2357 final String method;
2354 final Uri location; 2358 final Uri location;
2355 } 2359 }
OLDNEW
« no previous file with comments | « no previous file | runtime/bin/http_parser.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698