Moved target host extraction code to a re-usable static method in the URIUtils class

git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1053679 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Oleg Kalnichevski 2010-12-29 17:35:36 +00:00
parent 21aae1dfe2
commit 261fb7d7db
4 changed files with 77 additions and 95 deletions

View File

@ -277,6 +277,56 @@ public class URIUtils {
} }
} }
/**
* Extracts target host from the given {@link URI}.
*
* @param uri
* @return the target host if the URI is absolute or <code>null</null> if the URI is
* relative or does not contain a valid host name.
*
* @since 4.1
*/
public static HttpHost exctractHost(final URI uri) {
if (uri == null) {
return null;
}
HttpHost target = null;
if (uri.isAbsolute()) {
int port = uri.getPort(); // may be overridden later
String host = uri.getHost();
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 = uri.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 = uri.getScheme();
if (host != null) {
target = new HttpHost(host, port, scheme);
}
}
return target;
}
/** /**
* This class should not be instantiated. * This class should not be instantiated.
*/ */

View File

@ -57,6 +57,7 @@ import org.apache.http.client.HttpClient;
import org.apache.http.client.HttpRequestRetryHandler; import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.UserTokenHandler; import org.apache.http.client.UserTokenHandler;
import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.utils.URIUtils;
import org.apache.http.conn.ClientConnectionManager; import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.ConnectionKeepAliveStrategy; import org.apache.http.conn.ConnectionKeepAliveStrategy;
import org.apache.http.conn.routing.HttpRoutePlanner; import org.apache.http.conn.routing.HttpRoutePlanner;
@ -626,47 +627,18 @@ public abstract class AbstractHttpClient implements HttpClient {
return execute(determineTarget(request), request, context); return execute(determineTarget(request), request, context);
} }
// Package-protected so can be accessed from unit tests private static HttpHost determineTarget(HttpUriRequest request) throws ClientProtocolException {
static HttpHost determineTarget(HttpUriRequest request) throws ClientProtocolException {
// A null target may be acceptable if there is a default target. // A null target may be acceptable if there is a default target.
// Otherwise, the null target is detected in the director. // Otherwise, the null target is detected in the director.
HttpHost target = null; HttpHost target = null;
URI requestURI = request.getURI(); URI requestURI = request.getURI();
if (requestURI.isAbsolute()) { if (requestURI.isAbsolute()) {
int port = requestURI.getPort(); // may be overridden later target = URIUtils.exctractHost(requestURI);
String host = requestURI.getHost(); if (target == null) {
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( throw new ClientProtocolException(
"URI does not specify a valid host name: " + requestURI); "URI does not specify a valid host name: " + requestURI);
} }
target = new HttpHost(host, port, scheme);
} }
return target; return target;
} }

View File

@ -317,4 +317,27 @@ public class TestURIUtils {
"http://s/mid/content=5/../6").toString()); "http://s/mid/content=5/../6").toString());
} }
@Test
public void testHTTPCLIENT_911() throws Exception{
Assert.assertEquals(new HttpHost("localhost"),URIUtils.exctractHost(new URI("http://localhost/abcd")));
Assert.assertEquals(new HttpHost("localhost"),URIUtils.exctractHost(new URI("http://localhost/abcd%3A")));
Assert.assertEquals(new HttpHost("local_host"),URIUtils.exctractHost(new URI("http://local_host/abcd")));
Assert.assertEquals(new HttpHost("local_host"),URIUtils.exctractHost(new URI("http://local_host/abcd%3A")));
Assert.assertEquals(new HttpHost("localhost",8),URIUtils.exctractHost(new URI("http://localhost:8/abcd")));
Assert.assertEquals(new HttpHost("local_host",8),URIUtils.exctractHost(new URI("http://local_host:8/abcd")));
// URI seems to OK with missing port number
Assert.assertEquals(new HttpHost("localhost"),URIUtils.exctractHost(new URI("http://localhost:/abcd")));
Assert.assertEquals(new HttpHost("local_host"),URIUtils.exctractHost(new URI("http://local_host:/abcd")));
Assert.assertEquals(new HttpHost("localhost",8080),URIUtils.exctractHost(new URI("http://user:pass@localhost:8080/abcd")));
Assert.assertEquals(new HttpHost("local_host",8080),URIUtils.exctractHost(new URI("http://user:pass@local_host:8080/abcd")));
Assert.assertEquals(new HttpHost("localhost",8080),URIUtils.exctractHost(new URI("http://@localhost:8080/abcd")));
Assert.assertEquals(new HttpHost("local_host",8080),URIUtils.exctractHost(new URI("http://@local_host:8080/abcd")));
}
} }

View File

@ -1,63 +0,0 @@
/*
* ====================================================================
* 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
* <http://www.apache.org/>.
*
*/
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")));
}
}