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

Side by Side Diff: mojo/public/dart/third_party/shelf/lib/src/response.dart

Issue 1346773002: Stop running pub get at gclient sync time and fix build bugs (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 3 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
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 library shelf.response;
6
7 import 'dart:convert';
8
9 import 'package:http_parser/http_parser.dart';
10
11 import 'message.dart';
12 import 'util.dart';
13
14 /// The response returned by a [Handler].
15 class Response extends Message {
16 /// The HTTP status code of the response.
17 final int statusCode;
18
19 /// The date and time after which the response's data should be considered
20 /// stale.
21 ///
22 /// This is parsed from the Expires header in [headers]. If [headers] doesn't
23 /// have an Expires header, this will be `null`.
24 DateTime get expires {
25 if (_expiresCache != null) return _expiresCache;
26 if (!headers.containsKey('expires')) return null;
27 _expiresCache = parseHttpDate(headers['expires']);
28 return _expiresCache;
29 }
30 DateTime _expiresCache;
31
32 /// The date and time the source of the response's data was last modified.
33 ///
34 /// This is parsed from the Last-Modified header in [headers]. If [headers]
35 /// doesn't have a Last-Modified header, this will be `null`.
36 DateTime get lastModified {
37 if (_lastModifiedCache != null) return _lastModifiedCache;
38 if (!headers.containsKey('last-modified')) return null;
39 _lastModifiedCache = parseHttpDate(headers['last-modified']);
40 return _lastModifiedCache;
41 }
42 DateTime _lastModifiedCache;
43
44 /// Constructs a 200 OK response.
45 ///
46 /// This indicates that the request has succeeded.
47 ///
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],
50 /// [encoding] is used to encode it to a [Stream<List<int>>]. It defaults to
51 /// UTF-8.
52 ///
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
55 /// Content-Type header, it will be set to "application/octet-stream".
56 Response.ok(body, {Map<String, String> headers, Encoding encoding,
57 Map<String, Object> context})
58 : this(200, body: body, headers: headers, encoding: encoding,
59 context: context);
60
61 /// Constructs a 301 Moved Permanently response.
62 ///
63 /// This indicates that the requested resource has moved permanently to a new
64 /// URI. [location] is that URI; it can be either a [String] or a [Uri]. It's
65 /// automatically set as the Location header in [headers].
66 ///
67 /// [body] is the response body. It may be either a [String], a
68 /// [Stream<List<int>>], or `null` to indicate no body. If it's a [String],
69 /// [encoding] is used to encode it to a [Stream<List<int>>]. It defaults to
70 /// UTF-8.
71 ///
72 /// If [encoding] is passed, the "encoding" field of the Content-Type header
73 /// in [headers] will be set appropriately. If there is no existing
74 /// Content-Type header, it will be set to "application/octet-stream".
75 Response.movedPermanently(location, {body, Map<String, String> headers,
76 Encoding encoding, Map<String, Object> context})
77 : this._redirect(301, location, body, headers, encoding,
78 context: context);
79
80 /// Constructs a 302 Found response.
81 ///
82 /// This indicates that the requested resource has moved temporarily to a new
83 /// URI. [location] is that URI; it can be either a [String] or a [Uri]. It's
84 /// automatically set as the Location header in [headers].
85 ///
86 /// [body] is the response body. It may be either a [String], a
87 /// [Stream<List<int>>], or `null` to indicate no body. If it's a [String],
88 /// [encoding] is used to encode it to a [Stream<List<int>>]. It defaults to
89 /// UTF-8.
90 ///
91 /// If [encoding] is passed, the "encoding" field of the Content-Type header
92 /// in [headers] will be set appropriately. If there is no existing
93 /// Content-Type header, it will be set to "application/octet-stream".
94 Response.found(location, {body, Map<String, String> headers,
95 Encoding encoding, Map<String, Object> context})
96 : this._redirect(302, location, body, headers, encoding,
97 context: context);
98
99 /// Constructs a 303 See Other response.
100 ///
101 /// This indicates that the response to the request should be retrieved using
102 /// a GET request to a new URI. [location] is that URI; it can be either a
103 /// [String] or a [Uri]. It's automatically set as the Location header in
104 /// [headers].
105 ///
106 /// [body] is the response body. It may be either a [String], a
107 /// [Stream<List<int>>], or `null` to indicate no body. If it's a [String],
108 /// [encoding] is used to encode it to a [Stream<List<int>>]. It defaults to
109 /// UTF-8.
110 ///
111 /// If [encoding] is passed, the "encoding" field of the Content-Type header
112 /// in [headers] will be set appropriately. If there is no existing
113 /// Content-Type header, it will be set to "application/octet-stream".
114 Response.seeOther(location, {body, Map<String, String> headers,
115 Encoding encoding, Map<String, Object> context})
116 : this._redirect(303, location, body, headers, encoding,
117 context: context);
118
119 /// Constructs a helper constructor for redirect responses.
120 Response._redirect(int statusCode, location, body,
121 Map<String, String> headers, Encoding encoding,
122 { Map<String, Object> context })
123 : this(statusCode,
124 body: body,
125 encoding: encoding,
126 headers: addHeader(
127 headers, 'location', _locationToString(location)),
128 context: context);
129
130 /// Constructs a 304 Not Modified response.
131 ///
132 /// This is used to respond to a conditional GET request that provided
133 /// information used to determine whether the requested resource has changed
134 /// since the last request. It indicates that the resource has not changed and
135 /// the old value should be used.
136 Response.notModified({Map<String, String> headers,
137 Map<String, Object> context})
138 : this(304, headers: addHeader(
139 headers, 'date', formatHttpDate(new DateTime.now())),
140 context: context);
141
142 /// Constructs a 403 Forbidden response.
143 ///
144 /// This indicates that the server is refusing to fulfill the request.
145 ///
146 /// [body] is the response body. It may be a [String], a [Stream<List<int>>],
147 /// or `null`. If it's a [String], [encoding] is used to encode it to a
148 /// [Stream<List<int>>]. The default encoding is UTF-8. If it's `null` or not
149 /// passed, a default error message is used.
150 ///
151 /// If [encoding] is passed, the "encoding" field of the Content-Type header
152 /// in [headers] will be set appropriately. If there is no existing
153 /// Content-Type header, it will be set to "application/octet-stream".
154 Response.forbidden(body, {Map<String, String> headers,
155 Encoding encoding, Map<String, Object> context})
156 : this(403,
157 headers: body == null ? _adjustErrorHeaders(headers) : headers,
158 body: body == null ? 'Forbidden' : body,
159 context: context);
160
161 /// Constructs a 404 Not Found response.
162 ///
163 /// This indicates that the server didn't find any resource matching the
164 /// requested URI.
165 ///
166 /// [body] is the response body. It may be a [String], a [Stream<List<int>>],
167 /// or `null`. If it's a [String], [encoding] is used to encode it to a
168 /// [Stream<List<int>>]. The default encoding is UTF-8. If it's `null` or not
169 /// passed, a default error message is used.
170 ///
171 /// If [encoding] is passed, the "encoding" field of the Content-Type header
172 /// in [headers] will be set appropriately. If there is no existing
173 /// Content-Type header, it will be set to "application/octet-stream".
174 Response.notFound(body, {Map<String, String> headers, Encoding encoding,
175 Map<String, Object> context})
176 : this(404,
177 headers: body == null ? _adjustErrorHeaders(headers) : headers,
178 body: body == null ? 'Not Found' : body,
179 context: context);
180
181 /// Constructs a 500 Internal Server Error response.
182 ///
183 /// This indicates that the server had an internal error that prevented it
184 /// from fulfilling the request.
185 ///
186 /// [body] is the response body. It may be a [String], a [Stream<List<int>>],
187 /// or `null`. If it's a [String], [encoding] is used to encode it to a
188 /// [Stream<List<int>>]. The default encoding is UTF-8. If it's `null` or not
189 /// passed, a default error message is used.
190 ///
191 /// If [encoding] is passed, the "encoding" field of the Content-Type header
192 /// in [headers] will be set appropriately. If there is no existing
193 /// Content-Type header, it will be set to "application/octet-stream".
194 Response.internalServerError({body, Map<String, String> headers,
195 Encoding encoding, Map<String, Object> context})
196 : this(500,
197 headers: body == null ? _adjustErrorHeaders(headers) : headers,
198 body: body == null ? 'Internal Server Error' : body,
199 context: context);
200
201 /// Constructs an HTTP response with the given [statusCode].
202 ///
203 /// [statusCode] must be greater than or equal to 100.
204 ///
205 /// [body] is the response body. It may be either a [String], a
206 /// [Stream<List<int>>], or `null` to indicate no body.
207 /// If it's a [String], [encoding] is used to encode it to a
208 /// [Stream<List<int>>]. The default encoding is UTF-8.
209 ///
210 /// If [encoding] is passed, the "encoding" field of the Content-Type header
211 /// in [headers] will be set appropriately. If there is no existing
212 /// Content-Type header, it will be set to "application/octet-stream".
213 Response(this.statusCode, {body, Map<String, String> headers,
214 Encoding encoding, Map<String, Object> context})
215 : super(body, encoding: encoding, headers: headers, context: context) {
216 if (statusCode < 100) {
217 throw new ArgumentError("Invalid status code: $statusCode.");
218 }
219 }
220
221 /// Creates a new [Response] by copying existing values and applying specified
222 /// changes.
223 ///
224 /// New key-value pairs in [context] and [headers] will be added to the copied
225 /// [Response].
226 ///
227 /// If [context] or [headers] includes a key that already exists, the
228 /// key-value pair will replace the corresponding entry in the copied
229 /// [Response].
230 ///
231 /// All other context and header values from the [Response] will be included
232 /// in the copied [Response] unchanged.
233 ///
234 /// [body] is the request body. It may be either a [String] or a
235 /// [Stream<List<int>>].
236 Response change(
237 {Map<String, String> headers, Map<String, Object> context, body}) {
238 headers = updateMap(this.headers, headers);
239 context = updateMap(this.context, context);
240
241 if (body == null) body = getBody(this);
242
243 return new Response(this.statusCode, body: body, headers: headers,
244 context: context);
245 }
246 }
247
248 /// Adds content-type information to [headers].
249 ///
250 /// Returns a new map without modifying [headers]. This is used to add
251 /// content-type information when creating a 500 response with a default body.
252 Map<String, String> _adjustErrorHeaders(Map<String, String> headers) {
253 if (headers == null || headers['content-type'] == null) {
254 return addHeader(headers, 'content-type', 'text/plain');
255 }
256
257 var contentType = new MediaType.parse(headers['content-type'])
258 .change(mimeType: 'text/plain');
259 return addHeader(headers, 'content-type', contentType.toString());
260 }
261
262 /// Converts [location], which may be a [String] or a [Uri], to a [String].
263 ///
264 /// Throws an [ArgumentError] if [location] isn't a [String] or a [Uri].
265 String _locationToString(location) {
266 if (location is String) return location;
267 if (location is Uri) return location.toString();
268
269 throw new ArgumentError('Response location must be a String or Uri, was '
270 '"$location".');
271 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698