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 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 Response.notModified({Map<String, String> headers, | 137 Response.notModified({Map<String, String> headers, |
138 Map<String, Object> context}) | 138 Map<String, Object> context}) |
139 : this(304, headers: _addHeader( | 139 : this(304, headers: _addHeader( |
140 headers, 'date', formatHttpDate(new DateTime.now())), | 140 headers, 'date', formatHttpDate(new DateTime.now())), |
141 context: context); | 141 context: context); |
142 | 142 |
143 /// Constructs a 403 Forbidden response. | 143 /// Constructs a 403 Forbidden response. |
144 /// | 144 /// |
145 /// This indicates that the server is refusing to fulfill the request. | 145 /// This indicates that the server is refusing to fulfill the request. |
146 /// | 146 /// |
147 /// [body] is the response body. It may be either a [String], a | 147 /// [body] is the response body. It may be a [String], a [Stream<List<int>>], |
148 /// [Stream<List<int>>], or `null` to indicate no body. If it's a [String], | 148 /// or `null`. If it's a [String], [encoding] is used to encode it to a |
149 /// [encoding] is used to encode it to a [Stream<List<int>>]. It defaults to | 149 /// [Stream<List<int>>]. The default encoding is UTF-8. If it's `null` or not |
150 /// UTF-8. | 150 /// passed, a default error message is used. |
151 /// | 151 /// |
152 /// If [encoding] is passed, the "encoding" field of the Content-Type header | 152 /// If [encoding] is passed, the "encoding" field of the Content-Type header |
153 /// in [headers] will be set appropriately. If there is no existing | 153 /// in [headers] will be set appropriately. If there is no existing |
154 /// Content-Type header, it will be set to "application/octet-stream". | 154 /// Content-Type header, it will be set to "application/octet-stream". |
155 Response.forbidden(body, {Map<String, String> headers, | 155 Response.forbidden(body, {Map<String, String> headers, |
156 Encoding encoding, Map<String, Object> context}) | 156 Encoding encoding, Map<String, Object> context}) |
157 : this(403, body: body, headers: headers, | 157 : this(403, |
| 158 headers: body == null ? _adjustErrorHeaders(headers) : headers, |
| 159 body: body == null ? 'Forbidden' : body, |
158 context: context); | 160 context: context); |
159 | 161 |
160 /// Constructs a 404 Not Found response. | 162 /// Constructs a 404 Not Found response. |
161 /// | 163 /// |
162 /// This indicates that the server didn't find any resource matching the | 164 /// This indicates that the server didn't find any resource matching the |
163 /// requested URI. | 165 /// requested URI. |
164 /// | 166 /// |
165 /// [body] is the response body. It may be either a [String], a | 167 /// [body] is the response body. It may be a [String], a [Stream<List<int>>], |
166 /// [Stream<List<int>>], or `null` to indicate no body. If it's a [String], | 168 /// or `null`. If it's a [String], [encoding] is used to encode it to a |
167 /// [encoding] is used to encode it to a [Stream<List<int>>]. It defaults to | 169 /// [Stream<List<int>>]. The default encoding is UTF-8. If it's `null` or not |
168 /// UTF-8. | 170 /// passed, a default error message is used. |
169 /// | 171 /// |
170 /// If [encoding] is passed, the "encoding" field of the Content-Type header | 172 /// If [encoding] is passed, the "encoding" field of the Content-Type header |
171 /// in [headers] will be set appropriately. If there is no existing | 173 /// in [headers] will be set appropriately. If there is no existing |
172 /// Content-Type header, it will be set to "application/octet-stream". | 174 /// Content-Type header, it will be set to "application/octet-stream". |
173 Response.notFound(body, {Map<String, String> headers, Encoding encoding, | 175 Response.notFound(body, {Map<String, String> headers, Encoding encoding, |
174 Map<String, Object> context}) | 176 Map<String, Object> context}) |
175 : this(404, body: body, headers: headers, | 177 : this(404, |
| 178 headers: body == null ? _adjustErrorHeaders(headers) : headers, |
| 179 body: body == null ? 'Not Found' : body, |
176 context: context); | 180 context: context); |
177 | 181 |
178 /// Constructs a 500 Internal Server Error response. | 182 /// Constructs a 500 Internal Server Error response. |
179 /// | 183 /// |
180 /// This indicates that the server had an internal error that prevented it | 184 /// This indicates that the server had an internal error that prevented it |
181 /// from fulfilling the request. | 185 /// from fulfilling the request. |
182 /// | 186 /// |
183 /// [body] is the response body. It may be either a [String], a | 187 /// [body] is the response body. It may be a [String], a [Stream<List<int>>], |
184 /// [Stream<List<int>>], or `null` to indicate no body. If it's `null` or not | 188 /// or `null`. If it's a [String], [encoding] is used to encode it to a |
185 /// passed, a default error message is used. If it's a [String], [encoding] is | 189 /// [Stream<List<int>>]. The default encoding is UTF-8. If it's `null` or not |
186 /// used to encode it to a [Stream<List<int>>]. It defaults to UTF-8. | 190 /// passed, a default error message is used. |
187 /// | 191 /// |
188 /// If [encoding] is passed, the "encoding" field of the Content-Type header | 192 /// If [encoding] is passed, the "encoding" field of the Content-Type header |
189 /// in [headers] will be set appropriately. If there is no existing | 193 /// in [headers] will be set appropriately. If there is no existing |
190 /// Content-Type header, it will be set to "application/octet-stream". | 194 /// Content-Type header, it will be set to "application/octet-stream". |
191 Response.internalServerError({body, Map<String, String> headers, | 195 Response.internalServerError({body, Map<String, String> headers, |
192 Encoding encoding, Map<String, Object> context}) | 196 Encoding encoding, Map<String, Object> context}) |
193 : this(500, | 197 : this(500, |
194 headers: body == null ? _adjust500Headers(headers) : headers, | 198 headers: body == null ? _adjustErrorHeaders(headers) : headers, |
195 body: body == null ? 'Internal Server Error' : body, | 199 body: body == null ? 'Internal Server Error' : body, |
196 context: context); | 200 context: context); |
197 | 201 |
198 /// Constructs an HTTP response with the given [statusCode]. | 202 /// Constructs an HTTP response with the given [statusCode]. |
199 /// | 203 /// |
200 /// [statusCode] must be greater than or equal to 100. | 204 /// [statusCode] must be greater than or equal to 100. |
201 /// | 205 /// |
202 /// [body] is the response body. It may be either a [String], a | 206 /// [body] is the response body. It may be either a [String], a |
203 /// [Stream<List<int>>], or `null` to indicate no body. If it's `null` or not | 207 /// [Stream<List<int>>], or `null` to indicate no body. |
204 /// passed, a default error message is used. If it's a [String], [encoding] is | 208 /// If it's a [String], [encoding] is used to encode it to a |
205 /// used to encode it to a [Stream<List<int>>]. It defaults to UTF-8. | 209 /// [Stream<List<int>>]. The default encoding is UTF-8. |
206 /// | 210 /// |
207 /// If [encoding] is passed, the "encoding" field of the Content-Type header | 211 /// If [encoding] is passed, the "encoding" field of the Content-Type header |
208 /// in [headers] will be set appropriately. If there is no existing | 212 /// in [headers] will be set appropriately. If there is no existing |
209 /// Content-Type header, it will be set to "application/octet-stream". | 213 /// Content-Type header, it will be set to "application/octet-stream". |
210 Response(this.statusCode, {body, Map<String, String> headers, | 214 Response(this.statusCode, {body, Map<String, String> headers, |
211 Encoding encoding, Map<String, Object> context}) | 215 Encoding encoding, Map<String, Object> context}) |
212 : super(_bodyToStream(body, encoding), | 216 : super(_bodyToStream(body, encoding), |
213 headers: _adjustHeaders(headers, encoding), | 217 headers: _adjustHeaders(headers, encoding), |
214 context: context) { | 218 context: context) { |
215 if (statusCode < 100) { | 219 if (statusCode < 100) { |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
276 String value) { | 280 String value) { |
277 headers = headers == null ? {} : new Map.from(headers); | 281 headers = headers == null ? {} : new Map.from(headers); |
278 headers[name] = value; | 282 headers[name] = value; |
279 return headers; | 283 return headers; |
280 } | 284 } |
281 | 285 |
282 /// Adds content-type information to [headers]. | 286 /// Adds content-type information to [headers]. |
283 /// | 287 /// |
284 /// Returns a new map without modifying [headers]. This is used to add | 288 /// Returns a new map without modifying [headers]. This is used to add |
285 /// content-type information when creating a 500 response with a default body. | 289 /// content-type information when creating a 500 response with a default body. |
286 Map<String, String> _adjust500Headers(Map<String, String> headers) { | 290 Map<String, String> _adjustErrorHeaders(Map<String, String> headers) { |
287 if (headers == null || headers['content-type'] == null) { | 291 if (headers == null || headers['content-type'] == null) { |
288 return _addHeader(headers, 'content-type', 'text/plain'); | 292 return _addHeader(headers, 'content-type', 'text/plain'); |
289 } | 293 } |
290 | 294 |
291 var contentType = new MediaType.parse(headers['content-type']) | 295 var contentType = new MediaType.parse(headers['content-type']) |
292 .change(mimeType: 'text/plain'); | 296 .change(mimeType: 'text/plain'); |
293 return _addHeader(headers, 'content-type', contentType.toString()); | 297 return _addHeader(headers, 'content-type', contentType.toString()); |
294 } | 298 } |
295 | 299 |
296 /// Converts [location], which may be a [String] or a [Uri], to a [String]. | 300 /// Converts [location], which may be a [String] or a [Uri], to a [String]. |
297 /// | 301 /// |
298 /// Throws an [ArgumentError] if [location] isn't a [String] or a [Uri]. | 302 /// Throws an [ArgumentError] if [location] isn't a [String] or a [Uri]. |
299 String _locationToString(location) { | 303 String _locationToString(location) { |
300 if (location is String) return location; | 304 if (location is String) return location; |
301 if (location is Uri) return location.toString(); | 305 if (location is Uri) return location.toString(); |
302 | 306 |
303 throw new ArgumentError('Response location must be a String or Uri, was ' | 307 throw new ArgumentError('Response location must be a String or Uri, was ' |
304 '"$location".'); | 308 '"$location".'); |
305 } | 309 } |
OLD | NEW |