| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |