| 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 // Utility class for encoding a string into UTF-8 byte stream. | |
| 6 class _UTF8Encoder { | |
| 7 static List<int> encodeString(String string) { | |
| 8 int size = _encodingSize(string); | |
| 9 ByteArray result = new ByteArray(size); | |
| 10 _encodeString(string, result); | |
| 11 return result; | |
| 12 } | |
| 13 | |
| 14 static int _encodingSize(String string) => _encodeString(string, null); | |
| 15 | |
| 16 static int _encodeString(String string, List<int> buffer) { | |
| 17 int pos = 0; | |
| 18 int length = string.length; | |
| 19 for (int i = 0; i < length; i++) { | |
| 20 int additionalBytes; | |
| 21 int charCode = string.charCodeAt(i); | |
| 22 if (charCode <= 0x007F) { | |
| 23 additionalBytes = 0; | |
| 24 if (buffer != null) buffer[pos] = charCode; | |
| 25 } else if (charCode <= 0x07FF) { | |
| 26 // 110xxxxx (xxxxx is top 5 bits). | |
| 27 if (buffer != null) buffer[pos] = ((charCode >> 6) & 0x1F) | 0xC0; | |
| 28 additionalBytes = 1; | |
| 29 } else if (charCode <= 0xFFFF) { | |
| 30 // 1110xxxx (xxxx is top 4 bits) | |
| 31 if (buffer != null) buffer[pos] = ((charCode >> 12) & 0x0F)| 0xE0; | |
| 32 additionalBytes = 2; | |
| 33 } else { | |
| 34 // 11110xxx (xxx is top 3 bits) | |
| 35 if (buffer != null) buffer[pos] = ((charCode >> 18) & 0x07) | 0xF0; | |
| 36 additionalBytes = 3; | |
| 37 } | |
| 38 pos++; | |
| 39 if (buffer != null) { | |
| 40 for (int i = additionalBytes; i > 0; i--) { | |
| 41 // 10xxxxxx (xxxxxx is next 6 bits from the top). | |
| 42 buffer[pos++] = ((charCode >> (6 * (i - 1))) & 0x3F) | 0x80; | |
| 43 } | |
| 44 } else { | |
| 45 pos += additionalBytes; | |
| 46 } | |
| 47 } | |
| 48 return pos; | |
| 49 } | |
| 50 } | |
| 51 | |
| 52 | |
| 53 class _HttpRequestResponseBase { | 5 class _HttpRequestResponseBase { |
| 54 _HttpRequestResponseBase(_HttpConnectionBase this._httpConnection) | 6 _HttpRequestResponseBase(_HttpConnectionBase this._httpConnection) |
| 55 : _contentLength = -1, | 7 : _contentLength = -1, |
| 56 _keepAlive = false, | 8 _keepAlive = false, |
| 57 _headers = new Map(); | 9 _headers = new Map(); |
| 58 | 10 |
| 59 int get contentLength() => _contentLength; | 11 int get contentLength() => _contentLength; |
| 60 bool get keepAlive() => _keepAlive; | 12 bool get keepAlive() => _keepAlive; |
| 61 Map get headers() => _headers; | 13 Map get headers() => _headers; |
| 62 | 14 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 89 _writeCRLF(); | 41 _writeCRLF(); |
| 90 _httpConnection.outputStream.writeFrom(data, offset, count); | 42 _httpConnection.outputStream.writeFrom(data, offset, count); |
| 91 allWritten = _writeCRLF(); | 43 allWritten = _writeCRLF(); |
| 92 } else { | 44 } else { |
| 93 allWritten = _httpConnection.outputStream.writeFrom(data, offset, count)
; | 45 allWritten = _httpConnection.outputStream.writeFrom(data, offset, count)
; |
| 94 } | 46 } |
| 95 } | 47 } |
| 96 return allWritten; | 48 return allWritten; |
| 97 } | 49 } |
| 98 | 50 |
| 99 bool _writeString(String string) { | |
| 100 bool allWritten = true; | |
| 101 if (string.length > 0) { | |
| 102 // Encode as UTF-8 and write data. | |
| 103 List<int> data = _UTF8Encoder.encodeString(string); | |
| 104 allWritten = _writeList(data, 0, data.length); | |
| 105 } | |
| 106 return allWritten; | |
| 107 } | |
| 108 | |
| 109 bool _writeDone() { | 51 bool _writeDone() { |
| 110 bool allWritten = true; | 52 bool allWritten = true; |
| 111 if (_contentLength < 0) { | 53 if (_contentLength < 0) { |
| 112 // Terminate the content if transfer encoding is chunked. | 54 // Terminate the content if transfer encoding is chunked. |
| 113 allWritten = _httpConnection.outputStream.write(_Const.END_CHUNKED); | 55 allWritten = _httpConnection.outputStream.write(_Const.END_CHUNKED); |
| 114 } | 56 } |
| 115 return allWritten; | 57 return allWritten; |
| 116 } | 58 } |
| 117 | 59 |
| 118 bool _writeHeaders() { | 60 bool _writeHeaders() { |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 306 if (_outputStream == null) { | 248 if (_outputStream == null) { |
| 307 // Ensure that headers are written. | 249 // Ensure that headers are written. |
| 308 if (_state == START) { | 250 if (_state == START) { |
| 309 _writeHeader(); | 251 _writeHeader(); |
| 310 } | 252 } |
| 311 _outputStream = new _HttpOutputStream(this); | 253 _outputStream = new _HttpOutputStream(this); |
| 312 } | 254 } |
| 313 return _outputStream; | 255 return _outputStream; |
| 314 } | 256 } |
| 315 | 257 |
| 316 bool writeString(String string) { | |
| 317 // Invoke the output stream getter to make sure the header is sent. | |
| 318 outputStream; | |
| 319 return _writeString(string); | |
| 320 } | |
| 321 | |
| 322 // Delegate functions for the HttpOutputStream implementation. | 258 // Delegate functions for the HttpOutputStream implementation. |
| 323 bool _streamWrite(List<int> buffer, bool copyBuffer) { | 259 bool _streamWrite(List<int> buffer, bool copyBuffer) { |
| 324 return _write(buffer, copyBuffer); | 260 return _write(buffer, copyBuffer); |
| 325 } | 261 } |
| 326 | 262 |
| 327 bool _streamWriteFrom(List<int> buffer, int offset, int len) { | 263 bool _streamWriteFrom(List<int> buffer, int offset, int len) { |
| 328 return _writeList(buffer, offset, len); | 264 return _writeList(buffer, offset, len); |
| 329 } | 265 } |
| 330 | 266 |
| 331 void _streamClose() { | 267 void _streamClose() { |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 481 } | 417 } |
| 482 | 418 |
| 483 void _dataReceived() { | 419 void _dataReceived() { |
| 484 super._dataReceived(); | 420 super._dataReceived(); |
| 485 } | 421 } |
| 486 | 422 |
| 487 _HttpRequestResponseBase _requestOrResponse; | 423 _HttpRequestResponseBase _requestOrResponse; |
| 488 } | 424 } |
| 489 | 425 |
| 490 | 426 |
| 491 class _HttpOutputStream implements OutputStream { | 427 class _HttpOutputStream extends _BaseOutputStream implements OutputStream { |
| 492 _HttpOutputStream(_HttpRequestResponseBase this._requestOrResponse); | 428 _HttpOutputStream(_HttpRequestResponseBase this._requestOrResponse); |
| 493 | 429 |
| 494 bool write(List<int> buffer, [bool copyBuffer = true]) { | 430 bool write(List<int> buffer, [bool copyBuffer = true]) { |
| 495 return _requestOrResponse._streamWrite(buffer, copyBuffer); | 431 return _requestOrResponse._streamWrite(buffer, copyBuffer); |
| 496 } | 432 } |
| 497 | 433 |
| 498 bool writeFrom(List<int> buffer, [int offset = 0, int len]) { | 434 bool writeFrom(List<int> buffer, [int offset = 0, int len]) { |
| 499 return _requestOrResponse._streamWriteFrom(buffer, offset, len); | 435 return _requestOrResponse._streamWriteFrom(buffer, offset, len); |
| 500 } | 436 } |
| 501 | 437 |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 755 } else { | 691 } else { |
| 756 _port = Math.parseInt(value.substring(pos + 1)); | 692 _port = Math.parseInt(value.substring(pos + 1)); |
| 757 } | 693 } |
| 758 } | 694 } |
| 759 _updateHostHeader(); | 695 _updateHostHeader(); |
| 760 return; | 696 return; |
| 761 } | 697 } |
| 762 _setHeader(name, value); | 698 _setHeader(name, value); |
| 763 } | 699 } |
| 764 | 700 |
| 765 bool writeString(String string) { | |
| 766 outputStream; | |
| 767 return _writeString(string); | |
| 768 } | |
| 769 | |
| 770 OutputStream get outputStream() { | 701 OutputStream get outputStream() { |
| 771 if (_state == DONE) throw new HttpException("Request closed"); | 702 if (_state == DONE) throw new HttpException("Request closed"); |
| 772 if (_outputStream == null) { | 703 if (_outputStream == null) { |
| 773 // Ensure that headers are written. | 704 // Ensure that headers are written. |
| 774 if (_state == START) { | 705 if (_state == START) { |
| 775 _writeHeader(); | 706 _writeHeader(); |
| 776 } | 707 } |
| 777 _outputStream = new _HttpOutputStream(this); | 708 _outputStream = new _HttpOutputStream(this); |
| 778 } | 709 } |
| 779 return _outputStream; | 710 return _outputStream; |
| (...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1207 _onError = callback; | 1138 _onError = callback; |
| 1208 } | 1139 } |
| 1209 | 1140 |
| 1210 Function _onOpen; | 1141 Function _onOpen; |
| 1211 Function _onError; | 1142 Function _onError; |
| 1212 Map<String, Queue<_SocketConnection>> _openSockets; | 1143 Map<String, Queue<_SocketConnection>> _openSockets; |
| 1213 Set<_SocketConnection> _activeSockets; | 1144 Set<_SocketConnection> _activeSockets; |
| 1214 Timer _evictionTimer; | 1145 Timer _evictionTimer; |
| 1215 bool _shutdown; // Has this HTTP client been shutdown? | 1146 bool _shutdown; // Has this HTTP client been shutdown? |
| 1216 } | 1147 } |
| OLD | NEW |