Index: lib/src/message.dart |
diff --git a/lib/src/message.dart b/lib/src/message.dart |
index ba5c5fa5441d22853f3a21ffc03a616141d81fba..db420d671fe52a85cd8f35c63564822962014e90 100644 |
--- a/lib/src/message.dart |
+++ b/lib/src/message.dart |
@@ -11,6 +11,7 @@ import 'package:http_parser/http_parser.dart'; |
import 'package:stack_trace/stack_trace.dart'; |
import 'shelf_unmodifiable_map.dart'; |
+import 'util.dart'; |
/// Represents logic shared between [Request] and [Response]. |
abstract class Message { |
@@ -45,11 +46,21 @@ abstract class Message { |
/// Creates a new [Message]. |
/// |
+ /// [body] is the response body. It may be either a [String], a |
+ /// [Stream<List<int>>], or `null` to indicate no body. If it's a [String], |
+ /// [encoding] is used to encode it to a [Stream<List<int>>]. It defaults to |
+ /// UTF-8. |
+ /// |
/// If [headers] is `null`, it is treated as empty. |
- Message(this._body, |
- {Map<String, String> headers, Map<String, Object> context}) |
- : this.headers = new ShelfUnmodifiableMap<String>(headers, |
- ignoreKeyCase: true), |
+ /// |
+ /// If [encoding] is passed, the "encoding" field of the Content-Type header |
+ /// in [headers] will be set appropriately. If there is no existing |
+ /// Content-Type header, it will be set to "application/octet-stream". |
+ Message(body, {Encoding encoding, Map<String, String> headers, |
+ Map<String, Object> context}) |
+ : this._body = _bodyToStream(body, encoding), |
+ this.headers = new ShelfUnmodifiableMap<String>( |
+ _adjustHeaders(headers, encoding), ignoreKeyCase: true), |
this.context = new ShelfUnmodifiableMap<Object>(context, |
ignoreKeyCase: false); |
@@ -130,3 +141,34 @@ abstract class Message { |
/// changes. |
Message change({Map<String, String> headers, Map<String, Object> context}); |
} |
+ |
+/// Converts [body] to a byte stream. |
+/// |
+/// [body] may be either a [String], a [Stream<List<int>>], or `null`. If it's a |
+/// [String], [encoding] will be used to convert it to a [Stream<List<int>>]. |
+Stream<List<int>> _bodyToStream(body, Encoding encoding) { |
+ if (encoding == null) encoding = UTF8; |
+ if (body == null) return new Stream.fromIterable([]); |
+ if (body is String) return new Stream.fromIterable([encoding.encode(body)]); |
+ if (body is Stream) return body; |
+ |
+ throw new ArgumentError('Response body "$body" must be a String or a ' |
+ 'Stream.'); |
+} |
+ |
+/// Adds information about [encoding] to [headers]. |
+/// |
+/// Returns a new map without modifying [headers]. |
+Map<String, String> _adjustHeaders( |
+ Map<String, String> headers, Encoding encoding) { |
+ if (headers == null) headers = const {}; |
+ if (encoding == null) return headers; |
+ if (headers['content-type'] == null) { |
+ return addHeader(headers, 'content-type', |
+ 'application/octet-stream; charset=${encoding.name}'); |
+ } |
+ |
+ var contentType = new MediaType.parse(headers['content-type']).change( |
+ parameters: {'charset': encoding.name}); |
+ return addHeader(headers, 'content-type', contentType.toString()); |
+} |