7025238: HttpURLConnection does not handle URLs with an empty path component.
authorarieber
Wed, 19 Jun 2013 17:41:12 -0700
changeset 18294 364814dc7391
parent 18293 5d768c1bf246
child 18295 4fed9f71df91
child 18527 882b39a21471
7025238: HttpURLConnection does not handle URLs with an empty path component. Summary: Prepend a '/' to file when path is empty Reviewed-by: chegar, khazra
jdk/src/share/classes/sun/net/www/http/HttpClient.java
jdk/test/sun/net/www/http/HttpClient/B7025238.java
--- a/jdk/src/share/classes/sun/net/www/http/HttpClient.java	Wed Jun 19 14:13:41 2013 -0700
+++ b/jdk/src/share/classes/sun/net/www/http/HttpClient.java	Wed Jun 19 17:41:12 2013 -0700
@@ -549,9 +549,7 @@
 
     public String getURLFile() throws IOException {
 
-        String fileName = url.getFile();
-        if ((fileName == null) || (fileName.length() == 0))
-            fileName = "/";
+        String fileName;
 
         /**
          * proxyDisabled is set by subclass HttpsClient!
@@ -575,8 +573,24 @@
                 result.append(url.getQuery());
             }
 
-            fileName =  result.toString();
+            fileName = result.toString();
+        } else {
+            fileName = url.getFile();
+
+            if ((fileName == null) || (fileName.length() == 0)) {
+                fileName = "/";
+            } else if (fileName.charAt(0) == '?') {
+                /* HTTP/1.1 spec says in 5.1.2. about Request-URI:
+                 * "Note that the absolute path cannot be empty; if
+                 * none is present in the original URI, it MUST be
+                 * given as "/" (the server root)."  So if the file
+                 * name here has only a query string, the path is
+                 * empty and we also have to add a "/".
+                 */
+                fileName = "/" + fileName;
+            }
         }
+
         if (fileName.indexOf('\n') == -1)
             return fileName;
         else
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/net/www/http/HttpClient/B7025238.java	Wed Jun 19 17:41:12 2013 -0700
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import com.sun.net.httpserver.*;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.*;
+import java.util.concurrent.Executors;
+
+/*
+ * @test
+ * @bug 7025238
+ * @summary HttpURLConnection does not handle URLs with an empty path component
+ */
+public class B7025238 {
+
+    public static void main(String[] args) throws Exception {
+        new B7025238().runTest();
+    }
+
+    public void runTest() throws Exception {
+        Server s = null;
+        try {
+            s = new Server();
+            s.startServer();
+            URL url = new URL("http://localhost:" + s.getPort() + "?q=test");
+            HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
+            urlConnection.setRequestMethod("GET");
+            urlConnection.connect();
+            int code = urlConnection.getResponseCode();
+
+            if (code != 200) {
+                throw new RuntimeException("Test failed!");
+            }
+        } finally {
+            s.stopServer();
+        }
+    }
+
+    class Server {
+        HttpServer server;
+
+        public void startServer() {
+            InetSocketAddress addr = new InetSocketAddress(0);
+            try {
+                server = HttpServer.create(addr, 0);
+            } catch (IOException ioe) {
+                throw new RuntimeException("Server could not be created");
+            }
+
+            server.createContext("/", new EmptyPathHandler());
+            server.start();
+        }
+
+        public int getPort() {
+            return server.getAddress().getPort();
+        }
+
+        public void stopServer() {
+            server.stop(0);
+        }
+    }
+
+    class EmptyPathHandler implements HttpHandler {
+
+        @Override
+        public void handle(HttpExchange exchange) throws IOException {
+            String requestMethod = exchange.getRequestMethod();
+
+            if (requestMethod.equalsIgnoreCase("GET")) {
+                Headers responseHeaders = exchange.getResponseHeaders();
+                responseHeaders.set("Content-Type", "text/plain");
+                exchange.sendResponseHeaders(200, 0);
+                OutputStream os = exchange.getResponseBody();
+                String str = "Hello from server!";
+                os.write(str.getBytes());
+                os.flush();
+                os.close();
+            }
+        }
+    }
+}
+