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 28 matching lines...) Expand all Loading... |
39 | 39 |
40 /// This boolean indicates whether [_body] has been read. | 40 /// This boolean indicates whether [_body] has been read. |
41 /// | 41 /// |
42 /// After calling [read], or [readAsString] (which internally calls [read]), | 42 /// After calling [read], or [readAsString] (which internally calls [read]), |
43 /// this will be `true`. | 43 /// this will be `true`. |
44 bool _bodyWasRead = false; | 44 bool _bodyWasRead = false; |
45 | 45 |
46 /// Creates a new [Message]. | 46 /// Creates a new [Message]. |
47 /// | 47 /// |
48 /// If [headers] is `null`, it is treated as empty. | 48 /// If [headers] is `null`, it is treated as empty. |
49 Message(this._body, {Map<String, String> headers, | 49 Message(this._body, |
50 Map<String, Object> context}) | 50 {Map<String, String> headers, Map<String, Object> context}) |
51 : this.headers = new ShelfUnmodifiableMap<String>(headers, | 51 : this.headers = new ShelfUnmodifiableMap<String>(headers, |
52 ignoreKeyCase: true), | 52 ignoreKeyCase: true), |
53 this.context = new ShelfUnmodifiableMap<Object>(context, | 53 this.context = new ShelfUnmodifiableMap<Object>(context, |
54 ignoreKeyCase: false); | 54 ignoreKeyCase: false); |
55 | 55 |
56 /// The contents of the content-length field in [headers]. | 56 /// The contents of the content-length field in [headers]. |
57 /// | 57 /// |
58 /// If not set, `null`. | 58 /// If not set, `null`. |
59 int get contentLength { | 59 int get contentLength { |
60 if (_contentLengthCache != null) return _contentLengthCache; | 60 if (_contentLengthCache != null) return _contentLengthCache; |
61 if (!headers.containsKey('content-length')) return null; | 61 if (!headers.containsKey('content-length')) return null; |
62 _contentLengthCache = int.parse(headers['content-length']); | 62 _contentLengthCache = int.parse(headers['content-length']); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 return _contentTypeCache; | 100 return _contentTypeCache; |
101 } | 101 } |
102 MediaType _contentTypeCache; | 102 MediaType _contentTypeCache; |
103 | 103 |
104 /// Returns a [Stream] representing the body. | 104 /// Returns a [Stream] representing the body. |
105 /// | 105 /// |
106 /// Can only be called once. | 106 /// Can only be called once. |
107 Stream<List<int>> read() { | 107 Stream<List<int>> read() { |
108 if (_bodyWasRead) { | 108 if (_bodyWasRead) { |
109 throw new StateError("The 'read' method can only be called once on a " | 109 throw new StateError("The 'read' method can only be called once on a " |
110 "shelf.Request/shelf.Response object."); | 110 "shelf.Request/shelf.Response object."); |
111 } | 111 } |
112 _bodyWasRead = true; | 112 _bodyWasRead = true; |
113 return _body; | 113 return _body; |
114 } | 114 } |
115 | 115 |
116 /// Returns a [Future] containing the body as a String. | 116 /// Returns a [Future] containing the body as a String. |
117 /// | 117 /// |
118 /// If [encoding] is passed, that's used to decode the body. | 118 /// If [encoding] is passed, that's used to decode the body. |
119 /// 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 |
120 /// 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. |
121 /// | 121 /// |
122 /// This calls [read] internally, which can only be called once. | 122 /// This calls [read] internally, which can only be called once. |
123 Future<String> readAsString([Encoding encoding]) { | 123 Future<String> readAsString([Encoding encoding]) { |
124 if (encoding == null) encoding = this.encoding; | 124 if (encoding == null) encoding = this.encoding; |
125 if (encoding == null) encoding = UTF8; | 125 if (encoding == null) encoding = UTF8; |
126 return Chain.track(encoding.decodeStream(read())); | 126 return Chain.track(encoding.decodeStream(read())); |
127 } | 127 } |
128 | 128 |
129 /// Creates a new [Message] by copying existing values and applying specified | 129 /// Creates a new [Message] by copying existing values and applying specified |
130 /// changes. | 130 /// changes. |
131 Message change({Map<String, String> headers, Map<String, Object> context}); | 131 Message change({Map<String, String> headers, Map<String, Object> context}); |
132 } | 132 } |
OLD | NEW |