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 |