Index: C:/Dokumente und Einstellungen/Koch/Eigene Dateien/koch/opt/eclipse/workspace_p/httpcomponents-client/httpclient/src/main/java/org/apache/http/client/utils/URIUtils.java =================================================================== --- C:/Dokumente und Einstellungen/Koch/Eigene Dateien/koch/opt/eclipse/workspace_p/httpcomponents-client/httpclient/src/main/java/org/apache/http/client/utils/URIUtils.java (revision 794056) +++ C:/Dokumente und Einstellungen/Koch/Eigene Dateien/koch/opt/eclipse/workspace_p/httpcomponents-client/httpclient/src/main/java/org/apache/http/client/utils/URIUtils.java (working copy) @@ -28,6 +28,7 @@ import java.net.URI; import java.net.URISyntaxException; +import java.util.Stack; import net.jcip.annotations.Immutable; @@ -171,8 +172,8 @@ } /** - * Resolves a URI reference against a base URI. Work-around for bug in - * java.net.URI () + * Resolves a URI reference against a base URI. Work-around for bugs in + * java.net.URI (e.g. ) * * @param baseURI the base URI * @param reference the URI reference @@ -185,6 +186,9 @@ if (reference == null) { throw new IllegalArgumentException("Reference URI may nor be null"); } + if (reference.toString().startsWith("?")) { + return resolveReferenceStartingWithQueryString(baseURI, reference); + } boolean emptyReference = reference.toString().length() == 0; if (emptyReference) { reference = URI.create("#"); @@ -195,10 +199,64 @@ resolved = URI.create(resolvedString.substring(0, resolvedString.indexOf('#'))); } - return resolved; + return removeDotSegments(resolved); } /** + * Resolves a reference starting with a query string. + * + * @param baseURI the base URI + * @param reference the URI reference starting with a query string + * @return the resulting URI + */ + private static URI resolveReferenceStartingWithQueryString(URI baseURI, + URI reference) { + String baseUri = baseURI.toString(); + baseUri = baseUri.indexOf('?') > -1 ? + baseUri.substring(0, baseUri.indexOf('?')) : baseUri; + return URI.create(baseUri + reference.toString()); + } + + /** + * Removes dot segments according to RFC 3986, section 5.2.4 + * + * @param uri the original URI + * @return the URI without dot segments + */ + private static URI removeDotSegments(URI uri) { + String path = uri.getPath(); + if ((path == null) || (path.indexOf("/.") == -1)) { + // No dot segments to remove + return uri; + } + String[] inputSegments = path.split("/"); + Stack outputSegments = new Stack(); + for (int i = 0; i < inputSegments.length; i++) { + if ((inputSegments[i].length() == 0) + || (".".equals(inputSegments[i]))) { + // Do nothing + } + else if ("..".equals(inputSegments[i])) { + if (!outputSegments.isEmpty()) { + outputSegments.pop(); + } + } else { + outputSegments.push(inputSegments[i]); + } + } + StringBuffer outputBuffer = new StringBuffer(); + for (String outputSegment : outputSegments) { + outputBuffer.append('/').append(outputSegment); + } + try { + return new URI(uri.getScheme(), uri.getAuthority(), + outputBuffer.toString(), uri.getQuery(), uri.getFragment()); + } catch (URISyntaxException e) { + throw new IllegalArgumentException(e); + } + } + + /** * This class should not be instantiated. */ private URIUtils() {