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.response; | 5 library shelf.response; |
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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 /// This indicates that the request has succeeded. | 46 /// This indicates that the request has succeeded. |
47 /// | 47 /// |
48 /// [body] is the response body. It may be either a [String], a | 48 /// [body] is the response body. It may be either a [String], a |
49 /// [Stream<List<int>>], or `null` to indicate no body. If it's a [String], | 49 /// [Stream<List<int>>], or `null` to indicate no body. If it's a [String], |
50 /// [encoding] is used to encode it to a [Stream<List<int>>]. It defaults to | 50 /// [encoding] is used to encode it to a [Stream<List<int>>]. It defaults to |
51 /// UTF-8. | 51 /// UTF-8. |
52 /// | 52 /// |
53 /// If [encoding] is passed, the "encoding" field of the Content-Type header | 53 /// If [encoding] is passed, the "encoding" field of the Content-Type header |
54 /// in [headers] will be set appropriately. If there is no existing | 54 /// in [headers] will be set appropriately. If there is no existing |
55 /// Content-Type header, it will be set to "application/octet-stream". | 55 /// Content-Type header, it will be set to "application/octet-stream". |
56 Response.ok(body, {Map<String, String> headers, Encoding encoding}) | 56 Response.ok(body, {Map<String, String> headers, Encoding encoding, |
57 : this(200, body: body, headers: headers, encoding: encoding); | 57 Map<String, Object> context}) |
| 58 : this(200, body: body, headers: headers, encoding: encoding, |
| 59 context: context); |
58 | 60 |
59 /// Constructs a 301 Moved Permanently response. | 61 /// Constructs a 301 Moved Permanently response. |
60 /// | 62 /// |
61 /// This indicates that the requested resource has moved permanently to a new | 63 /// This indicates that the requested resource has moved permanently to a new |
62 /// URI. [location] is that URI; it can be either a [String] or a [Uri]. It's | 64 /// URI. [location] is that URI; it can be either a [String] or a [Uri]. It's |
63 /// automatically set as the Location header in [headers]. | 65 /// automatically set as the Location header in [headers]. |
64 /// | 66 /// |
65 /// [body] is the response body. It may be either a [String], a | 67 /// [body] is the response body. It may be either a [String], a |
66 /// [Stream<List<int>>], or `null` to indicate no body. If it's a [String], | 68 /// [Stream<List<int>>], or `null` to indicate no body. If it's a [String], |
67 /// [encoding] is used to encode it to a [Stream<List<int>>]. It defaults to | 69 /// [encoding] is used to encode it to a [Stream<List<int>>]. It defaults to |
68 /// UTF-8. | 70 /// UTF-8. |
69 /// | 71 /// |
70 /// If [encoding] is passed, the "encoding" field of the Content-Type header | 72 /// If [encoding] is passed, the "encoding" field of the Content-Type header |
71 /// in [headers] will be set appropriately. If there is no existing | 73 /// in [headers] will be set appropriately. If there is no existing |
72 /// Content-Type header, it will be set to "application/octet-stream". | 74 /// Content-Type header, it will be set to "application/octet-stream". |
73 Response.movedPermanently(location, {body, Map<String, String> headers, | 75 Response.movedPermanently(location, {body, Map<String, String> headers, |
74 Encoding encoding}) | 76 Encoding encoding, Map<String, Object> context}) |
75 : this._redirect(301, location, body, headers, encoding); | 77 : this._redirect(301, location, body, headers, encoding, |
| 78 context: context); |
76 | 79 |
77 /// Constructs a 302 Found response. | 80 /// Constructs a 302 Found response. |
78 /// | 81 /// |
79 /// This indicates that the requested resource has moved temporarily to a new | 82 /// This indicates that the requested resource has moved temporarily to a new |
80 /// URI. [location] is that URI; it can be either a [String] or a [Uri]. It's | 83 /// URI. [location] is that URI; it can be either a [String] or a [Uri]. It's |
81 /// automatically set as the Location header in [headers]. | 84 /// automatically set as the Location header in [headers]. |
82 /// | 85 /// |
83 /// [body] is the response body. It may be either a [String], a | 86 /// [body] is the response body. It may be either a [String], a |
84 /// [Stream<List<int>>], or `null` to indicate no body. If it's a [String], | 87 /// [Stream<List<int>>], or `null` to indicate no body. If it's a [String], |
85 /// [encoding] is used to encode it to a [Stream<List<int>>]. It defaults to | 88 /// [encoding] is used to encode it to a [Stream<List<int>>]. It defaults to |
86 /// UTF-8. | 89 /// UTF-8. |
87 /// | 90 /// |
88 /// If [encoding] is passed, the "encoding" field of the Content-Type header | 91 /// If [encoding] is passed, the "encoding" field of the Content-Type header |
89 /// in [headers] will be set appropriately. If there is no existing | 92 /// in [headers] will be set appropriately. If there is no existing |
90 /// Content-Type header, it will be set to "application/octet-stream". | 93 /// Content-Type header, it will be set to "application/octet-stream". |
91 Response.found(location, {body, Map<String, String> headers, | 94 Response.found(location, {body, Map<String, String> headers, |
92 Encoding encoding}) | 95 Encoding encoding, Map<String, Object> context}) |
93 : this._redirect(302, location, body, headers, encoding); | 96 : this._redirect(302, location, body, headers, encoding, |
| 97 context: context); |
94 | 98 |
95 /// Constructs a 303 See Other response. | 99 /// Constructs a 303 See Other response. |
96 /// | 100 /// |
97 /// This indicates that the response to the request should be retrieved using | 101 /// This indicates that the response to the request should be retrieved using |
98 /// a GET request to a new URI. [location] is that URI; it can be either a | 102 /// a GET request to a new URI. [location] is that URI; it can be either a |
99 /// [String] or a [Uri]. It's automatically set as the Location header in | 103 /// [String] or a [Uri]. It's automatically set as the Location header in |
100 /// [headers]. | 104 /// [headers]. |
101 /// | 105 /// |
102 /// [body] is the response body. It may be either a [String], a | 106 /// [body] is the response body. It may be either a [String], a |
103 /// [Stream<List<int>>], or `null` to indicate no body. If it's a [String], | 107 /// [Stream<List<int>>], or `null` to indicate no body. If it's a [String], |
104 /// [encoding] is used to encode it to a [Stream<List<int>>]. It defaults to | 108 /// [encoding] is used to encode it to a [Stream<List<int>>]. It defaults to |
105 /// UTF-8. | 109 /// UTF-8. |
106 /// | 110 /// |
107 /// If [encoding] is passed, the "encoding" field of the Content-Type header | 111 /// If [encoding] is passed, the "encoding" field of the Content-Type header |
108 /// in [headers] will be set appropriately. If there is no existing | 112 /// in [headers] will be set appropriately. If there is no existing |
109 /// Content-Type header, it will be set to "application/octet-stream". | 113 /// Content-Type header, it will be set to "application/octet-stream". |
110 Response.seeOther(location, {body, Map<String, String> headers, | 114 Response.seeOther(location, {body, Map<String, String> headers, |
111 Encoding encoding}) | 115 Encoding encoding, Map<String, Object> context}) |
112 : this._redirect(303, location, body, headers, encoding); | 116 : this._redirect(303, location, body, headers, encoding, |
| 117 context: context); |
113 | 118 |
114 /// Constructs a helper constructor for redirect responses. | 119 /// Constructs a helper constructor for redirect responses. |
115 Response._redirect(int statusCode, location, body, | 120 Response._redirect(int statusCode, location, body, |
116 Map<String, String> headers, Encoding encoding) | 121 Map<String, String> headers, Encoding encoding, |
| 122 { Map<String, Object> context }) |
117 : this(statusCode, | 123 : this(statusCode, |
118 body: body, | 124 body: body, |
119 encoding: encoding, | 125 encoding: encoding, |
120 headers: _addHeader( | 126 headers: _addHeader( |
121 headers, 'location', _locationToString(location))); | 127 headers, 'location', _locationToString(location)), |
| 128 context: context); |
122 | 129 |
123 /// Constructs a 304 Not Modified response. | 130 /// Constructs a 304 Not Modified response. |
124 /// | 131 /// |
125 /// This is used to respond to a conditional GET request that provided | 132 /// This is used to respond to a conditional GET request that provided |
126 /// information used to determine whether the requested resource has changed | 133 /// information used to determine whether the requested resource has changed |
127 /// since the last request. It indicates that the resource has not changed and | 134 /// since the last request. It indicates that the resource has not changed and |
128 /// the old value should be used. | 135 /// the old value should be used. |
129 Response.notModified({Map<String, String> headers}) | 136 Response.notModified({Map<String, String> headers, |
| 137 Map<String, Object> context}) |
130 : this(304, headers: _addHeader( | 138 : this(304, headers: _addHeader( |
131 headers, 'date', formatHttpDate(new DateTime.now()))); | 139 headers, 'date', formatHttpDate(new DateTime.now())), |
| 140 context: context); |
132 | 141 |
133 /// Constructs a 403 Forbidden response. | 142 /// Constructs a 403 Forbidden response. |
134 /// | 143 /// |
135 /// This indicates that the server is refusing to fulfill the request. | 144 /// This indicates that the server is refusing to fulfill the request. |
136 /// | 145 /// |
137 /// [body] is the response body. It may be either a [String], a | 146 /// [body] is the response body. It may be either a [String], a |
138 /// [Stream<List<int>>], or `null` to indicate no body. If it's a [String], | 147 /// [Stream<List<int>>], or `null` to indicate no body. If it's a [String], |
139 /// [encoding] is used to encode it to a [Stream<List<int>>]. It defaults to | 148 /// [encoding] is used to encode it to a [Stream<List<int>>]. It defaults to |
140 /// UTF-8. | 149 /// UTF-8. |
141 /// | 150 /// |
142 /// If [encoding] is passed, the "encoding" field of the Content-Type header | 151 /// If [encoding] is passed, the "encoding" field of the Content-Type header |
143 /// in [headers] will be set appropriately. If there is no existing | 152 /// in [headers] will be set appropriately. If there is no existing |
144 /// Content-Type header, it will be set to "application/octet-stream". | 153 /// Content-Type header, it will be set to "application/octet-stream". |
145 Response.forbidden(body, {Map<String, String> headers, | 154 Response.forbidden(body, {Map<String, String> headers, |
146 Encoding encoding}) | 155 Encoding encoding, Map<String, Object> context}) |
147 : this(403, body: body, headers: headers); | 156 : this(403, body: body, headers: headers, |
| 157 context: context); |
148 | 158 |
149 /// Constructs a 404 Not Found response. | 159 /// Constructs a 404 Not Found response. |
150 /// | 160 /// |
151 /// This indicates that the server didn't find any resource matching the | 161 /// This indicates that the server didn't find any resource matching the |
152 /// requested URI. | 162 /// requested URI. |
153 /// | 163 /// |
154 /// [body] is the response body. It may be either a [String], a | 164 /// [body] is the response body. It may be either a [String], a |
155 /// [Stream<List<int>>], or `null` to indicate no body. If it's a [String], | 165 /// [Stream<List<int>>], or `null` to indicate no body. If it's a [String], |
156 /// [encoding] is used to encode it to a [Stream<List<int>>]. It defaults to | 166 /// [encoding] is used to encode it to a [Stream<List<int>>]. It defaults to |
157 /// UTF-8. | 167 /// UTF-8. |
158 /// | 168 /// |
159 /// If [encoding] is passed, the "encoding" field of the Content-Type header | 169 /// If [encoding] is passed, the "encoding" field of the Content-Type header |
160 /// in [headers] will be set appropriately. If there is no existing | 170 /// in [headers] will be set appropriately. If there is no existing |
161 /// Content-Type header, it will be set to "application/octet-stream". | 171 /// Content-Type header, it will be set to "application/octet-stream". |
162 Response.notFound(body, {Map<String, String> headers, Encoding encoding}) | 172 Response.notFound(body, {Map<String, String> headers, Encoding encoding, |
163 : this(404, body: body, headers: headers); | 173 Map<String, Object> context}) |
| 174 : this(404, body: body, headers: headers, |
| 175 context: context); |
164 | 176 |
165 /// Constructs a 500 Internal Server Error response. | 177 /// Constructs a 500 Internal Server Error response. |
166 /// | 178 /// |
167 /// This indicates that the server had an internal error that prevented it | 179 /// This indicates that the server had an internal error that prevented it |
168 /// from fulfilling the request. | 180 /// from fulfilling the request. |
169 /// | 181 /// |
170 /// [body] is the response body. It may be either a [String], a | 182 /// [body] is the response body. It may be either a [String], a |
171 /// [Stream<List<int>>], or `null` to indicate no body. If it's `null` or not | 183 /// [Stream<List<int>>], or `null` to indicate no body. If it's `null` or not |
172 /// passed, a default error message is used. If it's a [String], [encoding] is | 184 /// passed, a default error message is used. If it's a [String], [encoding] is |
173 /// used to encode it to a [Stream<List<int>>]. It defaults to UTF-8. | 185 /// used to encode it to a [Stream<List<int>>]. It defaults to UTF-8. |
174 /// | 186 /// |
175 /// If [encoding] is passed, the "encoding" field of the Content-Type header | 187 /// If [encoding] is passed, the "encoding" field of the Content-Type header |
176 /// in [headers] will be set appropriately. If there is no existing | 188 /// in [headers] will be set appropriately. If there is no existing |
177 /// Content-Type header, it will be set to "application/octet-stream". | 189 /// Content-Type header, it will be set to "application/octet-stream". |
178 Response.internalServerError({body, Map<String, String> headers, | 190 Response.internalServerError({body, Map<String, String> headers, |
179 Encoding encoding}) | 191 Encoding encoding, Map<String, Object> context}) |
180 : this(500, | 192 : this(500, |
181 headers: body == null ? _adjust500Headers(headers) : headers, | 193 headers: body == null ? _adjust500Headers(headers) : headers, |
182 body: body == null ? 'Internal Server Error' : body); | 194 body: body == null ? 'Internal Server Error' : body, |
| 195 context: context); |
183 | 196 |
184 /// Constructs an HTTP response with the given [statusCode]. | 197 /// Constructs an HTTP response with the given [statusCode]. |
185 /// | 198 /// |
186 /// [statusCode] must be greater than or equal to 100. | 199 /// [statusCode] must be greater than or equal to 100. |
187 /// | 200 /// |
188 /// [body] is the response body. It may be either a [String], a | 201 /// [body] is the response body. It may be either a [String], a |
189 /// [Stream<List<int>>], or `null` to indicate no body. If it's `null` or not | 202 /// [Stream<List<int>>], or `null` to indicate no body. If it's `null` or not |
190 /// passed, a default error message is used. If it's a [String], [encoding] is | 203 /// passed, a default error message is used. If it's a [String], [encoding] is |
191 /// used to encode it to a [Stream<List<int>>]. It defaults to UTF-8. | 204 /// used to encode it to a [Stream<List<int>>]. It defaults to UTF-8. |
192 /// | 205 /// |
193 /// If [encoding] is passed, the "encoding" field of the Content-Type header | 206 /// If [encoding] is passed, the "encoding" field of the Content-Type header |
194 /// in [headers] will be set appropriately. If there is no existing | 207 /// in [headers] will be set appropriately. If there is no existing |
195 /// Content-Type header, it will be set to "application/octet-stream". | 208 /// Content-Type header, it will be set to "application/octet-stream". |
196 Response(this.statusCode, {body, Map<String, String> headers, | 209 Response(this.statusCode, {body, Map<String, String> headers, |
197 Encoding encoding}) | 210 Encoding encoding, Map<String, Object> context}) |
198 : super(_bodyToStream(body, encoding), | 211 : super(_bodyToStream(body, encoding), |
199 headers: _adjustHeaders(headers, encoding)) { | 212 headers: _adjustHeaders(headers, encoding), |
| 213 context: context) { |
200 if (statusCode < 100) { | 214 if (statusCode < 100) { |
201 throw new ArgumentError("Invalid status code: $statusCode."); | 215 throw new ArgumentError("Invalid status code: $statusCode."); |
202 } | 216 } |
203 } | 217 } |
204 } | 218 } |
205 | 219 |
206 /// Converts [body] to a byte stream. | 220 /// Converts [body] to a byte stream. |
207 /// | 221 /// |
208 /// [body] may be either a [String], a [Stream<List<int>>], or `null`. If it's a | 222 /// [body] may be either a [String], a [Stream<List<int>>], or `null`. If it's a |
209 /// [String], [encoding] will be used to convert it to a [Stream<List<int>>]. | 223 /// [String], [encoding] will be used to convert it to a [Stream<List<int>>]. |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
261 /// Converts [location], which may be a [String] or a [Uri], to a [String]. | 275 /// Converts [location], which may be a [String] or a [Uri], to a [String]. |
262 /// | 276 /// |
263 /// Throws an [ArgumentError] if [location] isn't a [String] or a [Uri]. | 277 /// Throws an [ArgumentError] if [location] isn't a [String] or a [Uri]. |
264 String _locationToString(location) { | 278 String _locationToString(location) { |
265 if (location is String) return location; | 279 if (location is String) return location; |
266 if (location is Uri) return location.toString(); | 280 if (location is Uri) return location.toString(); |
267 | 281 |
268 throw new ArgumentError('Response location must be a String or Uri, was ' | 282 throw new ArgumentError('Response location must be a String or Uri, was ' |
269 '"$location".'); | 283 '"$location".'); |
270 } | 284 } |
OLD | NEW |