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() { |