diff --git a/httpclient/src/main/java/org/apache/http/impl/client/AbstractHttpClient.java b/httpclient/src/main/java/org/apache/http/impl/client/AbstractHttpClient.java index 7480c842d..332140519 100644 --- a/httpclient/src/main/java/org/apache/http/impl/client/AbstractHttpClient.java +++ b/httpclient/src/main/java/org/apache/http/impl/client/AbstractHttpClient.java @@ -625,15 +625,41 @@ public abstract class AbstractHttpClient implements HttpClient { return execute(determineTarget(request), request, context); } - private HttpHost determineTarget(HttpUriRequest request) throws ClientProtocolException { + // Package-protected so can be accessed from unit tests + static HttpHost determineTarget(HttpUriRequest request) throws ClientProtocolException { // A null target may be acceptable if there is a default target. // Otherwise, the null target is detected in the director. HttpHost target = null; URI requestURI = request.getURI(); if (requestURI.isAbsolute()) { + int port = requestURI.getPort(); // may be overridden later String host = requestURI.getHost(); - int port = requestURI.getPort(); + if (host == null) { // normal parse failed; let's do it ourselves + // authority does not seem to care about the valid character-set for host names + host = requestURI.getAuthority(); + if (host != null) { + // Strip off any leading user credentials + int at = host.indexOf('@'); + if (at >= 0) { + if (host.length() > at+1 ) { + host = host.substring(at+1); + } else { + host = null; // @ on its own + } + } + // Extract the port suffix, if present + if (host != null) { + int colon = host.indexOf(':'); + if (colon >= 0) { + if (colon+1 < host.length()) { + port = Integer.parseInt(host.substring(colon+1)); + } + host = host.substring(0,colon); + } + } + } + } String scheme = requestURI.getScheme(); if (host == null) { throw new ClientProtocolException( diff --git a/httpclient/src/test/java/org/apache/http/impl/client/TestAbstractHttpClient.java b/httpclient/src/test/java/org/apache/http/impl/client/TestAbstractHttpClient.java new file mode 100644 index 000000000..b70b145d4 --- /dev/null +++ b/httpclient/src/test/java/org/apache/http/impl/client/TestAbstractHttpClient.java @@ -0,0 +1,63 @@ +/* + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.client; + +import static org.junit.Assert.assertEquals; + +import org.apache.http.HttpHost; +import org.apache.http.client.methods.HttpHead; +import org.junit.Test; + +/** + * Unit tests for {@link AbstractHttpClient}. + */ +public class TestAbstractHttpClient { + + @Test + public void testHTTPCLIENT_911() throws Exception{ + assertEquals(new HttpHost("localhost"),AbstractHttpClient.determineTarget(new HttpHead("http://localhost/abcd"))); + assertEquals(new HttpHost("localhost"),AbstractHttpClient.determineTarget(new HttpHead("http://localhost/abcd%3A"))); + + assertEquals(new HttpHost("local_host"),AbstractHttpClient.determineTarget(new HttpHead("http://local_host/abcd"))); + assertEquals(new HttpHost("local_host"),AbstractHttpClient.determineTarget(new HttpHead("http://local_host/abcd%3A"))); + + assertEquals(new HttpHost("localhost",8),AbstractHttpClient.determineTarget(new HttpHead("http://localhost:8/abcd"))); + assertEquals(new HttpHost("local_host",8),AbstractHttpClient.determineTarget(new HttpHead("http://local_host:8/abcd"))); + + // URI seems to OK with missing port number + assertEquals(new HttpHost("localhost"),AbstractHttpClient.determineTarget(new HttpHead("http://localhost:/abcd"))); + assertEquals(new HttpHost("local_host"),AbstractHttpClient.determineTarget(new HttpHead("http://local_host:/abcd"))); + + assertEquals(new HttpHost("localhost",8080),AbstractHttpClient.determineTarget(new HttpHead("http://user:pass@localhost:8080/abcd"))); + assertEquals(new HttpHost("local_host",8080),AbstractHttpClient.determineTarget(new HttpHead("http://user:pass@local_host:8080/abcd"))); + + assertEquals(new HttpHost("localhost",8080),AbstractHttpClient.determineTarget(new HttpHead("http://@localhost:8080/abcd"))); + assertEquals(new HttpHost("local_host",8080),AbstractHttpClient.determineTarget(new HttpHead("http://@local_host:8080/abcd"))); + + } +}