1 /*
   2  * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.net.www.protocol.file;
  27 
  28 import java.net.InetAddress;
  29 import java.net.URLConnection;
  30 import java.net.URL;
  31 import java.net.Proxy;
  32 import java.net.MalformedURLException;
  33 import java.net.URLStreamHandler;
  34 import java.io.InputStream;
  35 import java.io.IOException;
  36 import sun.net.www.ParseUtil;
  37 import java.io.File;
  38 
  39 /**
  40  * Open an file input stream given a URL.
  41  * @author      James Gosling
  42  */
  43 public class Handler extends URLStreamHandler {
  44 
  45     private String getHost(URL url) {
  46         String host = url.getHost();
  47         if (host == null)
  48             host = "";
  49         return host;
  50     }
  51 
  52 
  53     protected void parseURL(URL u, String spec, int start, int limit) {
  54         /*
  55          * Ugly backwards compatibility. Flip any file separator
  56          * characters to be forward slashes. This is a nop on Unix
  57          * and "fixes" win32 file paths. According to RFC 2396,
  58          * only forward slashes may be used to represent hierarchy
  59          * separation in a URL but previous releases unfortunately
  60          * performed this "fixup" behavior in the file URL parsing code
  61          * rather than forcing this to be fixed in the caller of the URL
  62          * class where it belongs. Since backslash is an "unwise"
  63          * character that would normally be encoded if literally intended
  64          * as a non-seperator character the damage of veering away from the
  65          * specification is presumably limited.
  66          */
  67         super.parseURL(u, spec.replace(File.separatorChar, '/'), start, limit);
  68     }
  69 
  70     public synchronized URLConnection openConnection(URL url)
  71         throws IOException {
  72         return openConnection(url, null);
  73     }
  74 
  75     public synchronized URLConnection openConnection(URL url, Proxy p)
  76            throws IOException {
  77 
  78         String path;
  79         String file = url.getFile();
  80         String host = url.getHost();
  81 
  82         path = ParseUtil.decode(file);
  83         path = path.replace('/', '\\');
  84         path = path.replace('|', ':');
  85 
  86         if ((host == null) || host.equals("") ||
  87                 host.equalsIgnoreCase("localhost") ||
  88                 host.equals("~")) {
  89            return createFileURLConnection(url, new File(path));
  90         }
  91 
  92         /*
  93          * attempt to treat this as a UNC path. See 4180841
  94          */
  95         path = "\\\\" + host + path;
  96         File f = new File(path);
  97         if (f.exists()) {
  98             return createFileURLConnection(url, f);
  99         }
 100 
 101         /*
 102          * Now attempt an ftp connection.
 103          */
 104         URLConnection uc;
 105         URL newurl;
 106 
 107         try {
 108             newurl = new URL("ftp", host, file +
 109                             (url.getRef() == null ? "":
 110                             "#" + url.getRef()));
 111             if (p != null) {
 112                 uc = newurl.openConnection(p);
 113             } else {
 114                 uc = newurl.openConnection();
 115             }
 116         } catch (IOException e) {
 117             uc = null;
 118         }
 119         if (uc == null) {
 120             throw new IOException("Unable to connect to: " +
 121                                         url.toExternalForm());
 122         }
 123         return uc;
 124     }
 125 
 126     /**
 127      * Template method to be overridden by Java Plug-in. [stanleyh]
 128      */
 129     protected URLConnection createFileURLConnection(URL url, File file) {
 130         return new FileURLConnection(url, file);
 131     }
 132 
 133     /**
 134      * Compares the host components of two URLs.
 135      * @param u1 the URL of the first host to compare
 136      * @param u2 the URL of the second host to compare
 137      * @return  {@code true} if and only if they
 138      * are equal, {@code false} otherwise.
 139      */
 140     protected boolean hostsEqual(URL u1, URL u2) {
 141         /*
 142          * Special case for file: URLs
 143          * per RFC 1738 no hostname is equivalent to 'localhost'
 144          * i.e. file:///path is equal to file://localhost/path
 145          */
 146         String s1 = u1.getHost();
 147         String s2 = u2.getHost();
 148         if ("localhost".equalsIgnoreCase(s1) && ( s2 == null || "".equals(s2)))
 149             return true;
 150         if ("localhost".equalsIgnoreCase(s2) && ( s1 == null || "".equals(s1)))
 151             return true;
 152         return super.hostsEqual(u1, u2);
 153     }
 154 }