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

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

Issue 294123011: pkg/shelf: added `url` and `scriptName` named params to Request.change (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: error msg and pubspec tweaks Created 6 years, 7 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
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.request; 5 library shelf.request;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 8
9 import 'package:http_parser/http_parser.dart'; 9 import 'package:http_parser/http_parser.dart';
10 10
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 this.scriptName = _computeScriptName(requestedUri, url, scriptName), 127 this.scriptName = _computeScriptName(requestedUri, url, scriptName),
128 this._onHijack = onHijack == null ? null : new _OnHijack(onHijack), 128 this._onHijack = onHijack == null ? null : new _OnHijack(onHijack),
129 super(body == null ? new Stream.fromIterable([]) : body, 129 super(body == null ? new Stream.fromIterable([]) : body,
130 headers: headers, context: context) { 130 headers: headers, context: context) {
131 if (method.isEmpty) throw new ArgumentError('method cannot be empty.'); 131 if (method.isEmpty) throw new ArgumentError('method cannot be empty.');
132 132
133 if (!requestedUri.isAbsolute) { 133 if (!requestedUri.isAbsolute) {
134 throw new ArgumentError('requstedUri must be an absolute URI.'); 134 throw new ArgumentError('requstedUri must be an absolute URI.');
135 } 135 }
136 136
137 // TODO(kevmoo) if defined, check that scriptName is a fully-encoded, valid
138 // path component
137 if (this.scriptName.isNotEmpty && !this.scriptName.startsWith('/')) { 139 if (this.scriptName.isNotEmpty && !this.scriptName.startsWith('/')) {
138 throw new ArgumentError('scriptName must be empty or start with "/".'); 140 throw new ArgumentError('scriptName must be empty or start with "/".');
139 } 141 }
140 142
141 if (this.scriptName == '/') { 143 if (this.scriptName == '/') {
142 throw new ArgumentError( 144 throw new ArgumentError(
143 'scriptName can never be "/". It should be empty instead.'); 145 'scriptName can never be "/". It should be empty instead.');
144 } 146 }
145 147
146 if (this.scriptName.endsWith('/')) { 148 if (this.scriptName.endsWith('/')) {
(...skipping 14 matching lines...) Expand all
161 /// 163 ///
162 /// New key-value pairs in [context] and [headers] will be added to the copied 164 /// New key-value pairs in [context] and [headers] will be added to the copied
163 /// [Request]. 165 /// [Request].
164 /// 166 ///
165 /// If [context] or [headers] includes a key that already exists, the 167 /// If [context] or [headers] includes a key that already exists, the
166 /// key-value pair will replace the corresponding entry in the copied 168 /// key-value pair will replace the corresponding entry in the copied
167 /// [Request]. 169 /// [Request].
168 /// 170 ///
169 /// All other context and header values from the [Request] will be included 171 /// All other context and header values from the [Request] will be included
170 /// in the copied [Request] unchanged. 172 /// in the copied [Request] unchanged.
171 Request change({Map<String, String> headers, Map<String, Object> context}) { 173 ///
174 /// If [scriptName] is provided without [url], the corresponding path
175 /// component of [Request.url] is replaced in the new instance. In this case,
176 /// [scriptName] must match the beginning of the existing `path` component of
177 /// [Request.url] or an [ArgumentError] is thrown.
nweiz 2014/05/22 19:50:42 This paragraph is confusing. I suggest: "If [scrip
kevmoo 2014/05/22 20:38:36 Done.
nweiz 2014/05/23 21:43:34 You didn't include any explanation of the purpose.
178 Request change({Map<String, String> headers, Map<String, Object> context,
179 String scriptName, Uri url}) {
172 headers = updateMap(this.headers, headers); 180 headers = updateMap(this.headers, headers);
173 context = updateMap(this.context, context); 181 context = updateMap(this.context, context);
174 182
183 if (scriptName != null && url == null) {
184 var path = this.url.path;
185 if (path.startsWith(scriptName)) {
186 path = path.substring(scriptName.length);
187 url = new Uri(path: path, query: this.url.query);
188 } else {
189 throw new ArgumentError('If scriptName is provided without url, it must'
190 ' match the beginning of the existing url path.');
nweiz 2014/05/22 19:50:42 "match the beginning" -> "be a prefix"
kevmoo 2014/05/22 20:38:36 Done.
191 }
192 }
193
194 if (url == null) url = this.url;
195
nweiz 2014/05/22 19:50:42 Nit: I'd remove this newline.
kevmoo 2014/05/22 20:38:36 Done.
196 if (scriptName == null) scriptName = this.scriptName;
197
175 return new Request(this.method, this.requestedUri, 198 return new Request(this.method, this.requestedUri,
176 protocolVersion: this.protocolVersion, headers: headers, url: this.url, 199 protocolVersion: this.protocolVersion, headers: headers, url: url,
177 scriptName: this.scriptName, body: this.read(), context: context); 200 scriptName: scriptName, body: this.read(), context: context);
178 } 201 }
179 202
180 /// Takes control of the underlying request socket. 203 /// Takes control of the underlying request socket.
181 /// 204 ///
182 /// Synchronously, this throws a [HijackException] that indicates to the 205 /// Synchronously, this throws a [HijackException] that indicates to the
183 /// adapter that it shouldn't emit a response itself. Asynchronously, 206 /// adapter that it shouldn't emit a response itself. Asynchronously,
184 /// [callback] is called with a [Stream<List<int>>] and 207 /// [callback] is called with a [Stream<List<int>>] and
185 /// [StreamSink<List<int>>], respectively, that provide access to the 208 /// [StreamSink<List<int>>], respectively, that provide access to the
186 /// underlying request socket. 209 /// underlying request socket.
187 /// 210 ///
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 249
227 /// Computes `url` from the provided [Request] constructor arguments. 250 /// Computes `url` from the provided [Request] constructor arguments.
228 /// 251 ///
229 /// If [url] and [scriptName] are `null`, infer value from [requestedUrl], 252 /// If [url] and [scriptName] are `null`, infer value from [requestedUrl],
230 /// otherwise return [url]. 253 /// otherwise return [url].
231 /// 254 ///
232 /// If [url] is provided, but [scriptName] is omitted, throws an 255 /// If [url] is provided, but [scriptName] is omitted, throws an
233 /// [ArgumentError]. 256 /// [ArgumentError].
234 Uri _computeUrl(Uri requestedUri, Uri url, String scriptName) { 257 Uri _computeUrl(Uri requestedUri, Uri url, String scriptName) {
235 if (url == null && scriptName == null) { 258 if (url == null && scriptName == null) {
236 return new Uri(path: requestedUri.path, query: requestedUri.query, 259 return new Uri(path: requestedUri.path, query: requestedUri.query);
237 fragment: requestedUri.fragment);
238 } 260 }
239 261
240 if (url != null && scriptName != null) { 262 if (url != null && scriptName != null) {
241 if (url.scheme.isNotEmpty) throw new ArgumentError('url must be relative.'); 263 if (url.scheme.isNotEmpty) throw new ArgumentError('url must be relative.');
242 return url; 264 return url;
243 } 265 }
244 266
245 throw new ArgumentError( 267 throw new ArgumentError(
246 'url and scriptName must both be null or both be set.'); 268 'url and scriptName must both be null or both be set.');
247 } 269 }
(...skipping 10 matching lines...) Expand all
258 return ''; 280 return '';
259 } 281 }
260 282
261 if (url != null && scriptName != null) { 283 if (url != null && scriptName != null) {
262 return scriptName; 284 return scriptName;
263 } 285 }
264 286
265 throw new ArgumentError( 287 throw new ArgumentError(
266 'url and scriptName must both be null or both be set.'); 288 'url and scriptName must both be null or both be set.');
267 } 289 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698