Resolve reference
as an URI relative to this
.
Returns the resolved URI.
The algorithm "Transform Reference" for resolving a reference is described in RFC-3986 Section 5.
Updated to handle the case where the base URI is just a relative path - that is: when it has no scheme or authority and the path does not start with a slash. In that case, the paths are combined without removing leading "..", and an empty path is not converted to "/".
Source
Uri resolveUri(Uri reference) { // From RFC 3986. String targetScheme; String targetUserInfo = ""; String targetHost; int targetPort; String targetPath; String targetQuery; if (reference.scheme.isNotEmpty) { targetScheme = reference.scheme; if (reference.hasAuthority) { targetUserInfo = reference.userInfo; targetHost = reference.host; targetPort = reference.hasPort ? reference.port : null; } targetPath = _removeDotSegments(reference.path); if (reference.hasQuery) { targetQuery = reference.query; } } else { targetScheme = this.scheme; if (reference.hasAuthority) { targetUserInfo = reference.userInfo; targetHost = reference.host; targetPort = _makePort(reference.hasPort ? reference.port : null, targetScheme); targetPath = _removeDotSegments(reference.path); if (reference.hasQuery) targetQuery = reference.query; } else { targetUserInfo = this._userInfo; targetHost = this._host; targetPort = this._port; if (reference.path == "") { targetPath = this._path; if (reference.hasQuery) { targetQuery = reference.query; } else { targetQuery = this._query; } } else { if (reference.hasAbsolutePath) { targetPath = _removeDotSegments(reference.path); } else { // This is the RFC 3986 behavior for merging. if (this.hasEmptyPath) { if (!this.hasScheme && !this.hasAuthority) { // Keep the path relative if no scheme or authority. targetPath = reference.path; } else { // Add path normalization on top of RFC algorithm. targetPath = _removeDotSegments("/" + reference.path); } } else { var mergedPath = _mergePaths(this._path, reference.path); if (this.hasScheme || this.hasAuthority || this.hasAbsolutePath) { targetPath = _removeDotSegments(mergedPath); } else { // Non-RFC 3986 beavior. If both base and reference are relative // path, allow the merged path to start with "..". // The RFC only specifies the case where the base has a scheme. targetPath = _normalizeRelativePath(mergedPath); } } } if (reference.hasQuery) targetQuery = reference.query; } } } String fragment = reference.hasFragment ? reference.fragment : null; return new Uri._internal(targetScheme, targetUserInfo, targetHost, targetPort, targetPath, targetQuery, fragment); }