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