| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 library shelf.message; | 5 library shelf.message; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:convert'; | 8 import 'dart:convert'; |
| 9 | 9 |
| 10 import 'package:http_parser/http_parser.dart'; | 10 import 'package:http_parser/http_parser.dart'; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 /// since it's in the `shelf` package. | 30 /// since it's in the `shelf` package. |
| 31 /// | 31 /// |
| 32 /// The value is immutable. | 32 /// The value is immutable. |
| 33 final Map<String, Object> context; | 33 final Map<String, Object> context; |
| 34 | 34 |
| 35 /// The streaming body of the message. | 35 /// The streaming body of the message. |
| 36 /// | 36 /// |
| 37 /// This can be read via [read] or [readAsString]. | 37 /// This can be read via [read] or [readAsString]. |
| 38 final Stream<List<int>> _body; | 38 final Stream<List<int>> _body; |
| 39 | 39 |
| 40 /// This boolean indicates whether [_body] has been read. |
| 41 /// |
| 42 /// After calling [read], or [readAsString] (which internally calls [read]), |
| 43 /// this will be `true`. |
| 44 bool _bodyWasRead = false; |
| 45 |
| 40 /// Creates a new [Message]. | 46 /// Creates a new [Message]. |
| 41 /// | 47 /// |
| 42 /// If [headers] is `null`, it is treated as empty. | 48 /// If [headers] is `null`, it is treated as empty. |
| 43 Message(this._body, {Map<String, String> headers, | 49 Message(this._body, {Map<String, String> headers, |
| 44 Map<String, Object> context}) | 50 Map<String, Object> context}) |
| 45 : this.headers = new ShelfUnmodifiableMap<String>(headers, | 51 : this.headers = new ShelfUnmodifiableMap<String>(headers, |
| 46 ignoreKeyCase: true), | 52 ignoreKeyCase: true), |
| 47 this.context = new ShelfUnmodifiableMap<Object>(context, | 53 this.context = new ShelfUnmodifiableMap<Object>(context, |
| 48 ignoreKeyCase: false); | 54 ignoreKeyCase: false); |
| 49 | 55 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 if (_contentTypeCache != null) return _contentTypeCache; | 97 if (_contentTypeCache != null) return _contentTypeCache; |
| 92 if (!headers.containsKey('content-type')) return null; | 98 if (!headers.containsKey('content-type')) return null; |
| 93 _contentTypeCache = new MediaType.parse(headers['content-type']); | 99 _contentTypeCache = new MediaType.parse(headers['content-type']); |
| 94 return _contentTypeCache; | 100 return _contentTypeCache; |
| 95 } | 101 } |
| 96 MediaType _contentTypeCache; | 102 MediaType _contentTypeCache; |
| 97 | 103 |
| 98 /// Returns a [Stream] representing the body. | 104 /// Returns a [Stream] representing the body. |
| 99 /// | 105 /// |
| 100 /// Can only be called once. | 106 /// Can only be called once. |
| 101 Stream<List<int>> read() => _body; | 107 Stream<List<int>> read() { |
| 108 if (_bodyWasRead) { |
| 109 throw new StateError("The 'read' method can only be called once on a " |
| 110 "shelf.Request/shelf.Response object."); |
| 111 } |
| 112 _bodyWasRead = true; |
| 113 return _body; |
| 114 } |
| 102 | 115 |
| 103 /// Returns a [Future] containing the body as a String. | 116 /// Returns a [Future] containing the body as a String. |
| 104 /// | 117 /// |
| 105 /// If [encoding] is passed, that's used to decode the body. | 118 /// If [encoding] is passed, that's used to decode the body. |
| 106 /// Otherwise the encoding is taken from the Content-Type header. If that | 119 /// Otherwise the encoding is taken from the Content-Type header. If that |
| 107 /// doesn't exist or doesn't have a "charset" parameter, UTF-8 is used. | 120 /// doesn't exist or doesn't have a "charset" parameter, UTF-8 is used. |
| 108 /// | 121 /// |
| 109 /// This calls [read] internally, which can only be called once. | 122 /// This calls [read] internally, which can only be called once. |
| 110 Future<String> readAsString([Encoding encoding]) { | 123 Future<String> readAsString([Encoding encoding]) { |
| 111 if (encoding == null) encoding = this.encoding; | 124 if (encoding == null) encoding = this.encoding; |
| 112 if (encoding == null) encoding = UTF8; | 125 if (encoding == null) encoding = UTF8; |
| 113 return Chain.track(encoding.decodeStream(read())); | 126 return Chain.track(encoding.decodeStream(read())); |
| 114 } | 127 } |
| 115 | 128 |
| 116 /// Creates a new [Message] by copying existing values and applying specified | 129 /// Creates a new [Message] by copying existing values and applying specified |
| 117 /// changes. | 130 /// changes. |
| 118 Message change({Map<String, String> headers, Map<String, Object> context}); | 131 Message change({Map<String, String> headers, Map<String, Object> context}); |
| 119 } | 132 } |
| OLD | NEW |