OLD | NEW |
---|---|
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 // Frequently used character codes. | 7 // Frequently used character codes. |
8 const int _SPACE = 0x20; | 8 const int _SPACE = 0x20; |
9 const int _PERCENT = 0x25; | 9 const int _PERCENT = 0x25; |
10 const int _PLUS = 0x2B; | 10 const int _PLUS = 0x2B; |
(...skipping 4305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4316 return new _SimpleUri(newUri, | 4316 return new _SimpleUri(newUri, |
4317 base._schemeEnd, | 4317 base._schemeEnd, |
4318 base._hostStart, | 4318 base._hostStart, |
4319 base._portStart, | 4319 base._portStart, |
4320 base._pathStart, | 4320 base._pathStart, |
4321 ref._queryStart + delta, | 4321 ref._queryStart + delta, |
4322 ref._fragmentStart + delta, | 4322 ref._fragmentStart + delta, |
4323 base._schemeCache); | 4323 base._schemeCache); |
4324 } | 4324 } |
4325 // Merge paths. | 4325 // Merge paths. |
4326 if (base._uri.startsWith("../", base._pathStart)) { | |
4327 // Complex rare case, go slow. | |
4328 return _toNonSimple().resolveUri(ref); | |
4329 } | |
4330 | 4326 |
4331 // The RFC 3986 algorithm merges the base path without its final segment | 4327 // The RFC 3986 algorithm merges the base path without its final segment |
4332 // (anything after the final "/", or everything if the base path doesn't | 4328 // (anything after the final "/", or everything if the base path doesn't |
4333 // contain any "/"), and the reference path. | 4329 // contain any "/"), and the reference path. |
4334 // Then it removes "." and ".." segments using the remove-dot-segment | 4330 // Then it removes "." and ".." segments using the remove-dot-segment |
4335 // algorithm. | 4331 // algorithm. |
4336 // This code combines the two steps. It is simplified by knowing that | 4332 // This code combines the two steps. It is simplified by knowing that |
4337 // the base path contains no "." or ".." segments, and the reference | 4333 // the base path contains no "." or ".." segments, and the reference |
4338 // path can only contain leading ".." segments. | 4334 // path can only contain leading ".." segments. |
4339 | 4335 |
4340 String baseUri = base._uri; | 4336 String baseUri = base._uri; |
4341 String refUri = ref._uri; | 4337 String refUri = ref._uri; |
4342 int baseStart = base._pathStart; | 4338 int baseStart = base._pathStart; |
4343 int baseEnd = base._queryStart; | 4339 int baseEnd = base._queryStart; |
4340 while (baseUri.startsWith("../", baseStart)) baseStart += 3; | |
4344 int refStart = ref._pathStart; | 4341 int refStart = ref._pathStart; |
4345 int refEnd = ref._queryStart; | 4342 int refEnd = ref._queryStart; |
4346 int backCount = 1; | 4343 int backCount = 0; |
eernst
2016/09/29 12:28:49
It would help to document this variable. Is it som
Lasse Reichstein Nielsen
2016/09/29 12:58:30
Done.
| |
4347 | 4344 |
4348 int slashCount = 0; | 4345 int slashCount = 0; |
4349 | 4346 |
4350 // Count leading ".." segments in reference path. | 4347 // Count leading ".." segments in reference path. |
4351 while (refStart + 3 <= refEnd && refUri.startsWith("../", refStart)) { | 4348 while (refStart + 3 <= refEnd && refUri.startsWith("../", refStart)) { |
4352 refStart += 3; | 4349 refStart += 3; |
4353 backCount += 1; | 4350 backCount += 1; |
4354 } | 4351 } |
4355 | 4352 |
4356 // Extra slash inserted between base and reference path parts if | 4353 // Extra slash inserted between base and reference path parts if |
4357 // the base path contains any slashes. | 4354 // the base path contains any slashes. |
4358 // (We could use a slash from the base path in most cases, but not if | 4355 // (We could use a slash from the base path in most cases, but not if |
4359 // we remove the entire base path). | 4356 // we remove the entire base path). |
4360 String insert = ""; | 4357 String insert = ""; |
4361 while (baseEnd > baseStart) { | 4358 while (baseEnd > baseStart) { |
4362 baseEnd--; | 4359 baseEnd--; |
4363 int char = baseUri.codeUnitAt(baseEnd); | 4360 int char = baseUri.codeUnitAt(baseEnd); |
4364 if (char == _SLASH) { | 4361 if (char == _SLASH) { |
4365 insert = "/"; | 4362 insert = "/"; |
4363 if (backCount == 0) break; | |
4366 backCount--; | 4364 backCount--; |
4367 if (backCount == 0) break; | |
4368 } | 4365 } |
4369 } | 4366 } |
eernst
2016/09/29 12:28:49
This while loop seems to cut off segments starting
Lasse Reichstein Nielsen
2016/09/29 12:58:30
Done.
| |
4370 // If the base URI has no scheme or authority (`_pathStart == 0`) | 4367 |
4371 // and a relative path, and we reached the beginning of the path, | 4368 if (!base.hasScheme && !base.hasAbsolutePath) { |
4372 // we have a special case. | 4369 // If the base is *just* a relative path (no scheme or authority), |
4373 if (baseEnd == 0 && !base.hasAbsolutePath) { | 4370 // then merging with another relative path doesn't follow the |
4374 // Non-RFC 3986 behavior when resolving a purely relative path on top of | 4371 // RFC-3986 behavior. |
4375 // another relative path: Don't make the result absolute. | 4372 // Don't need to check `base.hasAuthority` since the base path is |
4376 insert = ""; | 4373 // non-empty - if there is an authority, a non-empty path is absolute. |
4374 if (backCount > 0) { | |
4375 // We reached the start of the base path with more "../" left over | |
4376 // in the reference path. Include those in the result. | |
4377 refStart -= backCount * 3; | |
4378 insert = ""; | |
4379 } else if (baseEnd == baseStart) { | |
4380 // We reached the start of the base path with no more "../" left | |
4381 // over, so don't insert a "/" - that would make the result absolute. | |
eernst
2016/09/29 12:28:49
Would be nice to have an explicit "this is the cas
Lasse Reichstein Nielsen
2016/09/29 12:58:30
That is what it says right above (look for RFC-398
| |
4382 insert = ""; | |
4383 } | |
4377 } | 4384 } |
4378 | 4385 |
4379 var delta = baseEnd - refStart + insert.length; | 4386 var delta = baseEnd - refStart + insert.length; |
4380 var newUri = "${base._uri.substring(0, baseEnd)}$insert" | 4387 var newUri = "${base._uri.substring(0, baseEnd)}$insert" |
4381 "${ref._uri.substring(refStart)}"; | 4388 "${ref._uri.substring(refStart)}"; |
4382 | 4389 |
4383 return new _SimpleUri(newUri, | 4390 return new _SimpleUri(newUri, |
4384 base._schemeEnd, | 4391 base._schemeEnd, |
4385 base._hostStart, | 4392 base._hostStart, |
4386 base._portStart, | 4393 base._portStart, |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4458 int delta = (text.codeUnitAt(start + 4) ^ _COLON) * 3; | 4465 int delta = (text.codeUnitAt(start + 4) ^ _COLON) * 3; |
4459 delta |= text.codeUnitAt(start) ^ 0x64 /*d*/; | 4466 delta |= text.codeUnitAt(start) ^ 0x64 /*d*/; |
4460 delta |= text.codeUnitAt(start + 1) ^ 0x61 /*a*/; | 4467 delta |= text.codeUnitAt(start + 1) ^ 0x61 /*a*/; |
4461 delta |= text.codeUnitAt(start + 2) ^ 0x74 /*t*/; | 4468 delta |= text.codeUnitAt(start + 2) ^ 0x74 /*t*/; |
4462 delta |= text.codeUnitAt(start + 3) ^ 0x61 /*a*/; | 4469 delta |= text.codeUnitAt(start + 3) ^ 0x61 /*a*/; |
4463 return delta; | 4470 return delta; |
4464 } | 4471 } |
4465 | 4472 |
4466 /// Helper function returning the length of a string, or `0` for `null`. | 4473 /// Helper function returning the length of a string, or `0` for `null`. |
4467 int _stringOrNullLength(String s) => (s == null) ? 0 : s.length; | 4474 int _stringOrNullLength(String s) => (s == null) ? 0 : s.length; |
OLD | NEW |