< prev index next >

src/java.base/share/classes/java/net/URLConnection.java

Print this page

        

*** 26,37 **** --- 26,41 ---- package java.net; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; + import java.security.PrivilegedAction; import java.util.Hashtable; import java.util.Date; + import java.util.Iterator; + import java.util.ServiceConfigurationError; + import java.util.ServiceLoader; import java.util.StringTokenizer; import java.util.Collections; import java.util.Map; import java.util.List; import java.security.Permission;
*** 105,115 **** * <li>{@code getContentEncoding} * <li>{@code getContentLength} * <li>{@code getContentType} * <li>{@code getDate} * <li>{@code getExpiration} ! * <li>{@code getLastModifed} * </ul> * <p> * provide convenient access to these fields. The * {@code getContentType} method is used by the * {@code getContent} method to determine the type of the remote --- 109,119 ---- * <li>{@code getContentEncoding} * <li>{@code getContentLength} * <li>{@code getContentType} * <li>{@code getDate} * <li>{@code getExpiration} ! * <li>{@code getLastModified} * </ul> * <p> * provide convenient access to these fields. The * {@code getContentType} method is used by the * {@code getContent} method to determine the type of the remote
*** 693,712 **** * Retrieves the contents of this URL connection. * <p> * This method first determines the content type of the object by * calling the {@code getContentType} method. If this is * the first time that the application has seen that specific content ! * type, a content handler for that content type is created: * <ol> * <li>If the application has set up a content handler factory instance * using the {@code setContentHandlerFactory} method, the * {@code createContentHandler} method of that instance is called * with the content type as an argument; the result is a content * handler for that content type. ! * <li>If no content handler factory has yet been set up, or if the ! * factory's {@code createContentHandler} method returns ! * {@code null}, then this method tries to load a content handler * class as defined by {@link java.net.ContentHandler ContentHandler}. * If the class does not exist, or is not a subclass of {@code * ContentHandler}, then an {@code UnknownServiceException} is thrown. * </ol> * --- 697,730 ---- * Retrieves the contents of this URL connection. * <p> * This method first determines the content type of the object by * calling the {@code getContentType} method. If this is * the first time that the application has seen that specific content ! * type, a content handler for that content type is created. ! * <p> This is done as follows: * <ol> * <li>If the application has set up a content handler factory instance * using the {@code setContentHandlerFactory} method, the * {@code createContentHandler} method of that instance is called * with the content type as an argument; the result is a content * handler for that content type. ! * <li>If no {@code ContentHandlerFactory} has yet been set up, ! * or if the factory's {@code createContentHandler} method ! * returns {@code null}, then the {@linkplain java.util.ServiceLoader ! * ServiceLoader} mechanism is used to locate {@linkplain ! * java.net.ContentHandlerFactory ContentHandlerFactory} ! * implementations using the system class ! * loader. The order that factories are located is implementation ! * specific, and an implementation is free to cache the located ! * factories. A {@linkplain java.util.ServiceConfigurationError ! * ServiceConfigurationError}, {@code Error} or {@code RuntimeException} ! * thrown from the {@code createContentHandler}, if encountered, will ! * be propagated to the calling thread. The {@code ! * createContentHandler} method of each factory, if instantiated, is ! * invoked, with the content type, until a factory returns non-null, ! * or all factories have been exhausted. ! * <li>Failing that, this method tries to load a content handler * class as defined by {@link java.net.ContentHandler ContentHandler}. * If the class does not exist, or is not a subclass of {@code * ContentHandler}, then an {@code UnknownServiceException} is thrown. * </ol> *
*** 853,864 **** * @throws IllegalStateException if already connected * @see java.net.URLConnection#doInput * @see #getDoInput() */ public void setDoInput(boolean doinput) { ! if (connected) ! throw new IllegalStateException("Already connected"); doInput = doinput; } /** * Returns the value of this {@code URLConnection}'s --- 871,881 ---- * @throws IllegalStateException if already connected * @see java.net.URLConnection#doInput * @see #getDoInput() */ public void setDoInput(boolean doinput) { ! checkConnected(); doInput = doinput; } /** * Returns the value of this {@code URLConnection}'s
*** 883,894 **** * @param dooutput the new value. * @throws IllegalStateException if already connected * @see #getDoOutput() */ public void setDoOutput(boolean dooutput) { ! if (connected) ! throw new IllegalStateException("Already connected"); doOutput = dooutput; } /** * Returns the value of this {@code URLConnection}'s --- 900,910 ---- * @param dooutput the new value. * @throws IllegalStateException if already connected * @see #getDoOutput() */ public void setDoOutput(boolean dooutput) { ! checkConnected(); doOutput = dooutput; } /** * Returns the value of this {@code URLConnection}'s
*** 909,920 **** * @param allowuserinteraction the new value. * @throws IllegalStateException if already connected * @see #getAllowUserInteraction() */ public void setAllowUserInteraction(boolean allowuserinteraction) { ! if (connected) ! throw new IllegalStateException("Already connected"); allowUserInteraction = allowuserinteraction; } /** * Returns the value of the {@code allowUserInteraction} field for --- 925,935 ---- * @param allowuserinteraction the new value. * @throws IllegalStateException if already connected * @see #getAllowUserInteraction() */ public void setAllowUserInteraction(boolean allowuserinteraction) { ! checkConnected(); allowUserInteraction = allowuserinteraction; } /** * Returns the value of the {@code allowUserInteraction} field for
*** 972,983 **** * or not to allow caching * @throws IllegalStateException if already connected * @see #getUseCaches() */ public void setUseCaches(boolean usecaches) { ! if (connected) ! throw new IllegalStateException("Already connected"); useCaches = usecaches; } /** * Returns the value of this {@code URLConnection}'s --- 987,997 ---- * or not to allow caching * @throws IllegalStateException if already connected * @see #getUseCaches() */ public void setUseCaches(boolean usecaches) { ! checkConnected(); useCaches = usecaches; } /** * Returns the value of this {@code URLConnection}'s
*** 998,1009 **** * @param ifmodifiedsince the new value. * @throws IllegalStateException if already connected * @see #getIfModifiedSince() */ public void setIfModifiedSince(long ifmodifiedsince) { ! if (connected) ! throw new IllegalStateException("Already connected"); ifModifiedSince = ifmodifiedsince; } /** * Returns the value of this object's {@code ifModifiedSince} field. --- 1012,1022 ---- * @param ifmodifiedsince the new value. * @throws IllegalStateException if already connected * @see #getIfModifiedSince() */ public void setIfModifiedSince(long ifmodifiedsince) { ! checkConnected(); ifModifiedSince = ifmodifiedsince; } /** * Returns the value of this object's {@code ifModifiedSince} field.
*** 1053,1068 **** * * @param key the keyword by which the request is known * (e.g., "{@code Accept}"). * @param value the value associated with it. * @throws IllegalStateException if already connected ! * @throws NullPointerException if key is <CODE>null</CODE> * @see #getRequestProperty(java.lang.String) */ public void setRequestProperty(String key, String value) { ! if (connected) ! throw new IllegalStateException("Already connected"); if (key == null) throw new NullPointerException ("key is null"); if (requests == null) requests = new MessageHeader(); --- 1066,1080 ---- * * @param key the keyword by which the request is known * (e.g., "{@code Accept}"). * @param value the value associated with it. * @throws IllegalStateException if already connected ! * @throws NullPointerException if key is {@code null} * @see #getRequestProperty(java.lang.String) */ public void setRequestProperty(String key, String value) { ! checkConnected(); if (key == null) throw new NullPointerException ("key is null"); if (requests == null) requests = new MessageHeader();
*** 1082,1093 **** * @throws NullPointerException if key is null * @see #getRequestProperties() * @since 1.4 */ public void addRequestProperty(String key, String value) { ! if (connected) ! throw new IllegalStateException("Already connected"); if (key == null) throw new NullPointerException ("key is null"); if (requests == null) requests = new MessageHeader(); --- 1094,1104 ---- * @throws NullPointerException if key is null * @see #getRequestProperties() * @since 1.4 */ public void addRequestProperty(String key, String value) { ! checkConnected(); if (key == null) throw new NullPointerException ("key is null"); if (requests == null) requests = new MessageHeader();
*** 1105,1116 **** * connection. If key is null, then null is returned. * @throws IllegalStateException if already connected * @see #setRequestProperty(java.lang.String, java.lang.String) */ public String getRequestProperty(String key) { ! if (connected) ! throw new IllegalStateException("Already connected"); if (requests == null) return null; return requests.findValue(key); --- 1116,1126 ---- * connection. If key is null, then null is returned. * @throws IllegalStateException if already connected * @see #setRequestProperty(java.lang.String, java.lang.String) */ public String getRequestProperty(String key) { ! checkConnected(); if (requests == null) return null; return requests.findValue(key);
*** 1127,1138 **** * @return a Map of the general request properties for this connection. * @throws IllegalStateException if already connected * @since 1.4 */ public Map<String,List<String>> getRequestProperties() { ! if (connected) ! throw new IllegalStateException("Already connected"); if (requests == null) return Collections.emptyMap(); return requests.getHeaders(null); --- 1137,1147 ---- * @return a Map of the general request properties for this connection. * @throws IllegalStateException if already connected * @since 1.4 */ public Map<String,List<String>> getRequestProperties() { ! checkConnected(); if (requests == null) return Collections.emptyMap(); return requests.getHeaders(null);
*** 1181,1191 **** } /** * The ContentHandler factory. */ ! static ContentHandlerFactory factory; /** * Sets the {@code ContentHandlerFactory} of an * application. It can be called at most once by an application. * <p> --- 1190,1200 ---- } /** * The ContentHandler factory. */ ! private static volatile ContentHandlerFactory factory; /** * Sets the {@code ContentHandlerFactory} of an * application. It can be called at most once by an application. * <p>
*** 1214,1254 **** security.checkSetFactory(); } factory = fac; } ! private static Hashtable<String, ContentHandler> handlers = new Hashtable<>(); /** * Gets the Content Handler appropriate for this connection. */ ! synchronized ContentHandler getContentHandler() ! throws UnknownServiceException ! { String contentType = stripOffParameters(getContentType()); ! ContentHandler handler = null; ! if (contentType == null) throw new UnknownServiceException("no content-type"); ! try { ! handler = handlers.get(contentType); if (handler != null) return handler; - } catch(Exception e) { - } ! if (factory != null) handler = factory.createContentHandler(contentType); ! if (handler == null) { try { handler = lookupContentHandlerClassFor(contentType); ! } catch(Exception e) { e.printStackTrace(); handler = UnknownContentHandler.INSTANCE; } ! handlers.put(contentType, handler); ! } ! return handler; } /* * Media types are in the format: type/subtype*(; parameter). * For looking up the content handler, we should ignore those --- 1223,1271 ---- security.checkSetFactory(); } factory = fac; } ! private static final Hashtable<String, ContentHandler> handlers = new Hashtable<>(); /** * Gets the Content Handler appropriate for this connection. */ ! private ContentHandler getContentHandler() throws UnknownServiceException { String contentType = stripOffParameters(getContentType()); ! if (contentType == null) { throw new UnknownServiceException("no content-type"); ! } ! ! ContentHandler handler = handlers.get(contentType); if (handler != null) return handler; ! if (factory != null) { handler = factory.createContentHandler(contentType); ! if (handler != null) ! return handler; ! } ! ! handler = lookupContentHandlerViaProvider(contentType); ! ! if (handler != null) { ! ContentHandler h = handlers.putIfAbsent(contentType, handler); ! return h != null ? h : handler; ! } ! try { handler = lookupContentHandlerClassFor(contentType); ! } catch (Exception e) { e.printStackTrace(); handler = UnknownContentHandler.INSTANCE; } ! ! assert handler != null; ! ! ContentHandler h = handlers.putIfAbsent(contentType, handler); ! return h != null ? h : handler; } /* * Media types are in the format: type/subtype*(; parameter). * For looking up the content handler, we should ignore those
*** 1268,1293 **** private static final String contentClassPrefix = "sun.net.www.content"; private static final String contentPathProp = "java.content.handler.pkgs"; /** ! * Looks for a content handler in a user-defineable set of places. ! * By default it looks in sun.net.www.content, but users can define a ! * vertical-bar delimited set of class prefixes to search through in ! * addition by defining the java.content.handler.pkgs property. * The class name must be of the form: * <pre> * {package-prefix}.{major}.{minor} * e.g. * YoyoDyne.experimental.text.plain * </pre> */ ! private ContentHandler lookupContentHandlerClassFor(String contentType) ! throws InstantiationException, IllegalAccessException, ClassNotFoundException { String contentHandlerClassName = typeToPackageName(contentType); ! String contentHandlerPkgPrefixes =getContentHandlerPkgPrefixes(); StringTokenizer packagePrefixIter = new StringTokenizer(contentHandlerPkgPrefixes, "|"); while (packagePrefixIter.hasMoreTokens()) { --- 1285,1309 ---- private static final String contentClassPrefix = "sun.net.www.content"; private static final String contentPathProp = "java.content.handler.pkgs"; /** ! * Looks for a content handler in a user-definable set of places. ! * By default it looks in {@value #contentClassPrefix}, but users can define ! * a vertical-bar delimited set of class prefixes to search through in ! * addition by defining the {@value #contentPathProp} property. * The class name must be of the form: * <pre> * {package-prefix}.{major}.{minor} * e.g. * YoyoDyne.experimental.text.plain * </pre> */ ! private ContentHandler lookupContentHandlerClassFor(String contentType) { String contentHandlerClassName = typeToPackageName(contentType); ! String contentHandlerPkgPrefixes = getContentHandlerPkgPrefixes(); StringTokenizer packagePrefixIter = new StringTokenizer(contentHandlerPkgPrefixes, "|"); while (packagePrefixIter.hasMoreTokens()) {
*** 1303,1323 **** if (cl != null) { cls = cl.loadClass(clsName); } } if (cls != null) { ! ContentHandler handler = ! (ContentHandler)cls.newInstance(); ! return handler; ! } ! } catch(Exception e) { } } return UnknownContentHandler.INSTANCE; } /** * Utility function to map a MIME content type into an equivalent * pair of class name components. For example: "text/html" would * be returned as "text.html" */ --- 1319,1368 ---- if (cl != null) { cls = cl.loadClass(clsName); } } if (cls != null) { ! return (ContentHandler) cls.newInstance(); } + } catch(Exception ignored) { } } return UnknownContentHandler.INSTANCE; } + private ContentHandler lookupContentHandlerViaProvider(String contentType) { + return AccessController.doPrivileged( + new PrivilegedAction<>() { + @Override + public ContentHandler run() { + ClassLoader cl = ClassLoader.getSystemClassLoader(); + ServiceLoader<ContentHandlerFactory> sl = + ServiceLoader.load(ContentHandlerFactory.class, cl); + + Iterator<ContentHandlerFactory> iterator = sl.iterator(); + + ContentHandler handler = null; + while (iterator.hasNext()) { + ContentHandlerFactory f; + try { + f = iterator.next(); + } catch (ServiceConfigurationError e) { + if (e.getCause() instanceof SecurityException) { + continue; + } + throw e; + } + handler = f.createContentHandler(contentType); + if (handler != null) { + break; + } + } + return handler; + } + }); + } + /** * Utility function to map a MIME content type into an equivalent * pair of class name components. For example: "text/html" would * be returned as "text.html" */
*** 1343,1354 **** /** * Returns a vertical bar separated list of package prefixes for potential * content handlers. Tries to get the java.content.handler.pkgs property * to use as a set of package prefixes to search. Whether or not ! * that property has been defined, the sun.net.www.content is always ! * the last one on the returned package list. */ private String getContentHandlerPkgPrefixes() { String packagePrefixList = AccessController.doPrivileged( new sun.security.action.GetPropertyAction(contentPathProp, "")); --- 1388,1399 ---- /** * Returns a vertical bar separated list of package prefixes for potential * content handlers. Tries to get the java.content.handler.pkgs property * to use as a set of package prefixes to search. Whether or not ! * that property has been defined, the {@value #contentClassPrefix} ! * is always the last one on the returned package list. */ private String getContentHandlerPkgPrefixes() { String packagePrefixList = AccessController.doPrivileged( new sun.security.action.GetPropertyAction(contentPathProp, ""));
*** 1762,1774 **** skipped += eachSkip; } return skipped; } } - class UnknownContentHandler extends ContentHandler { static final ContentHandler INSTANCE = new UnknownContentHandler(); public Object getContent(URLConnection uc) throws IOException { return uc.getInputStream(); --- 1807,1822 ---- skipped += eachSkip; } return skipped; } + private void checkConnected() { + if (connected) + throw new IllegalStateException("Already connected"); + } } class UnknownContentHandler extends ContentHandler { static final ContentHandler INSTANCE = new UnknownContentHandler(); public Object getContent(URLConnection uc) throws IOException { return uc.getInputStream();
< prev index next >