Chromium Code Reviews| 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.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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 74 Stream<List<int>> body, Map<String, Object> context}) | 74 Stream<List<int>> body, Map<String, Object> context}) |
| 75 : this.requestedUri = requestedUri, | 75 : this.requestedUri = requestedUri, |
| 76 this.protocolVersion = protocolVersion == null ? | 76 this.protocolVersion = protocolVersion == null ? |
| 77 '1.1' : protocolVersion, | 77 '1.1' : protocolVersion, |
| 78 this.url = _computeUrl(requestedUri, url, scriptName), | 78 this.url = _computeUrl(requestedUri, url, scriptName), |
| 79 this.scriptName = _computeScriptName(requestedUri, url, scriptName), | 79 this.scriptName = _computeScriptName(requestedUri, url, scriptName), |
| 80 super(body == null ? new Stream.fromIterable([]) : body, | 80 super(body == null ? new Stream.fromIterable([]) : body, |
| 81 headers: headers, context: context) { | 81 headers: headers, context: context) { |
| 82 if (method.isEmpty) throw new ArgumentError('method cannot be empty.'); | 82 if (method.isEmpty) throw new ArgumentError('method cannot be empty.'); |
| 83 | 83 |
| 84 // TODO(kevmoo) use isAbsolute property on Uri once Issue 18053 is fixed | 84 // NOTE: A Uri with a #fragment is is not considered 'absolute' per |
| 85 // http://tools.ietf.org/html/rfc3986#section-4.3 | |
| 86 // So instead of using Uri.isAbsolute, just checking for an empty scheme | |
|
nweiz
2014/04/28 22:13:33
Use full sentences in comments.
kevmoo
2014/04/29 10:41:54
Done.
| |
| 85 if (requestedUri.scheme.isEmpty) { | 87 if (requestedUri.scheme.isEmpty) { |
|
kevmoo
2014/04/26 16:34:34
The RFC is a bit weird about fragments, hence Uri.
nweiz
2014/04/28 22:13:33
I think we should use [isAbsolute] here. The reque
kevmoo
2014/04/29 10:41:54
I double checked. dart_io doesn't send the fragmen
| |
| 86 throw new ArgumentError('requstedUri must be an absolute URI.'); | 88 throw new ArgumentError('requstedUri must be an absolute URI.'); |
| 87 } | 89 } |
| 88 | 90 |
| 89 if (this.scriptName.isNotEmpty && !this.scriptName.startsWith('/')) { | 91 if (this.scriptName.isNotEmpty && !this.scriptName.startsWith('/')) { |
| 90 throw new ArgumentError('scriptName must be empty or start with "/".'); | 92 throw new ArgumentError('scriptName must be empty or start with "/".'); |
| 91 } | 93 } |
| 92 | 94 |
| 93 if (this.scriptName == '/') { | 95 if (this.scriptName == '/') { |
| 94 throw new ArgumentError( | 96 throw new ArgumentError( |
| 95 'scriptName can never be "/". It should be empty instead.'); | 97 'scriptName can never be "/". It should be empty instead.'); |
| 96 } | 98 } |
| 97 | 99 |
| 98 if (this.scriptName.endsWith('/')) { | 100 if (this.scriptName.endsWith('/')) { |
| 99 throw new ArgumentError('scriptName must not end with "/".'); | 101 throw new ArgumentError('scriptName must not end with "/".'); |
| 100 } | 102 } |
| 101 | 103 |
| 102 if (this.url.path.isNotEmpty && !this.url.path.startsWith('/')) { | 104 if (this.url.path.isNotEmpty && !this.url.path.startsWith('/')) { |
| 103 throw new ArgumentError('url must be empty or start with "/".'); | 105 throw new ArgumentError('url must be empty or start with "/".'); |
| 104 } | 106 } |
| 105 | 107 |
| 106 if (this.scriptName.isEmpty && this.url.path.isEmpty) { | 108 if (this.scriptName.isEmpty && this.url.path.isEmpty) { |
| 107 throw new ArgumentError('scriptName and url cannot both be empty.'); | 109 throw new ArgumentError('scriptName and url cannot both be empty.'); |
| 108 } | 110 } |
| 109 } | 111 } |
| 112 | |
| 113 /// Copies the request updated [context] and [headers] values. | |
|
nweiz
2014/04/28 22:13:33
Fix this sentence.
kevmoo
2014/04/29 10:41:54
Done.
| |
| 114 /// | |
| 115 /// New key-value pairs in [context] and [headers] will be added to the copied | |
| 116 /// [Request]. | |
| 117 /// | |
| 118 /// If [context] or [headers] includes a key that already exists, the | |
| 119 /// key-value pair will replace the corresponding entry in the copied | |
| 120 /// [Request]. | |
| 121 /// | |
| 122 /// All other context and header values from the [Request] will be included | |
| 123 /// in the copied [Request] unchanged. | |
| 124 Request copy({Map<String, String> headers, Map<String, Object> context}) { | |
|
nweiz
2014/04/28 22:13:33
We should discuss this name a bit. I like "copy" o
kevmoo
2014/04/29 10:41:54
Done.
| |
| 125 headers = _updatedMap(this.headers, headers); | |
| 126 context = _updatedMap(this.context, context); | |
| 127 | |
| 128 return new Request(this.method, this.requestedUri, | |
| 129 protocolVersion: this.protocolVersion, headers: headers, url: this.url, | |
| 130 scriptName: this.scriptName, body: this.read(), context: context); | |
|
nweiz
2014/04/28 22:13:33
I don't like that this copies the headers and re-w
kevmoo
2014/04/29 10:41:54
Done.
| |
| 131 } | |
| 132 } | |
| 133 | |
| 134 Map _updatedMap(Map original, Map updates) { | |
|
nweiz
2014/04/28 22:13:33
Functions should have verb names, e.g. "_updateMap
kevmoo
2014/04/29 10:41:54
Done.
| |
| 135 if (updates == null || updates.isEmpty) return original; | |
| 136 | |
| 137 return new Map.from(original) | |
| 138 ..addAll(updates); | |
| 110 } | 139 } |
| 111 | 140 |
| 112 /// Computes `url` from the provided [Request] constructor arguments. | 141 /// Computes `url` from the provided [Request] constructor arguments. |
| 113 /// | 142 /// |
| 114 /// If [url] and [scriptName] are `null`, infer value from [requestedUrl], | 143 /// If [url] and [scriptName] are `null`, infer value from [requestedUrl], |
| 115 /// otherwise return [url]. | 144 /// otherwise return [url]. |
| 116 /// | 145 /// |
| 117 /// If [url] is provided, but [scriptName] is omitted, throws an | 146 /// If [url] is provided, but [scriptName] is omitted, throws an |
| 118 /// [ArgumentError]. | 147 /// [ArgumentError]. |
| 119 Uri _computeUrl(Uri requestedUri, Uri url, String scriptName) { | 148 Uri _computeUrl(Uri requestedUri, Uri url, String scriptName) { |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 144 return ''; | 173 return ''; |
| 145 } | 174 } |
| 146 | 175 |
| 147 if (url != null && scriptName != null) { | 176 if (url != null && scriptName != null) { |
| 148 return scriptName; | 177 return scriptName; |
| 149 } | 178 } |
| 150 | 179 |
| 151 throw new ArgumentError( | 180 throw new ArgumentError( |
| 152 'url and scriptName must both be null or both be set.'); | 181 'url and scriptName must both be null or both be set.'); |
| 153 } | 182 } |
| OLD | NEW |