src/java.base/share/classes/java/net/URL.java
branchdatagramsocketimpl-branch
changeset 58678 9cf78a70fa4f
parent 54696 0907dce4b90e
child 58679 9c3209ff7550
equal deleted inserted replaced
58677:13588c901957 58678:9cf78a70fa4f
    43 import java.util.ServiceConfigurationError;
    43 import java.util.ServiceConfigurationError;
    44 import java.util.ServiceLoader;
    44 import java.util.ServiceLoader;
    45 
    45 
    46 import jdk.internal.access.JavaNetURLAccess;
    46 import jdk.internal.access.JavaNetURLAccess;
    47 import jdk.internal.access.SharedSecrets;
    47 import jdk.internal.access.SharedSecrets;
       
    48 import sun.net.util.IPAddressUtil;
    48 import sun.security.util.SecurityConstants;
    49 import sun.security.util.SecurityConstants;
    49 import sun.security.action.GetPropertyAction;
    50 import sun.security.action.GetPropertyAction;
    50 
    51 
    51 /**
    52 /**
    52  * Class {@code URL} represents a Uniform Resource
    53  * Class {@code URL} represents a Uniform Resource
   172  * @since 1.0
   173  * @since 1.0
   173  */
   174  */
   174 public final class URL implements java.io.Serializable {
   175 public final class URL implements java.io.Serializable {
   175 
   176 
   176     static final String BUILTIN_HANDLERS_PREFIX = "sun.net.www.protocol";
   177     static final String BUILTIN_HANDLERS_PREFIX = "sun.net.www.protocol";
       
   178     @java.io.Serial
   177     static final long serialVersionUID = -7627629688361524110L;
   179     static final long serialVersionUID = -7627629688361524110L;
   178 
   180 
   179     /**
   181     /**
   180      * The property which specifies the package prefix list to be scanned
   182      * The property which specifies the package prefix list to be scanned
   181      * for protocol handlers.  The value of this property (if any) should
   183      * for protocol handlers.  The value of this property (if any) should
   325      *     subclass of {@code URLStreamHandler}, then a
   327      *     subclass of {@code URLStreamHandler}, then a
   326      *     {@code MalformedURLException} is thrown.
   328      *     {@code MalformedURLException} is thrown.
   327      * </ol>
   329      * </ol>
   328      *
   330      *
   329      * <p>Protocol handlers for the following protocols are guaranteed
   331      * <p>Protocol handlers for the following protocols are guaranteed
   330      * to exist on the search path :-
   332      * to exist on the search path:
   331      * <blockquote><pre>
   333      * <ul>
   332      *     http, https, file, and jar
   334      * <li>{@code http}</li>
   333      * </pre></blockquote>
   335      * <li>{@code https}</li>
       
   336      * <li>{@code file}</li>
       
   337      * <li>{@code jar}</li>
       
   338      * </ul>
   334      * Protocol handlers for additional protocols may also be  available.
   339      * Protocol handlers for additional protocols may also be  available.
   335      * Some protocol handlers, for example those used for loading platform
   340      * Some protocol handlers, for example those used for loading platform
   336      * classes or classes on the class path, may not be overridden. The details
   341      * classes or classes on the class path, may not be overridden. The details
   337      * of such restrictions, and when those restrictions apply (during
   342      * of such restrictions, and when those restrictions apply (during
   338      * initialization of the runtime for example), are implementation specific
   343      * initialization of the runtime for example), are implementation specific
   342      *
   347      *
   343      * @param      protocol   the name of the protocol to use.
   348      * @param      protocol   the name of the protocol to use.
   344      * @param      host       the name of the host.
   349      * @param      host       the name of the host.
   345      * @param      port       the port number on the host.
   350      * @param      port       the port number on the host.
   346      * @param      file       the file on the host
   351      * @param      file       the file on the host
   347      * @exception  MalformedURLException  if an unknown protocol or the port
   352      * @throws     MalformedURLException  if an unknown protocol or the port
   348      *                  is a negative number other than -1
   353      *                  is a negative number other than -1
   349      * @see        java.lang.System#getProperty(java.lang.String)
   354      * @see        java.lang.System#getProperty(java.lang.String)
   350      * @see        java.net.URL#setURLStreamHandlerFactory(
   355      * @see        java.net.URL#setURLStreamHandlerFactory(
   351      *                  java.net.URLStreamHandlerFactory)
   356      *                  java.net.URLStreamHandlerFactory)
   352      * @see        java.net.URLStreamHandler
   357      * @see        java.net.URLStreamHandler
   371      * No validation of the inputs is performed by this constructor.
   376      * No validation of the inputs is performed by this constructor.
   372      *
   377      *
   373      * @param      protocol   the name of the protocol to use.
   378      * @param      protocol   the name of the protocol to use.
   374      * @param      host       the name of the host.
   379      * @param      host       the name of the host.
   375      * @param      file       the file on the host.
   380      * @param      file       the file on the host.
   376      * @exception  MalformedURLException  if an unknown protocol is specified.
   381      * @throws     MalformedURLException  if an unknown protocol is specified.
   377      * @see        java.net.URL#URL(java.lang.String, java.lang.String,
   382      * @see        java.net.URL#URL(java.lang.String, java.lang.String,
   378      *                  int, java.lang.String)
   383      *                  int, java.lang.String)
   379      */
   384      */
   380     public URL(String protocol, String host, String file)
   385     public URL(String protocol, String host, String file)
   381             throws MalformedURLException {
   386             throws MalformedURLException {
   405      * @param      protocol   the name of the protocol to use.
   410      * @param      protocol   the name of the protocol to use.
   406      * @param      host       the name of the host.
   411      * @param      host       the name of the host.
   407      * @param      port       the port number on the host.
   412      * @param      port       the port number on the host.
   408      * @param      file       the file on the host
   413      * @param      file       the file on the host
   409      * @param      handler    the stream handler for the URL.
   414      * @param      handler    the stream handler for the URL.
   410      * @exception  MalformedURLException  if an unknown protocol or the port
   415      * @throws     MalformedURLException  if an unknown protocol or the port
   411                         is a negative number other than -1
   416                         is a negative number other than -1
   412      * @exception  SecurityException
   417      * @throws     SecurityException
   413      *        if a security manager exists and its
   418      *        if a security manager exists and its
   414      *        {@code checkPermission} method doesn't allow
   419      *        {@code checkPermission} method doesn't allow
   415      *        specifying a stream handler explicitly.
   420      *        specifying a stream handler explicitly.
   416      * @see        java.lang.System#getProperty(java.lang.String)
   421      * @see        java.lang.System#getProperty(java.lang.String)
   417      * @see        java.net.URL#setURLStreamHandlerFactory(
   422      * @see        java.net.URL#setURLStreamHandlerFactory(
   464         } else {
   469         } else {
   465             this.path = file;
   470             this.path = file;
   466             this.file = path;
   471             this.file = path;
   467         }
   472         }
   468 
   473 
   469         // Note: we don't do validation of the URL here. Too risky to change
   474         // Note: we don't do full validation of the URL here. Too risky to change
   470         // right now, but worth considering for future reference. -br
   475         // right now, but worth considering for future reference. -br
   471         if (handler == null &&
   476         if (handler == null &&
   472             (handler = getURLStreamHandler(protocol)) == null) {
   477             (handler = getURLStreamHandler(protocol)) == null) {
   473             throw new MalformedURLException("unknown protocol: " + protocol);
   478             throw new MalformedURLException("unknown protocol: " + protocol);
   474         }
   479         }
   475         this.handler = handler;
   480         this.handler = handler;
       
   481         if (host != null && isBuiltinStreamHandler(handler)) {
       
   482             String s = IPAddressUtil.checkExternalForm(this);
       
   483             if (s != null) {
       
   484                 throw new MalformedURLException(s);
       
   485             }
       
   486         }
       
   487         if ("jar".equalsIgnoreCase(protocol)) {
       
   488             if (handler instanceof sun.net.www.protocol.jar.Handler) {
       
   489                 // URL.openConnection() would throw a confusing exception
       
   490                 // so generate a better exception here instead.
       
   491                 String s = ((sun.net.www.protocol.jar.Handler) handler).checkNestedProtocol(file);
       
   492                 if (s != null) {
       
   493                     throw new MalformedURLException(s);
       
   494                 }
       
   495             }
       
   496         }
   476     }
   497     }
   477 
   498 
   478     /**
   499     /**
   479      * Creates a {@code URL} object from the {@code String}
   500      * Creates a {@code URL} object from the {@code String}
   480      * representation.
   501      * representation.
   481      * <p>
   502      * <p>
   482      * This constructor is equivalent to a call to the two-argument
   503      * This constructor is equivalent to a call to the two-argument
   483      * constructor with a {@code null} first argument.
   504      * constructor with a {@code null} first argument.
   484      *
   505      *
   485      * @param      spec   the {@code String} to parse as a URL.
   506      * @param      spec   the {@code String} to parse as a URL.
   486      * @exception  MalformedURLException  if no protocol is specified, or an
   507      * @throws     MalformedURLException  if no protocol is specified, or an
   487      *               unknown protocol is found, or {@code spec} is {@code null},
   508      *               unknown protocol is found, or {@code spec} is {@code null},
   488      *               or the parsed URL fails to comply with the specific syntax
   509      *               or the parsed URL fails to comply with the specific syntax
   489      *               of the associated protocol.
   510      *               of the associated protocol.
   490      * @see        java.net.URL#URL(java.net.URL, java.lang.String)
   511      * @see        java.net.URL#URL(java.net.URL, java.lang.String)
   491      */
   512      */
   530      * <p>
   551      * <p>
   531      * For a more detailed description of URL parsing, refer to RFC2396.
   552      * For a more detailed description of URL parsing, refer to RFC2396.
   532      *
   553      *
   533      * @param      context   the context in which to parse the specification.
   554      * @param      context   the context in which to parse the specification.
   534      * @param      spec      the {@code String} to parse as a URL.
   555      * @param      spec      the {@code String} to parse as a URL.
   535      * @exception  MalformedURLException  if no protocol is specified, or an
   556      * @throws     MalformedURLException  if no protocol is specified, or an
   536      *               unknown protocol is found, or {@code spec} is {@code null},
   557      *               unknown protocol is found, or {@code spec} is {@code null},
   537      *               or the parsed URL fails to comply with the specific syntax
   558      *               or the parsed URL fails to comply with the specific syntax
   538      *               of the associated protocol.
   559      *               of the associated protocol.
   539      * @see        java.net.URL#URL(java.lang.String, java.lang.String,
   560      * @see        java.net.URL#URL(java.lang.String, java.lang.String,
   540      *                  int, java.lang.String)
   561      *                  int, java.lang.String)
   552      * occurs as with the two argument constructor.
   573      * occurs as with the two argument constructor.
   553      *
   574      *
   554      * @param      context   the context in which to parse the specification.
   575      * @param      context   the context in which to parse the specification.
   555      * @param      spec      the {@code String} to parse as a URL.
   576      * @param      spec      the {@code String} to parse as a URL.
   556      * @param      handler   the stream handler for the URL.
   577      * @param      handler   the stream handler for the URL.
   557      * @exception  MalformedURLException  if no protocol is specified, or an
   578      * @throws     MalformedURLException  if no protocol is specified, or an
   558      *               unknown protocol is found, or {@code spec} is {@code null},
   579      *               unknown protocol is found, or {@code spec} is {@code null},
   559      *               or the parsed URL fails to comply with the specific syntax
   580      *               or the parsed URL fails to comply with the specific syntax
   560      *               of the associated protocol.
   581      *               of the associated protocol.
   561      * @exception  SecurityException
   582      * @throws     SecurityException
   562      *        if a security manager exists and its
   583      *        if a security manager exists and its
   563      *        {@code checkPermission} method doesn't allow
   584      *        {@code checkPermission} method doesn't allow
   564      *        specifying a stream handler.
   585      *        specifying a stream handler.
   565      * @see        java.net.URL#URL(java.lang.String, java.lang.String,
   586      * @see        java.net.URL#URL(java.lang.String, java.lang.String,
   566      *                  int, java.lang.String)
   587      *                  int, java.lang.String)
  1029      * This method functions in the same way as {@code new URI (this.toString())}.
  1050      * This method functions in the same way as {@code new URI (this.toString())}.
  1030      * <p>Note, any URL instance that complies with RFC 2396 can be converted
  1051      * <p>Note, any URL instance that complies with RFC 2396 can be converted
  1031      * to a URI. However, some URLs that are not strictly in compliance
  1052      * to a URI. However, some URLs that are not strictly in compliance
  1032      * can not be converted to a URI.
  1053      * can not be converted to a URI.
  1033      *
  1054      *
  1034      * @exception URISyntaxException if this URL is not formatted strictly according to
  1055      * @throws    URISyntaxException if this URL is not formatted strictly according to
  1035      *            RFC2396 and cannot be converted to a URI.
  1056      *            RFC2396 and cannot be converted to a URI.
  1036      *
  1057      *
  1037      * @return    a URI instance equivalent to this URL.
  1058      * @return    a URI instance equivalent to this URL.
  1038      * @since 1.5
  1059      * @since 1.5
  1039      */
  1060      */
  1040     public URI toURI() throws URISyntaxException {
  1061     public URI toURI() throws URISyntaxException {
  1041         return new URI (toString());
  1062         URI uri = new URI(toString());
       
  1063         if (authority != null && isBuiltinStreamHandler(handler)) {
       
  1064             String s = IPAddressUtil.checkAuthority(this);
       
  1065             if (s != null) throw new URISyntaxException(authority, s);
       
  1066         }
       
  1067         return uri;
  1042     }
  1068     }
  1043 
  1069 
  1044     /**
  1070     /**
  1045      * Returns a {@link java.net.URLConnection URLConnection} instance that
  1071      * Returns a {@link java.net.URLConnection URLConnection} instance that
  1046      * represents a connection to the remote object referred to by the
  1072      * represents a connection to the remote object referred to by the
  1064      * HttpURLConnection will be returned, and for JAR a
  1090      * HttpURLConnection will be returned, and for JAR a
  1065      * JarURLConnection will be returned.</P>
  1091      * JarURLConnection will be returned.</P>
  1066      *
  1092      *
  1067      * @return     a {@link java.net.URLConnection URLConnection} linking
  1093      * @return     a {@link java.net.URLConnection URLConnection} linking
  1068      *             to the URL.
  1094      *             to the URL.
  1069      * @exception  IOException  if an I/O exception occurs.
  1095      * @throws     IOException  if an I/O exception occurs.
  1070      * @see        java.net.URL#URL(java.lang.String, java.lang.String,
  1096      * @see        java.net.URL#URL(java.lang.String, java.lang.String,
  1071      *             int, java.lang.String)
  1097      *             int, java.lang.String)
  1072      */
  1098      */
  1073     public URLConnection openConnection() throws java.io.IOException {
  1099     public URLConnection openConnection() throws java.io.IOException {
  1074         return handler.openConnection(this);
  1100         return handler.openConnection(this);
  1085      *
  1111      *
  1086      * @param      proxy the Proxy through which this connection
  1112      * @param      proxy the Proxy through which this connection
  1087      *             will be made. If direct connection is desired,
  1113      *             will be made. If direct connection is desired,
  1088      *             Proxy.NO_PROXY should be specified.
  1114      *             Proxy.NO_PROXY should be specified.
  1089      * @return     a {@code URLConnection} to the URL.
  1115      * @return     a {@code URLConnection} to the URL.
  1090      * @exception  IOException  if an I/O exception occurs.
  1116      * @throws     IOException  if an I/O exception occurs.
  1091      * @exception  SecurityException if a security manager is present
  1117      * @throws     SecurityException if a security manager is present
  1092      *             and the caller doesn't have permission to connect
  1118      *             and the caller doesn't have permission to connect
  1093      *             to the proxy.
  1119      *             to the proxy.
  1094      * @exception  IllegalArgumentException will be thrown if proxy is null,
  1120      * @throws     IllegalArgumentException will be thrown if proxy is null,
  1095      *             or proxy has the wrong type
  1121      *             or proxy has the wrong type
  1096      * @exception  UnsupportedOperationException if the subclass that
  1122      * @throws     UnsupportedOperationException if the subclass that
  1097      *             implements the protocol handler doesn't support
  1123      *             implements the protocol handler doesn't support
  1098      *             this method.
  1124      *             this method.
  1099      * @see        java.net.URL#URL(java.lang.String, java.lang.String,
  1125      * @see        java.net.URL#URL(java.lang.String, java.lang.String,
  1100      *             int, java.lang.String)
  1126      *             int, java.lang.String)
  1101      * @see        java.net.URLConnection
  1127      * @see        java.net.URLConnection
  1130      * <blockquote><pre>
  1156      * <blockquote><pre>
  1131      *     openConnection().getInputStream()
  1157      *     openConnection().getInputStream()
  1132      * </pre></blockquote>
  1158      * </pre></blockquote>
  1133      *
  1159      *
  1134      * @return     an input stream for reading from the URL connection.
  1160      * @return     an input stream for reading from the URL connection.
  1135      * @exception  IOException  if an I/O exception occurs.
  1161      * @throws     IOException  if an I/O exception occurs.
  1136      * @see        java.net.URL#openConnection()
  1162      * @see        java.net.URL#openConnection()
  1137      * @see        java.net.URLConnection#getInputStream()
  1163      * @see        java.net.URLConnection#getInputStream()
  1138      */
  1164      */
  1139     public final InputStream openStream() throws java.io.IOException {
  1165     public final InputStream openStream() throws java.io.IOException {
  1140         return openConnection().getInputStream();
  1166         return openConnection().getInputStream();
  1145      * <blockquote><pre>
  1171      * <blockquote><pre>
  1146      *     openConnection().getContent()
  1172      *     openConnection().getContent()
  1147      * </pre></blockquote>
  1173      * </pre></blockquote>
  1148      *
  1174      *
  1149      * @return     the contents of this URL.
  1175      * @return     the contents of this URL.
  1150      * @exception  IOException  if an I/O exception occurs.
  1176      * @throws     IOException  if an I/O exception occurs.
  1151      * @see        java.net.URLConnection#getContent()
  1177      * @see        java.net.URLConnection#getContent()
  1152      */
  1178      */
  1153     public final Object getContent() throws java.io.IOException {
  1179     public final Object getContent() throws java.io.IOException {
  1154         return openConnection().getContent();
  1180         return openConnection().getContent();
  1155     }
  1181     }
  1162      *
  1188      *
  1163      * @param classes an array of Java types
  1189      * @param classes an array of Java types
  1164      * @return     the content object of this URL that is the first match of
  1190      * @return     the content object of this URL that is the first match of
  1165      *               the types specified in the classes array.
  1191      *               the types specified in the classes array.
  1166      *               null if none of the requested types are supported.
  1192      *               null if none of the requested types are supported.
  1167      * @exception  IOException  if an I/O exception occurs.
  1193      * @throws     IOException  if an I/O exception occurs.
  1168      * @see        java.net.URLConnection#getContent(Class[])
  1194      * @see        java.net.URLConnection#getContent(Class[])
  1169      * @since 1.3
  1195      * @since 1.3
  1170      */
  1196      */
  1171     public final Object getContent(Class<?>[] classes)
  1197     public final Object getContent(Class<?>[] classes)
  1172     throws java.io.IOException {
  1198     throws java.io.IOException {
  1190      * the security manager's {@code checkSetFactory} method
  1216      * the security manager's {@code checkSetFactory} method
  1191      * to ensure the operation is allowed.
  1217      * to ensure the operation is allowed.
  1192      * This could result in a SecurityException.
  1218      * This could result in a SecurityException.
  1193      *
  1219      *
  1194      * @param      fac   the desired factory.
  1220      * @param      fac   the desired factory.
  1195      * @exception  Error  if the application has already set a factory.
  1221      * @throws     Error  if the application has already set a factory.
  1196      * @exception  SecurityException  if a security manager exists and its
  1222      * @throws     SecurityException  if a security manager exists and its
  1197      *             {@code checkSetFactory} method doesn't allow
  1223      *             {@code checkSetFactory} method doesn't allow
  1198      *             the operation.
  1224      *             the operation.
  1199      * @see        java.net.URL#URL(java.lang.String, java.lang.String,
  1225      * @see        java.net.URL#URL(java.lang.String, java.lang.String,
  1200      *             int, java.lang.String)
  1226      *             int, java.lang.String)
  1201      * @see        java.net.URLStreamHandlerFactory
  1227      * @see        java.net.URLStreamHandlerFactory
  1475      * @serialField    ref String
  1501      * @serialField    ref String
  1476      *
  1502      *
  1477      * @serialField    hashCode int
  1503      * @serialField    hashCode int
  1478      *
  1504      *
  1479      */
  1505      */
       
  1506     @java.io.Serial
  1480     private static final ObjectStreamField[] serialPersistentFields = {
  1507     private static final ObjectStreamField[] serialPersistentFields = {
  1481         new ObjectStreamField("protocol", String.class),
  1508         new ObjectStreamField("protocol", String.class),
  1482         new ObjectStreamField("host", String.class),
  1509         new ObjectStreamField("host", String.class),
  1483         new ObjectStreamField("port", int.class),
  1510         new ObjectStreamField("port", int.class),
  1484         new ObjectStreamField("authority", String.class),
  1511         new ObjectStreamField("authority", String.class),
  1494      * @serialData the default write object value. When read back in,
  1521      * @serialData the default write object value. When read back in,
  1495      * the reader must ensure that calling getURLStreamHandler with
  1522      * the reader must ensure that calling getURLStreamHandler with
  1496      * the protocol variable returns a valid URLStreamHandler and
  1523      * the protocol variable returns a valid URLStreamHandler and
  1497      * throw an IOException if it does not.
  1524      * throw an IOException if it does not.
  1498      */
  1525      */
       
  1526     @java.io.Serial
  1499     private synchronized void writeObject(java.io.ObjectOutputStream s)
  1527     private synchronized void writeObject(java.io.ObjectOutputStream s)
  1500         throws IOException
  1528         throws IOException
  1501     {
  1529     {
  1502         s.defaultWriteObject(); // write the fields
  1530         s.defaultWriteObject(); // write the fields
  1503     }
  1531     }
  1505     /**
  1533     /**
  1506      * readObject is called to restore the state of the URL from the
  1534      * readObject is called to restore the state of the URL from the
  1507      * stream.  It reads the components of the URL and finds the local
  1535      * stream.  It reads the components of the URL and finds the local
  1508      * stream handler.
  1536      * stream handler.
  1509      */
  1537      */
       
  1538     @java.io.Serial
  1510     private synchronized void readObject(java.io.ObjectInputStream s)
  1539     private synchronized void readObject(java.io.ObjectInputStream s)
  1511             throws IOException, ClassNotFoundException {
  1540             throws IOException, ClassNotFoundException {
  1512         GetField gf = s.readFields();
  1541         GetField gf = s.readFields();
  1513         String protocol = (String)gf.get("protocol", null);
  1542         String protocol = (String)gf.get("protocol", null);
  1514         if (getURLStreamHandler(protocol) == null) {
  1543         if (getURLStreamHandler(protocol) == null) {
  1536      * @return a newly created object from deserialized data
  1565      * @return a newly created object from deserialized data
  1537      *
  1566      *
  1538      * @throws ObjectStreamException if a new object replacing this
  1567      * @throws ObjectStreamException if a new object replacing this
  1539      * object could not be created
  1568      * object could not be created
  1540      */
  1569      */
  1541 
  1570    @java.io.Serial
  1542    private Object readResolve() throws ObjectStreamException {
  1571    private Object readResolve() throws ObjectStreamException {
  1543 
  1572 
  1544         URLStreamHandler handler = null;
  1573         URLStreamHandler handler = null;
  1545         // already been checked in readObject
  1574         // already been checked in readObject
  1546         handler = getURLStreamHandler(tempState.getProtocol());
  1575         handler = getURLStreamHandler(tempState.getProtocol());
  1633         replacementURL.setSerializedHashCode(tempState.getHashCode());
  1662         replacementURL.setSerializedHashCode(tempState.getHashCode());
  1634         resetState();
  1663         resetState();
  1635         return replacementURL;
  1664         return replacementURL;
  1636     }
  1665     }
  1637 
  1666 
       
  1667     boolean isBuiltinStreamHandler(URLStreamHandler handler) {
       
  1668        return isBuiltinStreamHandler(handler.getClass().getName());
       
  1669     }
       
  1670 
  1638     private boolean isBuiltinStreamHandler(String handlerClassName) {
  1671     private boolean isBuiltinStreamHandler(String handlerClassName) {
  1639         return (handlerClassName.startsWith(BUILTIN_HANDLERS_PREFIX));
  1672         return (handlerClassName.startsWith(BUILTIN_HANDLERS_PREFIX));
  1640     }
  1673     }
  1641 
  1674 
  1642     private void resetState() {
  1675     private void resetState() {