harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From telli...@apache.org
Subject svn commit: r415701 - in /incubator/harmony/enhanced/classlib/trunk/modules/luni/src: main/java/org/apache/harmony/luni/internal/net/www/protocol/http/ test/java/org/apache/harmony/tests/internal/net/www/protocol/http/
Date Tue, 20 Jun 2006 15:14:29 GMT
Author: tellison
Date: Tue Jun 20 08:14:29 2006
New Revision: 415701

URL: http://svn.apache.org/viewvc?rev=415701&view=rev
Log:
Apply patch HARMONY-624 ([classlib][luni] HttpURLConnection does not send proxy authorization
credentials)

Modified:
    incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpURLConnection.java
    incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/org/apache/harmony/tests/internal/net/www/protocol/http/HttpURLConnectionTest.java

Modified: incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpURLConnection.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpURLConnection.java?rev=415701&r1=415700&r2=415701&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpURLConnection.java
(original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpURLConnection.java
Tue Jun 20 08:14:29 2006
@@ -74,6 +74,8 @@
 
     private InputStream uis;
 
+    protected Socket socket;
+    
     OutputStream socketOut;
 
     OutputStream cacheOut;
@@ -582,23 +584,11 @@
         }
         if (socket == null) {
             // make direct connection
-            socket = getHTTPConnection(
-                    new InetSocketAddress(getHostName(), getHostPort()));
+            socket = getHTTPConnection(null);
         }
         socket.setSoTimeout(getReadTimeout());
+        setUpTransportIO(socket);
         connected = true;
-        socketOut = socket.getOutputStream();
-        is = new BufferedInputStream(socket.getInputStream());
-    }
-
-    /**
-     * Returns connected socket to be used for this HTTP connection.
-     * TODO: implement persistent connections.
-     */
-    protected Socket getHTTPConnection(SocketAddress address) throws IOException {
-        Socket socket = new Socket();
-        socket.connect(address, getConnectTimeout());
-        return socket;
     }
 
     /**
@@ -607,18 +597,35 @@
      */
     protected Socket getHTTPConnection(Proxy proxy) throws IOException {
         Socket socket;
-        if (proxy.type() == Proxy.Type.HTTP) {
-            socket = getHTTPConnection(proxy.address());
+        if (proxy == null || proxy.type() == Proxy.Type.DIRECT) {
+            this.proxy = null; // not using proxy
+            socket = new Socket();
+            socket.connect(
+                    new InetSocketAddress(getHostName(), getHostPort()),
+                    getConnectTimeout());
+        } else if (proxy.type() == Proxy.Type.HTTP) {
+            socket = new Socket();
+            socket.connect(proxy.address(), getConnectTimeout());
         } else {
-            // using DIRECT or SOCKS proxy
+            // using SOCKS proxy
             socket = new Socket(proxy);
             socket.connect(
-                    new InetSocketAddress(url.getHost(), url.getPort()),
+                    new InetSocketAddress(getHostName(), getHostPort()),
                     getConnectTimeout());
         }
         return socket;
     }
 
+    /**
+     * Sets up the data streams used to send request[s] and read response[s].
+     * @param socket socket to be used for connection
+     */
+    protected void setUpTransportIO(Socket socket) throws IOException {
+        this.socket = socket;
+        socketOut = socket.getOutputStream();
+        is = new BufferedInputStream(socket.getInputStream());
+    }
+
     // Tries to get head and body from cache, return true if has got this time or
     // already got before
     private boolean getFromCache() throws IOException {
@@ -675,7 +682,7 @@
         }
     }
 
-    void endRequest() throws IOException {
+    protected void endRequest() throws IOException {
         if (os != null) {
             os.close();
         }
@@ -990,7 +997,7 @@
         return result.toString();
     }
 
-    private String requestString() {
+    protected String requestString() {
         if (usingProxy() || proxyName != null) {
             return url.toString();
         }
@@ -1351,7 +1358,7 @@
 
     /**
      * Answer whether the connection should use a proxy server.
-     * 
+     *
      * Need to check both proxy* and http.proxy* because of change between JDK
      * 1.0 and JDK 1.1
      */
@@ -1362,7 +1369,7 @@
     /**
      * Handles an HTTP request along with its redirects and authentication
      */
-    void doRequest() throws IOException {
+    protected void doRequest() throws IOException {
         // do nothing if we've already sent the request
         if (sentRequest) {
             // If necessary, finish the request by
@@ -1384,48 +1391,58 @@
             if (!sendRequest()) {
                 return;
             }
-
-            // authorization failed ?
-            if (responseCode == HTTP_UNAUTHORIZED) { // keep asking for
+            // proxy authorization failed ?
+            if (responseCode == HTTP_PROXY_AUTH) {
+                if (!usingProxy()) {
+                    throw new IOException("Received HTTP_PROXY_AUTH (407) "
+                            +"code while not using proxy");
+                }
                 // username/password
                 // until authorized
-                String challenge = resHeader.get("WWW-Authenticate");
+                String challenge = resHeader.get("Proxy-Authenticate");
                 if (challenge == null) {
-                    break;
-                }
-                int idx = challenge.indexOf(" ");
-                String scheme = challenge.substring(0, idx);
-                int realm = challenge.indexOf("realm=\"") + 7;
-                String prompt = null;
-                if (realm != -1) {
-                    int end = challenge.indexOf('"', realm);
-                    if (end != -1) {
-                        prompt = challenge.substring(realm, end);
-                    }
+                    throw new IOException(
+                            "Received authentication challenge is null.");
                 }
-
-                // the following will use the user-defined authenticator to get
-                // the password
-                PasswordAuthentication pa = Authenticator
-                        .requestPasswordAuthentication(getHostAddress(),
-                                getHostPort(), url.getProtocol(), prompt,
-                                scheme);
-                if (pa == null) {
+                // drop everything and reconnect, might not be required for
+                // HTTP/1.1
+                endRequest();
+                closeSocket();
+                connected = false;
+                String credentials = getAuthorizationCredentials(challenge);
+                if (credentials == null) {
+                    // could not find credentials, end request cicle
                     break;
                 }
+                // set up the authorization credentials
+                setRequestProperty("Proxy-Authorization", credentials);
+                // continue to send request
+                continue;
+            }
+            // www authorization failed ?
+            if (responseCode == HTTP_UNAUTHORIZED) { // keep asking for
+                // username/password
+                // until authorized
+                String challenge = resHeader.get("WWW-Authenticate");
+                if (challenge == null) {
+                    throw new IOException(
+                            "Received authentication challenge is null.");
+                }
                 // drop everything and reconnect, might not be required for
                 // HTTP/1.1
                 endRequest();
                 closeSocket();
                 connected = false;
-                // base64 encode the username and password
-                byte[] bytes = (pa.getUserName() + ":" + new String(pa
-                        .getPassword())).getBytes("ISO8859_1");
-                String encoded = Base64.encode(bytes, "ISO8859_1");
-                setRequestProperty("Authorization", scheme + " " + encoded);
+                String credentials = getAuthorizationCredentials(challenge);
+                if (credentials == null) {
+                    // could not find credentials, end request cicle
+                    break;
+                }
+                // set up the authorization credentials
+                setRequestProperty("Authorization", credentials);
+                // continue to send request
                 continue;
             }
-
             // See if there is a server redirect to the URL, but only handle 1
             // level of
             // URL redirection from the server to avoid being caught in an
@@ -1434,7 +1451,8 @@
                 if ((responseCode == HTTP_MULT_CHOICE
                         || responseCode == HTTP_MOVED_PERM
                         || responseCode == HTTP_MOVED_TEMP
-                        || responseCode == HTTP_SEE_OTHER || responseCode == HTTP_USE_PROXY)
+                        || responseCode == HTTP_SEE_OTHER 
+                        || responseCode == HTTP_USE_PROXY)
                         && os == null) {
 
                     if (++redirect > 4) {
@@ -1466,13 +1484,43 @@
                     }
                 }
             }
-
             break;
         }
-
         // Cache the content stream and read the first chunked header
         getContentStream();
     }
+
+    // Returns the authorization credentials on the base of
+    // provided authorization challenge
+    private String getAuthorizationCredentials(String challenge) 
+            throws IOException {
+
+        int idx = challenge.indexOf(" ");
+        String scheme = challenge.substring(0, idx);
+        int realm = challenge.indexOf("realm=\"") + 7;
+        String prompt = null;
+        if (realm != -1) {
+            int end = challenge.indexOf('"', realm);
+            if (end != -1)
+                prompt = challenge.substring(realm, end);
+        }
+        // The following will use the user-defined authenticator to get
+        // the password
+        PasswordAuthentication pa = Authenticator
+                .requestPasswordAuthentication(getHostAddress(),
+                        getHostPort(), url.getProtocol(), prompt,
+                        scheme);
+        if (pa == null) {
+            // could not retrieve the credentials
+            return null;
+        }
+        // base64 encode the username and password
+        byte[] bytes = (pa.getUserName() + ":" + 
+                new String(pa.getPassword())).getBytes("ISO8859_1");
+        String encoded = Base64.encode(bytes, "ISO8859_1");
+        return scheme + " " + encoded;
+    }
+    
 
     private void setProxy(String proxy) {
         int index = proxy.indexOf(':');

Modified: incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/org/apache/harmony/tests/internal/net/www/protocol/http/HttpURLConnectionTest.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/org/apache/harmony/tests/internal/net/www/protocol/http/HttpURLConnectionTest.java?rev=415701&r1=415700&r2=415701&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/org/apache/harmony/tests/internal/net/www/protocol/http/HttpURLConnectionTest.java
(original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/org/apache/harmony/tests/internal/net/www/protocol/http/HttpURLConnectionTest.java
Tue Jun 20 08:14:29 2006
@@ -17,11 +17,14 @@
 package org.apache.harmony.tests.internal.net.www.protocol.http;
 
 import java.io.IOException;
+import java.net.Authenticator;
 import java.net.HttpURLConnection;
 import java.net.InetSocketAddress;
+import java.net.PasswordAuthentication;
 import java.net.Proxy;
 import java.net.ProxySelector;
 import java.net.ServerSocket;
+import java.net.Socket;
 import java.net.SocketAddress;
 import java.net.SocketTimeoutException;
 import java.net.URI;
@@ -70,6 +73,43 @@
         }
     }
 
+    static class MockProxyServer extends MockServer {
+
+        boolean acceptedAuthorizedRequest;
+        
+        public MockProxyServer(String name) throws Exception {
+            super(name);
+        }
+
+        public void run() {
+            try {
+                Socket socket = serverSocket.accept();
+                socket.setSoTimeout(1000);
+                byte[] buff = new byte[1024];
+                int num = socket.getInputStream().read(buff);
+                socket.getOutputStream().write((
+                    "HTTP/1.0 407 Proxy authentication required\n" 
+                  + "Proxy-authenticate: Basic realm=\"remotehost\"\n\n")
+                        .getBytes());
+                num = socket.getInputStream().read(buff);
+                if (num == -1) {
+                    // this connection was closed, create new one:
+                    socket = serverSocket.accept();
+                    socket.setSoTimeout(1000);
+                    num = socket.getInputStream().read(buff);
+                }
+                String request = new String(buff, 0, num);
+                acceptedAuthorizedRequest = 
+                    request.toLowerCase().indexOf("proxy-authorization:") > 0;
+                if (acceptedAuthorizedRequest) {
+                    socket.getOutputStream().write((
+                            "HTTP/1.1 200 OK\n\n").getBytes());
+                }
+            } catch (IOException e) {
+            }
+        }
+    }
+    
     /**
      * ProxySelector implementation used in the test.
      */
@@ -212,4 +252,39 @@
             ProxySelector.setDefault(defPS);
         }
     }
+
+    public void testProxyAuthorization() throws Exception {
+        // Set up test Authenticator
+        Authenticator.setDefault(new Authenticator() {
+            protected PasswordAuthentication getPasswordAuthentication() {
+                return new PasswordAuthentication(
+                    "user", "password".toCharArray());
+            }
+        });
+        
+        try {
+            MockProxyServer proxy = new MockProxyServer("ProxyServer");
+
+            URL url = new URL("http://remotehost:55555/requested.data");
+            HttpURLConnection connection = 
+                (HttpURLConnection) url.openConnection(
+                        new Proxy(Proxy.Type.HTTP, 
+                            new InetSocketAddress("localhost", proxy.port())));
+            connection.setConnectTimeout(1000);
+            connection.setReadTimeout(1000);
+
+            proxy.start();
+
+            connection.connect();
+            assertEquals("unexpected response code", 
+                    200, connection.getResponseCode());
+            proxy.join();
+            assertTrue("Connection did not send proxy authorization request",
+                    proxy.acceptedAuthorizedRequest);
+        } finally {
+            // remove previously set authenticator
+            Authenticator.setDefault(null);
+        }
+    }
+    
 }



Mime
View raw message