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

Side by Side Diff: sdk/lib/core/uri.dart

Issue 23904004: Accept IPv6 addresses in Uri.http and Uri.https, and correctly nest IPv6 addresses in '[' and ']'. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | 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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 part of dart.core; 5 part of dart.core;
6 6
7 /** 7 /**
8 * A parsed URI, as specified by RFC-3986, http://tools.ietf.org/html/rfc3986. 8 * A parsed URI, as specified by RFC-3986, http://tools.ietf.org/html/rfc3986.
9 */ 9 */
10 class Uri { 10 class Uri {
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 * [queryParameters]. When [query] is used the provided string is 146 * [queryParameters]. When [query] is used the provided string is
147 * expected to be fully percent-encoded and is used in its literal 147 * expected to be fully percent-encoded and is used in its literal
148 * form. When [queryParameters] is used the query is built from the 148 * form. When [queryParameters] is used the query is built from the
149 * provided map. Each key and value in the map is percent-encoded 149 * provided map. Each key and value in the map is percent-encoded
150 * and joined using equal and ampersand characters. The 150 * and joined using equal and ampersand characters. The
151 * percent-encoding of the keys and values encodes all characters 151 * percent-encoding of the keys and values encodes all characters
152 * except for the unreserved characters. 152 * except for the unreserved characters.
153 * 153 *
154 * The fragment component is set through [fragment]. 154 * The fragment component is set through [fragment].
155 */ 155 */
156 Uri({scheme, 156 Uri({String scheme,
157 this.userInfo: "", 157 this.userInfo: "",
158 this.host: "", 158 String host: "",
159 port: 0, 159 port: 0,
160 String path, 160 String path,
161 Iterable<String> pathSegments, 161 Iterable<String> pathSegments,
162 String query, 162 String query,
163 Map<String, String> queryParameters, 163 Map<String, String> queryParameters,
164 fragment: ""}) : 164 fragment: ""}) :
165 scheme = _makeScheme(scheme), 165 scheme = _makeScheme(scheme),
166 host = _makeHost(host),
166 query = _makeQuery(query, queryParameters), 167 query = _makeQuery(query, queryParameters),
167 fragment = _makeFragment(fragment) { 168 fragment = _makeFragment(fragment) {
168 // Perform scheme specific normalization. 169 // Perform scheme specific normalization.
169 if (scheme == "http" && port == 80) { 170 if (scheme == "http" && port == 80) {
170 _port = 0; 171 _port = 0;
171 } else if (scheme == "https" && port == 443) { 172 } else if (scheme == "https" && port == 443) {
172 _port = 0; 173 _port = 0;
173 } else { 174 } else {
174 _port = port; 175 _port = port;
175 } 176 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 // Split off the user info. 231 // Split off the user info.
231 bool hasUserInfo = false; 232 bool hasUserInfo = false;
232 for (int i = 0; i < authority.length; i++) { 233 for (int i = 0; i < authority.length; i++) {
233 if (authority.codeUnitAt(i) == _AT_SIGN) { 234 if (authority.codeUnitAt(i) == _AT_SIGN) {
234 hasUserInfo = true; 235 hasUserInfo = true;
235 userInfo = authority.substring(0, i); 236 userInfo = authority.substring(0, i);
236 hostStart = i + 1; 237 hostStart = i + 1;
237 break; 238 break;
238 } 239 }
239 } 240 }
241 var hostEnd = null;
floitsch 2013/09/09 13:32:21 That's how I would write it. var hostEnd = hostSt
Anders Johnsen 2013/09/10 11:13:23 Done.
242 var portStart = hostStart;
243 if (authority.codeUnitAt(hostStart) == _LEFT_BRACKET) {
244 // IPv6 host.
245 for (int i = hostStart; i < authority.length; i++) {
246 if (authority.codeUnitAt(i) == _RIGHT_BRACKET) {
247 hostEnd = i;
248 break;
249 }
250 }
251 if (hostEnd == null) {
252 throw new FormatException("Invalid IPv6 host entry.");
253 }
254 hostEnd++;
255 portStart = hostEnd;
256 }
240 // Split host and port. 257 // Split host and port.
241 bool hasPort = false; 258 bool hasPort = false;
242 for (int i = hostStart; i < authority.length; i++) { 259 for (int i = portStart; i < authority.length; i++) {
243 if (authority.codeUnitAt(i) == _COLON) { 260 if (authority.codeUnitAt(i) == _COLON) {
244 hasPort = true; 261 hasPort = true;
floitsch 2013/09/09 13:32:21 you set hasPort to true, but if the host is empty
Anders Johnsen 2013/09/10 11:13:23 Done.
245 host = authority.substring(hostStart, i); 262 if (hostEnd == null) hostEnd = i;
263 host = authority.substring(hostStart, hostEnd);
246 if (!host.isEmpty) { 264 if (!host.isEmpty) {
floitsch 2013/09/09 13:32:21 if you just check hostStart != hostEnd you don't n
Anders Johnsen 2013/09/10 11:13:23 Done.
247 var portString = authority.substring(i + 1); 265 var portString = authority.substring(i + 1);
248 if (portString.isNotEmpty) port = int.parse(portString); 266 if (portString.isNotEmpty) port = int.parse(portString);
floitsch 2013/09/09 13:32:21 is this intended behavior? (an authority with ":"
Anders Johnsen 2013/09/10 11:13:23 Done.
249 } 267 }
250 break; 268 break;
251 } 269 }
252 } 270 }
253 if (!hasPort) { 271 if (!hasPort) {
254 host = hasUserInfo ? authority.substring(hostStart) : authority; 272 host = authority.substring(hostStart, hostEnd);
255 } 273 }
256 274
257 return new Uri(scheme: scheme, 275 return new Uri(scheme: scheme,
258 userInfo: userInfo, 276 userInfo: userInfo,
259 host: host, 277 host: host,
260 port: port, 278 port: port,
261 pathSegments: unencodedPath.split("/"), 279 pathSegments: unencodedPath.split("/"),
262 queryParameters: queryParameters); 280 queryParameters: queryParameters);
263 } 281 }
264 282
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 * The returned map is unmodifiable and will throw [UnsupportedError] on any 485 * The returned map is unmodifiable and will throw [UnsupportedError] on any
468 * calls that would mutate it. 486 * calls that would mutate it.
469 */ 487 */
470 Map<String, String> get queryParameters { 488 Map<String, String> get queryParameters {
471 if (_queryParameters == null) { 489 if (_queryParameters == null) {
472 _queryParameters = new _UnmodifiableMap(splitQueryString(query)); 490 _queryParameters = new _UnmodifiableMap(splitQueryString(query));
473 } 491 }
474 return _queryParameters; 492 return _queryParameters;
475 } 493 }
476 494
495 static String _makeHost(String host) {
496 if (host.isEmpty) return host;
497 if (host.codeUnitAt(0) == _LEFT_BRACKET) return host;
floitsch 2013/09/09 13:32:21 I would prefer a more sophisticated host-parser: d
Anders Johnsen 2013/09/10 11:13:23 Done.
498 for (int i = 0; i < host.length; i++) {
499 if (host.codeUnitAt(i) == _COLON) {
500 var buffer = new StringBuffer();
501 buffer.writeCharCode(_LEFT_BRACKET);
502 buffer.write(host);
503 if (host.codeUnitAt(host.length - 1) != _RIGHT_BRACKET) {
504 buffer.writeCharCode(_RIGHT_BRACKET);
505 }
506 return buffer.toString();
507 }
508 }
509 return host;
510 }
511
477 static String _makeScheme(String scheme) { 512 static String _makeScheme(String scheme) {
478 bool isSchemeLowerCharacter(int ch) { 513 bool isSchemeLowerCharacter(int ch) {
479 return ch < 128 && 514 return ch < 128 &&
480 ((_schemeLowerTable[ch >> 4] & (1 << (ch & 0x0f))) != 0); 515 ((_schemeLowerTable[ch >> 4] & (1 << (ch & 0x0f))) != 0);
481 } 516 }
482 517
483 bool isSchemeCharacter(int ch) { 518 bool isSchemeCharacter(int ch) {
484 return ch < 128 && ((_schemeTable[ch >> 4] & (1 << (ch & 0x0f))) != 0); 519 return ch < 128 && ((_schemeTable[ch >> 4] & (1 << (ch & 0x0f))) != 0);
485 } 520 }
486 521
(...skipping 670 matching lines...) Expand 10 before | Expand all | Expand 10 after
1157 static const int _ZERO = 0x30; 1192 static const int _ZERO = 0x30;
1158 static const int _NINE = 0x39; 1193 static const int _NINE = 0x39;
1159 static const int _COLON = 0x3A; 1194 static const int _COLON = 0x3A;
1160 static const int _LESS = 0x3C; 1195 static const int _LESS = 0x3C;
1161 static const int _GREATER = 0x3E; 1196 static const int _GREATER = 0x3E;
1162 static const int _QUESTION = 0x3F; 1197 static const int _QUESTION = 0x3F;
1163 static const int _AT_SIGN = 0x40; 1198 static const int _AT_SIGN = 0x40;
1164 static const int _UPPER_CASE_A = 0x41; 1199 static const int _UPPER_CASE_A = 0x41;
1165 static const int _UPPER_CASE_F = 0x46; 1200 static const int _UPPER_CASE_F = 0x46;
1166 static const int _UPPER_CASE_Z = 0x5A; 1201 static const int _UPPER_CASE_Z = 0x5A;
1202 static const int _LEFT_BRACKET = 0x5B;
1167 static const int _BACKSLASH = 0x5C; 1203 static const int _BACKSLASH = 0x5C;
1204 static const int _RIGHT_BRACKET = 0x5D;
1168 static const int _LOWER_CASE_A = 0x61; 1205 static const int _LOWER_CASE_A = 0x61;
1169 static const int _LOWER_CASE_F = 0x66; 1206 static const int _LOWER_CASE_F = 0x66;
1170 static const int _LOWER_CASE_Z = 0x7A; 1207 static const int _LOWER_CASE_Z = 0x7A;
1171 static const int _BAR = 0x7C; 1208 static const int _BAR = 0x7C;
1172 1209
1173 /** 1210 /**
1174 * This is the internal implementation of JavaScript's encodeURI function. 1211 * This is the internal implementation of JavaScript's encodeURI function.
1175 * It encodes all characters in the string [text] except for those 1212 * It encodes all characters in the string [text] except for those
1176 * that appear in [canonicalTable], and returns the escaped string. 1213 * that appear in [canonicalTable], and returns the escaped string.
1177 */ 1214 */
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
1465 void clear() { 1502 void clear() {
1466 throw new UnsupportedError("Cannot modify an unmodifiable map"); 1503 throw new UnsupportedError("Cannot modify an unmodifiable map");
1467 } 1504 }
1468 void forEach(void f(K key, V value)) => _map.forEach(f); 1505 void forEach(void f(K key, V value)) => _map.forEach(f);
1469 Iterable<K> get keys => _map.keys; 1506 Iterable<K> get keys => _map.keys;
1470 Iterable<V> get values => _map.values; 1507 Iterable<V> get values => _map.values;
1471 int get length => _map.length; 1508 int get length => _map.length;
1472 bool get isEmpty => _map.isEmpty; 1509 bool get isEmpty => _map.isEmpty;
1473 bool get isNotEmpty => _map.isNotEmpty; 1510 bool get isNotEmpty => _map.isNotEmpty;
1474 } 1511 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698