You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2012/12/20 13:56:26 UTC

svn commit: r1424444 - in /httpcomponents/httpclient/branches/4.2.x: ./ httpclient/src/main/java/org/apache/http/impl/auth/ httpclient/src/main/java/org/apache/http/impl/client/ httpclient/src/test/java/org/apache/http/client/entity/ httpclient/src/tes...

Author: olegk
Date: Thu Dec 20 12:56:25 2012
New Revision: 1424444

URL: http://svn.apache.org/viewvc?rev=1424444&view=rev
Log:
HTTPCLIENT-1284: HttpClient incorrectly generates Host header when physical connection route differs from the host name specified in the request URI

Added:
    httpcomponents/httpclient/branches/4.2.x/httpclient/src/test/java/org/apache/http/impl/client/TestCookieVirtualHost.java   (with props)
Modified:
    httpcomponents/httpclient/branches/4.2.x/RELEASE_NOTES.txt
    httpcomponents/httpclient/branches/4.2.x/httpclient/src/main/java/org/apache/http/impl/auth/NTLMEngineImpl.java
    httpcomponents/httpclient/branches/4.2.x/httpclient/src/main/java/org/apache/http/impl/client/DefaultRequestDirector.java
    httpcomponents/httpclient/branches/4.2.x/httpclient/src/test/java/org/apache/http/client/entity/TestGZip.java
    httpcomponents/httpclient/branches/4.2.x/httpclient/src/test/java/org/apache/http/impl/client/TestDefaultClientRequestDirector.java

Modified: httpcomponents/httpclient/branches/4.2.x/RELEASE_NOTES.txt
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/branches/4.2.x/RELEASE_NOTES.txt?rev=1424444&r1=1424443&r2=1424444&view=diff
==============================================================================
--- httpcomponents/httpclient/branches/4.2.x/RELEASE_NOTES.txt (original)
+++ httpcomponents/httpclient/branches/4.2.x/RELEASE_NOTES.txt Thu Dec 20 12:56:25 2012
@@ -1,6 +1,10 @@
 Changes since 4.2.2
 -------------------
 
+* [HTTPCLIENT-1284] HttpClient incorrectly generates Host header when physical connection
+  route differs from the host name specified in the request URI. 
+  Contributed by Oleg Kalnichevski <olegk at apache.org>
+
 * Kerberos and SPNego auth schemes use incorrect authorization header name when authenticating
   with a proxy.
   Contributed by Oleg Kalnichevski <olegk at apache.org>

Modified: httpcomponents/httpclient/branches/4.2.x/httpclient/src/main/java/org/apache/http/impl/auth/NTLMEngineImpl.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/branches/4.2.x/httpclient/src/main/java/org/apache/http/impl/auth/NTLMEngineImpl.java?rev=1424444&r1=1424443&r2=1424444&view=diff
==============================================================================
--- httpcomponents/httpclient/branches/4.2.x/httpclient/src/main/java/org/apache/http/impl/auth/NTLMEngineImpl.java (original)
+++ httpcomponents/httpclient/branches/4.2.x/httpclient/src/main/java/org/apache/http/impl/auth/NTLMEngineImpl.java Thu Dec 20 12:56:25 2012
@@ -33,7 +33,6 @@ import java.util.Locale;
 
 import javax.crypto.Cipher;
 import javax.crypto.spec.SecretKeySpec;
-import javax.crypto.Mac;
 
 import org.apache.commons.codec.binary.Base64;
 import org.apache.http.util.EncodingUtils;

Modified: httpcomponents/httpclient/branches/4.2.x/httpclient/src/main/java/org/apache/http/impl/client/DefaultRequestDirector.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/branches/4.2.x/httpclient/src/main/java/org/apache/http/impl/client/DefaultRequestDirector.java?rev=1424444&r1=1424443&r2=1424444&view=diff
==============================================================================
--- httpcomponents/httpclient/branches/4.2.x/httpclient/src/main/java/org/apache/http/impl/client/DefaultRequestDirector.java (original)
+++ httpcomponents/httpclient/branches/4.2.x/httpclient/src/main/java/org/apache/http/impl/client/DefaultRequestDirector.java Thu Dec 20 12:56:25 2012
@@ -491,20 +491,24 @@ public class DefaultRequestDirector impl
                             new BasicScheme(), new UsernamePasswordCredentials(userinfo));
                 }
 
-                // Reset headers on the request wrapper
-                wrapper.resetHeaders();
-
-                // Re-write request URI if needed
-                rewriteRequestURI(wrapper, route);
-
-                // Use virtual host if set
-                target = virtualHost;
-
+                HttpHost proxy = route.getProxyHost();
+                if (virtualHost != null) {
+                    target = virtualHost;
+                } else {
+                    URI requestURI = wrapper.getURI();
+                    if (requestURI.isAbsolute()) {
+                        target = new HttpHost(
+                                requestURI.getHost(), requestURI.getPort(), requestURI.getScheme());
+                    }
+                }
                 if (target == null) {
                     target = route.getTargetHost();
                 }
 
-                HttpHost proxy = route.getProxyHost();
+                // Reset headers on the request wrapper
+                wrapper.resetHeaders();
+                // Re-write request URI if needed
+                rewriteRequestURI(wrapper, route);
 
                 // Populate the execution context
                 context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, target);

Modified: httpcomponents/httpclient/branches/4.2.x/httpclient/src/test/java/org/apache/http/client/entity/TestGZip.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/branches/4.2.x/httpclient/src/test/java/org/apache/http/client/entity/TestGZip.java?rev=1424444&r1=1424443&r2=1424444&view=diff
==============================================================================
--- httpcomponents/httpclient/branches/4.2.x/httpclient/src/test/java/org/apache/http/client/entity/TestGZip.java (original)
+++ httpcomponents/httpclient/branches/4.2.x/httpclient/src/test/java/org/apache/http/client/entity/TestGZip.java Thu Dec 20 12:56:25 2012
@@ -27,7 +27,6 @@
 
 package org.apache.http.client.entity;
 
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.concurrent.atomic.AtomicBoolean;

Added: httpcomponents/httpclient/branches/4.2.x/httpclient/src/test/java/org/apache/http/impl/client/TestCookieVirtualHost.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/branches/4.2.x/httpclient/src/test/java/org/apache/http/impl/client/TestCookieVirtualHost.java?rev=1424444&view=auto
==============================================================================
--- httpcomponents/httpclient/branches/4.2.x/httpclient/src/test/java/org/apache/http/impl/client/TestCookieVirtualHost.java (added)
+++ httpcomponents/httpclient/branches/4.2.x/httpclient/src/test/java/org/apache/http/impl/client/TestCookieVirtualHost.java Thu Dec 20 12:56:25 2012
@@ -0,0 +1,158 @@
+/*
+ * ====================================================================
+ *
+ *  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 java.io.IOException;
+import java.net.URI;
+import java.util.List;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpException;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.HttpVersion;
+import org.apache.http.client.CookieStore;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.params.ClientPNames;
+import org.apache.http.client.params.CookiePolicy;
+import org.apache.http.client.protocol.ClientContext;
+import org.apache.http.cookie.Cookie;
+import org.apache.http.impl.client.BasicCookieStore;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.localserver.BasicServerTestBase;
+import org.apache.http.localserver.LocalTestServer;
+import org.apache.http.message.BasicHeader;
+import org.apache.http.protocol.BasicHttpContext;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpRequestHandler;
+import org.apache.http.util.EntityUtils;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * This class tests cookie matching when using Virtual Host.
+ */
+public class TestCookieVirtualHost extends BasicServerTestBase {
+
+    @Before
+    public void setUp() throws Exception {
+        this.localServer = new LocalTestServer(null, null);
+        this.localServer.registerDefaultHandlers();
+        this.localServer.start();
+        this.httpclient = new DefaultHttpClient();
+    }
+
+    @Test
+    public void testCookieMatchingWithVirtualHosts() throws Exception {
+        this.localServer.register("*", new HttpRequestHandler() {
+            public void handle(
+                    final HttpRequest request,
+                    final HttpResponse response,
+                    final HttpContext context) throws HttpException, IOException {
+
+                int n = Integer.parseInt(request.getFirstHeader("X-Request").getValue());
+                switch (n) {
+                case 1:
+                    // Assert Host is forwarded from URI
+                    Assert.assertEquals("app.mydomain.fr", request
+                            .getFirstHeader("Host").getValue());
+
+                    response.setStatusLine(HttpVersion.HTTP_1_1,
+                            HttpStatus.SC_OK);
+                    // Respond with Set-Cookie on virtual host domain. This
+                    // should be valid.
+                    response.addHeader(new BasicHeader("Set-Cookie",
+                            "name1=value1; domain=mydomain.fr; path=/"));
+                    break;
+
+                case 2:
+                    // Assert Host is still forwarded from URI
+                    Assert.assertEquals("app.mydomain.fr", request
+                            .getFirstHeader("Host").getValue());
+
+                    // We should get our cookie back.
+                    Assert.assertNotNull("We must get a cookie header",
+                            request.getFirstHeader("Cookie"));
+                    response.setStatusLine(HttpVersion.HTTP_1_1,
+                            HttpStatus.SC_OK);
+                    break;
+
+                case 3:
+                    // Assert Host is forwarded from URI
+                    Assert.assertEquals("app.mydomain.fr", request
+                            .getFirstHeader("Host").getValue());
+
+                    response.setStatusLine(HttpVersion.HTTP_1_1,
+                            HttpStatus.SC_OK);
+                    break;
+                }
+            }
+
+        });
+
+        this.httpclient.getParams().setParameter(ClientPNames.COOKIE_POLICY,
+                CookiePolicy.BEST_MATCH);
+
+        CookieStore cookieStore = new BasicCookieStore();
+        HttpContext context = new BasicHttpContext();
+        context.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
+
+        // First request : retrieve a domain cookie from remote server.
+        URI uri = new URI("http://app.mydomain.fr");
+        HttpRequest httpRequest = new HttpGet(uri);
+        httpRequest.addHeader("X-Request", "1");
+        HttpResponse response1 = this.httpclient.execute(getServerHttp(),
+                httpRequest, context);
+        HttpEntity e1 = response1.getEntity();
+        EntityUtils.consume(e1);
+
+        // We should have one cookie set on domain.
+        List<Cookie> cookies = cookieStore.getCookies();
+        Assert.assertNotNull(cookies);
+        Assert.assertEquals(1, cookies.size());
+        Assert.assertEquals("name1", cookies.get(0).getName());
+
+        // Second request : send the cookie back.
+        uri = new URI("http://app.mydomain.fr");
+        httpRequest = new HttpGet(uri);
+        httpRequest.addHeader("X-Request", "2");
+        HttpResponse response2 = this.httpclient.execute(getServerHttp(),
+                httpRequest, context);
+        HttpEntity e2 = response2.getEntity();
+        EntityUtils.consume(e2);
+
+        // Third request : Host header
+        uri = new URI("http://app.mydomain.fr");
+        httpRequest = new HttpGet(uri);
+        httpRequest.addHeader("X-Request", "3");
+        HttpResponse response3 = this.httpclient.execute(getServerHttp(),
+                httpRequest, context);
+        HttpEntity e3 = response3.getEntity();
+        EntityUtils.consume(e3);
+    }
+
+}

Propchange: httpcomponents/httpclient/branches/4.2.x/httpclient/src/test/java/org/apache/http/impl/client/TestCookieVirtualHost.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpclient/branches/4.2.x/httpclient/src/test/java/org/apache/http/impl/client/TestCookieVirtualHost.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpclient/branches/4.2.x/httpclient/src/test/java/org/apache/http/impl/client/TestCookieVirtualHost.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: httpcomponents/httpclient/branches/4.2.x/httpclient/src/test/java/org/apache/http/impl/client/TestDefaultClientRequestDirector.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/branches/4.2.x/httpclient/src/test/java/org/apache/http/impl/client/TestDefaultClientRequestDirector.java?rev=1424444&r1=1424443&r2=1424444&view=diff
==============================================================================
--- httpcomponents/httpclient/branches/4.2.x/httpclient/src/test/java/org/apache/http/impl/client/TestDefaultClientRequestDirector.java (original)
+++ httpcomponents/httpclient/branches/4.2.x/httpclient/src/test/java/org/apache/http/impl/client/TestDefaultClientRequestDirector.java Thu Dec 20 12:56:25 2012
@@ -105,7 +105,6 @@ public class TestDefaultClientRequestDir
     @Test
     public void testDefaultHostHeader() throws Exception {
         int port = this.localServer.getServiceAddress().getPort();
-        String hostname = getServerHttp().getHostName();
         this.localServer.register("*", new SimpleService());
 
         HttpContext context = new BasicHttpContext();
@@ -124,7 +123,7 @@ public class TestDefaultClientRequestDir
         Header[] headers = reqWrapper.getHeaders("host");
         Assert.assertNotNull(headers);
         Assert.assertEquals(1, headers.length);
-        Assert.assertEquals(hostname + ":" + port, headers[0].getValue());
+        Assert.assertEquals("localhost:" + port, headers[0].getValue());
     }
 
     @Test