Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(695)

Side by Side Diff: pkg/shelf/lib/src/response.dart

Issue 227563010: pkg/shelf: case-insensitive headers, cleaner Request ctor, a lot more tests (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: fixing dependent code, changelog Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « pkg/shelf/lib/src/request.dart ('k') | pkg/shelf/pubspec.yaml » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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:collection/wrappers.dart';
11 import 'package:http_parser/http_parser.dart'; 10 import 'package:http_parser/http_parser.dart';
12 11
13 import 'message.dart'; 12 import 'message.dart';
14 13
15 /// The response returned by a [Handler]. 14 /// The response returned by a [Handler].
16 class Response extends Message { 15 class Response extends Message {
17 /// The HTTP status code of the response. 16 /// The HTTP status code of the response.
18 final int statusCode; 17 final int statusCode;
19 18
20 /// The date and time after which the response's data should be considered 19 /// The date and time after which the response's data should be considered
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 /// [body] is the response body. It may be either a [String], a 188 /// [body] is the response body. It may be either a [String], a
190 /// [Stream<List<int>>], or `null` to indicate no body. If it's `null` or not 189 /// [Stream<List<int>>], or `null` to indicate no body. If it's `null` or not
191 /// passed, a default error message is used. If it's a [String], [encoding] is 190 /// passed, a default error message is used. If it's a [String], [encoding] is
192 /// used to encode it to a [Stream<List<int>>]. It defaults to UTF-8. 191 /// used to encode it to a [Stream<List<int>>]. It defaults to UTF-8.
193 /// 192 ///
194 /// If [encoding] is passed, the "encoding" field of the Content-Type header 193 /// If [encoding] is passed, the "encoding" field of the Content-Type header
195 /// in [headers] will be set appropriately. If there is no existing 194 /// in [headers] will be set appropriately. If there is no existing
196 /// Content-Type header, it will be set to "application/octet-stream". 195 /// Content-Type header, it will be set to "application/octet-stream".
197 Response(this.statusCode, {body, Map<String, String> headers, 196 Response(this.statusCode, {body, Map<String, String> headers,
198 Encoding encoding}) 197 Encoding encoding})
199 : super(_adjustHeaders(headers, encoding), 198 : super(_bodyToStream(body, encoding),
200 _bodyToStream(body, encoding)) { 199 headers: _adjustHeaders(headers, encoding)) {
201 if (statusCode < 100) { 200 if (statusCode < 100) {
202 throw new ArgumentError("Invalid status code: $statusCode."); 201 throw new ArgumentError("Invalid status code: $statusCode.");
203 } 202 }
204 } 203 }
205 } 204 }
206 205
207 /// Converts [body] to a byte stream. 206 /// Converts [body] to a byte stream.
208 /// 207 ///
209 /// [body] may be either a [String], a [Stream<List<int>>], or `null`. If it's a 208 /// [body] may be either a [String], a [Stream<List<int>>], or `null`. If it's a
210 /// [String], [encoding] will be used to convert it to a [Stream<List<int>>]. 209 /// [String], [encoding] will be used to convert it to a [Stream<List<int>>].
211 Stream<List<int>> _bodyToStream(body, Encoding encoding) { 210 Stream<List<int>> _bodyToStream(body, Encoding encoding) {
212 if (encoding == null) encoding = UTF8; 211 if (encoding == null) encoding = UTF8;
213 if (body == null) return new Stream.fromIterable([]); 212 if (body == null) return new Stream.fromIterable([]);
214 if (body is String) return new Stream.fromIterable([encoding.encode(body)]); 213 if (body is String) return new Stream.fromIterable([encoding.encode(body)]);
215 if (body is Stream) return body; 214 if (body is Stream) return body;
216 215
217 throw new ArgumentError('Response body "$body" must be a String or a ' 216 throw new ArgumentError('Response body "$body" must be a String or a '
218 'Stream.'); 217 'Stream.');
219 } 218 }
220 219
221 /// Adds information about [encoding] to [headers]. 220 /// Adds information about [encoding] to [headers].
222 /// 221 ///
223 /// Returns a new map without modifying [headers]. 222 /// Returns a new map without modifying [headers].
224 UnmodifiableMapView<String, String> _adjustHeaders( 223 Map<String, String> _adjustHeaders(
225 Map<String, String> headers, Encoding encoding) { 224 Map<String, String> headers, Encoding encoding) {
226 if (headers == null) headers = const {}; 225 if (headers == null) headers = const {};
227 if (encoding == null) return new UnmodifiableMapView(headers); 226 if (encoding == null) return headers;
228 if (headers['content-type'] == null) { 227 if (headers['content-type'] == null) {
229 return new UnmodifiableMapView(_addHeader(headers, 'content-type', 228 return _addHeader(headers, 'content-type',
230 'application/octet-stream; charset=${encoding.name}')); 229 'application/octet-stream; charset=${encoding.name}');
231 } 230 }
232 231
233 var contentType = new MediaType.parse(headers['content-type']) 232 var contentType = new MediaType.parse(headers['content-type'])
234 .change(parameters: {'charset': encoding.name}); 233 .change(parameters: {'charset': encoding.name});
235 return new UnmodifiableMapView( 234 return _addHeader(headers, 'content-type', contentType.toString());
236 _addHeader(headers, 'content-type', contentType.toString()));
237 } 235 }
238 236
239 /// Adds a header with [name] and [value] to [headers], which may be null. 237 /// Adds a header with [name] and [value] to [headers], which may be null.
240 /// 238 ///
241 /// Returns a new map without modifying [headers]. 239 /// Returns a new map without modifying [headers].
242 Map<String, String> _addHeader(Map<String, String> headers, String name, 240 Map<String, String> _addHeader(Map<String, String> headers, String name,
243 String value) { 241 String value) {
244 headers = headers == null ? {} : new Map.from(headers); 242 headers = headers == null ? {} : new Map.from(headers);
245 headers[name] = value; 243 headers[name] = value;
246 return headers; 244 return headers;
(...skipping 16 matching lines...) Expand all
263 /// Converts [location], which may be a [String] or a [Uri], to a [String]. 261 /// Converts [location], which may be a [String] or a [Uri], to a [String].
264 /// 262 ///
265 /// Throws an [ArgumentError] if [location] isn't a [String] or a [Uri]. 263 /// Throws an [ArgumentError] if [location] isn't a [String] or a [Uri].
266 String _locationToString(location) { 264 String _locationToString(location) {
267 if (location is String) return location; 265 if (location is String) return location;
268 if (location is Uri) return location.toString(); 266 if (location is Uri) return location.toString();
269 267
270 throw new ArgumentError('Response location must be a String or Uri, was ' 268 throw new ArgumentError('Response location must be a String or Uri, was '
271 '"$location".'); 269 '"$location".');
272 } 270 }
OLDNEW
« no previous file with comments | « pkg/shelf/lib/src/request.dart ('k') | pkg/shelf/pubspec.yaml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698