Chromium Code Reviews| Index: sdk/lib/io/http_impl.dart |
| diff --git a/sdk/lib/io/http_impl.dart b/sdk/lib/io/http_impl.dart |
| index b4d83af6f213afe73fe422b2b1882bff70e862a3..0ac2c7d5f80b83c0ce9a01e6c0045364e153d5a0 100644 |
| --- a/sdk/lib/io/http_impl.dart |
| +++ b/sdk/lib/io/http_impl.dart |
| @@ -332,7 +332,7 @@ abstract class _HttpOutboundMessage<T> implements IOSink { |
| _HttpOutboundMessage(String protocolVersion, _HttpOutgoing outgoing) |
| : _outgoing = outgoing, |
| - _ioSink = new IOSink(outgoing), |
| + _ioSink = new IOSink(outgoing, Encoding.ASCII), |
| headers = new _HttpHeaders(protocolVersion); |
| int get contentLength => headers.contentLength; |
| @@ -345,28 +345,75 @@ abstract class _HttpOutboundMessage<T> implements IOSink { |
| headers.persistentConnection = p; |
| } |
| - Future<T> consume(Stream<List<int>> stream) { |
| + Encoding get encoding { |
| + return headers.contentType != null ? headers.contentType.encoding |
| + : Encoding.ISO_8859_1; |
| + } |
| + void set encoding(Encoding value) { |
| + throw new StateError("IOSink encoding is not mutable"); |
| + } |
| + |
| + void write(Object obj) { |
| _writeHeaders(); |
| - if (_ignoreBody) return new Future.immediate(this); |
| + if (_ignoreBody) return; |
| + // This comment is copied from runtime/lib/string_buffer_patch.dart. |
| + // TODO(srdjan): The following four lines could be replaced by |
| + // '$obj', but apparently this is too slow on the Dart VM. |
| + String string; |
| + if (obj is String) { |
| + string = obj; |
| + } else { |
| + string = obj.toString(); |
| + if (string is! String) { |
| + throw new ArgumentError('toString() did not return a string'); |
| + } |
| + } |
| + if (string.isEmpty) return; |
| if (_chunked) { |
| - // Transform when chunked. |
| - stream = stream.transform(new _ChunkedTransformer()); |
| + _ChunkedTransformer._addChunk(_encodeString(string, encoding), |
| + _ioSink.writeBytes); |
| + } else { |
| + _ioSink.write(string); |
| } |
| - return _ioSink.consume(stream).then((_) => this); |
| } |
| - void add(List<int> data) { |
| + void writeAll(Iterable objects) { |
| + for (Object obj in objects) write(obj); |
| + } |
| + |
| + void writeln(Object obj) { |
| + write(obj); |
| + write("\n"); |
| + } |
| + |
| + void writeCharCode(int charCode) { |
| + write(new String.fromCharCode(charCode)); |
| + } |
| + |
| + void writeBytes(List<int> data) { |
| _writeHeaders(); |
| if (_ignoreBody || data.length == 0) return; |
| if (_chunked) { |
| - _ChunkedTransformer._addChunk(data, _ioSink.add); |
| + _ChunkedTransformer._addChunk(data, _ioSink.writeBytes); |
| } else { |
| - _ioSink.add(data); |
| + _ioSink.writeBytes(data); |
| + } |
| + } |
| + |
| + Future<T> consume(Stream<List<int>> stream) { |
| + _writeHeaders(); |
| + if (_ignoreBody) return new Future.immediate(this); |
| + if (_chunked) { |
| + // Transform when chunked. |
| + stream = stream.transform(new _ChunkedTransformer()); |
| } |
| + return _ioSink.consume(stream).then((_) => this); |
| } |
| + void add(List<int> data) => writeBytes(data); |
| + |
| void addString(String string, [Encoding encoding = Encoding.UTF_8]) { |
| - add(_encodeString(string, encoding)); |
| + writeBytes(_encodeString(string, encoding)); |
| } |
| Future<T> addStream(Stream<List<int>> stream) { |
| @@ -388,7 +435,7 @@ abstract class _HttpOutboundMessage<T> implements IOSink { |
| _writeHeaders(); |
| if (!_ignoreBody) { |
| if (_chunked) { |
| - _ChunkedTransformer._addChunk([], _ioSink.add); |
| + _ChunkedTransformer._addChunk([], _ioSink.writeBytes); |
| } |
| } |
| _ioSink.close(); |
| @@ -401,7 +448,11 @@ abstract class _HttpOutboundMessage<T> implements IOSink { |
| bool _tmpIgnoreBody = _ignoreBody; |
| _ignoreBody = false; |
| _headersWritten = true; |
| + _ioSink.encoding = Encoding.ASCII; |
| _writeHeader(); |
| + _ioSink.encoding = |
| + headers.contentType != null ? headers.contentType.encoding |
| + : Encoding.ISO_8859_1; |
| _ignoreBody = _tmpIgnoreBody; |
| if (_ignoreBody) { |
| _ioSink.close(); |
| @@ -455,19 +506,19 @@ class _HttpResponse extends _HttpOutboundMessage<HttpResponse> |
| HttpConnectionInfo get connectionInfo => _httpRequest.connectionInfo; |
| void _writeHeader() { |
| - writeSP() => add([_CharCode.SP]); |
| - writeCRLF() => add([_CharCode.CR, _CharCode.LF]); |
| + writeSP() => writeBytes([_CharCode.SP]); |
| + writeCRLF() => writeBytes([_CharCode.CR, _CharCode.LF]); |
| // Write status line. |
| if (headers.protocolVersion == "1.1") { |
| - add(_Const.HTTP11); |
| + writeBytes(_Const.HTTP11); |
| } else { |
| - add(_Const.HTTP10); |
| + writeBytes(_Const.HTTP10); |
| } |
| writeSP(); |
| - addString(statusCode.toString()); |
| + write(statusCode.toString()); |
| writeSP(); |
| - addString(reasonPhrase); |
| + write(reasonPhrase); |
| writeCRLF(); |
| var session = _httpRequest._session; |
| @@ -648,10 +699,10 @@ class _HttpClientRequest extends _HttpOutboundMessage<HttpClientRequest> |
| } |
| void _writeHeader() { |
| - writeSP() => add([_CharCode.SP]); |
| - writeCRLF() => add([_CharCode.CR, _CharCode.LF]); |
| + writeSP() => writeBytes([_CharCode.SP]); |
| + writeCRLF() => writeBytes([_CharCode.CR, _CharCode.LF]); |
| - addString(method); |
| + write(method); |
| writeSP(); |
| // Send the path for direct connections and the whole URL for |
| // proxy connections. |
| @@ -665,12 +716,12 @@ class _HttpClientRequest extends _HttpOutboundMessage<HttpClientRequest> |
| path = "${path}?${uri.query}"; |
| } |
| } |
| - addString(path); |
| + write(path); |
| } else { |
| - addString(uri.toString()); |
| + write(uri.toString()); |
| } |
| writeSP(); |
| - add(_Const.HTTP11); |
| + writeBytes(_Const.HTTP11); |
| writeCRLF(); |
| // Add the cookies to the headers. |
| @@ -778,7 +829,8 @@ class _DataValidatorTransformer |
| _controller.signalError(new HttpException( |
| "Content size exceeds specified contentLength. " |
| "$_bytesWritten bytes written while expected " |
| - "$expectedTransferLength.")); |
| + "$expectedTransferLength. " |
| + "[${new String.fromCharCodes(data)}]")); |
| _controller.close(); |
| return; |
| } |
| @@ -1512,6 +1564,16 @@ class _DetachedSocket extends Stream<List<int>> implements Socket { |
| unsubscribeOnError: unsubscribeOnError); |
| } |
| + Encoding get encoding => _socket.encoding; |
| + void set encoding(Encoding value) => _socket.encoding = value; |
| + |
| + void write(Object obj) => _socket.write(obj); |
| + void writeln(Object obj) => _socket.writeln(obj); |
| + void writeCharCode(int charCode) => _socket.writeCharCode(charCode); |
| + void writeAll(Iterable objects) => _socket.writeAll(objects); |
| + |
|
Mads Ager (google)
2013/03/07 07:57:36
Nit: consistently have blank line between write me
Søren Gjesse
2013/03/07 16:28:47
Done.
|
| + void writeBytes(List<int> bytes) => _socket.writeBytes(bytes); |
| + |
| Future<Socket> consume(Stream<List<int>> stream) { |
| return _socket.consume(stream); |
| } |