1. /*
  2. * @(#)HttpURLConnection.java 1.17 01/11/29
  3. *
  4. * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.net;
  8. import java.io.InputStream;
  9. import java.io.IOException;
  10. import java.security.Permission;
  11. /**
  12. * A URLConnection with support for HTTP-specific features. See
  13. * <A HREF="http://www.w3.org/pub/WWW/Protocols/"> the spec </A> for
  14. * details.
  15. * @since JDK1.1
  16. */
  17. abstract public class HttpURLConnection extends URLConnection {
  18. /* instance variables */
  19. /**
  20. */
  21. protected String method = "GET";
  22. /**
  23. */
  24. protected int responseCode = -1;
  25. /**
  26. */
  27. protected String responseMessage = null;
  28. /* static variables */
  29. /* do we automatically follow redirects? The default is true. */
  30. private static boolean followRedirects = true;
  31. /* valid HTTP methods */
  32. private static final String[] methods = {
  33. "GET", "POST", "HEAD", "OPTIONS", "PUT", "DELETE", "TRACE"
  34. };
  35. /**
  36. * Constructor for the URLStreamHandler.
  37. */
  38. protected HttpURLConnection (URL u) {
  39. super(u);
  40. }
  41. /**
  42. * Sets whether HTTP redirects (requests with response code 3xx) should
  43. * be automatically followed by this class. True by default. Applets
  44. * cannot change this variable.
  45. * <p>
  46. * If there is a security manager, this method first calls
  47. * the security manager's <code>checkSetFactory</code> method
  48. * to ensure the operation is allowed.
  49. * This could result in a SecurityException.
  50. *
  51. * @exception SecurityException if a security manager exists and its
  52. * <code>checkSetFactory</code> method doesn't allow the operation.
  53. * @see SecurityManager#checkSetFactory
  54. */
  55. public static void setFollowRedirects(boolean set) {
  56. SecurityManager sec = System.getSecurityManager();
  57. if (sec != null) {
  58. // seems to be the best check here...
  59. sec.checkSetFactory();
  60. }
  61. followRedirects = set;
  62. }
  63. /**
  64. */
  65. public static boolean getFollowRedirects() {
  66. return followRedirects;
  67. }
  68. /**
  69. * Set the method for the URL request, one of:
  70. * <UL>
  71. * <LI>GET
  72. * <LI>POST
  73. * <LI>HEAD
  74. * <LI>OPTIONS
  75. * <LI>PUT
  76. * <LI>DELETE
  77. * <LI>TRACE
  78. * </UL> are legal, subject to protocol restrictions. The default
  79. * method is GET.
  80. *
  81. * @exception ProtocolException if the method cannot be reset or if
  82. * the requested method isn't valid for HTTP.
  83. */
  84. public void setRequestMethod(String method) throws ProtocolException {
  85. if (connected) {
  86. throw new ProtocolException("Can't reset method: already connected");
  87. }
  88. // This restriction will prevent people from using this class to
  89. // experiment w/ new HTTP methods using java. But it should
  90. // be placed for security - the request String could be
  91. // arbitrarily long.
  92. for (int i = 0; i < methods.length; i++) {
  93. if (methods[i].equals(method)) {
  94. this.method = method;
  95. return;
  96. }
  97. }
  98. throw new ProtocolException("Invalid HTTP method: " + method);
  99. }
  100. /**
  101. * Get the request method.
  102. */
  103. public String getRequestMethod() {
  104. return method;
  105. }
  106. /**
  107. * Gets HTTP response status. From responses like:
  108. * <PRE>
  109. * HTTP/1.0 200 OK
  110. * HTTP/1.0 401 Unauthorized
  111. * </PRE>
  112. * Extracts the ints 200 and 401 respectively.
  113. * Returns -1 if none can be discerned
  114. * from the response (i.e., the response is not valid HTTP).
  115. * @throws IOException if an error occurred connecting to the server.
  116. */
  117. public int getResponseCode() throws IOException {
  118. if (responseCode != -1) {
  119. return responseCode;
  120. }
  121. // make sure we've gotten the headers
  122. getInputStream();
  123. String resp = getHeaderField(0);
  124. /* should have no leading/trailing LWS
  125. * expedite the typical case by assuming it has
  126. * form "HTTP/1.x <WS> 2XX <mumble>"
  127. */
  128. int ind;
  129. try {
  130. ind = resp.indexOf(' ');
  131. while(resp.charAt(ind) == ' ')
  132. ind++;
  133. responseCode = Integer.parseInt(resp.substring(ind, ind + 3));
  134. responseMessage = resp.substring(ind + 4).trim();
  135. return responseCode;
  136. } catch (Exception e) {
  137. return responseCode;
  138. }
  139. }
  140. /**
  141. * Gets the HTTP response message, if any, returned along with the
  142. * response code from a server. From responses like:
  143. * <PRE>
  144. * HTTP/1.0 200 OK
  145. * HTTP/1.0 404 Not Found
  146. * </PRE>
  147. * Extracts the Strings "OK" and "Not Found" respectively.
  148. * Returns null if none could be discerned from the responses
  149. * (the result was not valid HTTP).
  150. * @throws IOException if an error occurred connecting to the server.
  151. */
  152. public String getResponseMessage() throws IOException {
  153. getResponseCode();
  154. return responseMessage;
  155. }
  156. /**
  157. * Close the connection to the server.
  158. */
  159. public abstract void disconnect();
  160. /**
  161. * Indicates if the connection is going through a proxy.
  162. */
  163. public abstract boolean usingProxy();
  164. public Permission getPermission() throws IOException {
  165. int port = url.getPort();
  166. port = port < 0 ? 80 : port;
  167. String host = url.getHost() + ":" + port;
  168. Permission permission = new SocketPermission(host, "connect");
  169. return permission;
  170. }
  171. /**
  172. * Returns the error stream if the connection failed
  173. * but the server sent useful data nonetheless. The
  174. * typical example is when an HTTP server responds
  175. * with a 404, which will cause a FileNotFoundException
  176. * to be thrown in connect, but the server sent an HTML
  177. * help page with suggestions as to what to do.
  178. *
  179. * <p>This method will not cause a connection to be initiated.
  180. * If there the connection was not connected, or if the server
  181. * did not have an error while connecting or if the server did
  182. * have an error but there no error data was sent, this method
  183. * will return null. This is the default.
  184. *
  185. * @return an error stream if any, null if there have been
  186. * no errors, the connection is not connected or the server
  187. * sent no useful data.
  188. */
  189. public InputStream getErrorStream() {
  190. return null;
  191. }
  192. /**
  193. * The response codes for HTTP, as of version 1.1.
  194. */
  195. // REMIND: do we want all these??
  196. // Others not here that we do want??
  197. /** 2XX: generally "OK" */
  198. public static final int HTTP_OK = 200;
  199. public static final int HTTP_CREATED = 201;
  200. public static final int HTTP_ACCEPTED = 202;
  201. public static final int HTTP_NOT_AUTHORITATIVE = 203;
  202. public static final int HTTP_NO_CONTENT = 204;
  203. public static final int HTTP_RESET = 205;
  204. public static final int HTTP_PARTIAL = 206;
  205. /** 3XX: relocation/redirect */
  206. public static final int HTTP_MULT_CHOICE = 300;
  207. public static final int HTTP_MOVED_PERM = 301;
  208. public static final int HTTP_MOVED_TEMP = 302;
  209. public static final int HTTP_SEE_OTHER = 303;
  210. public static final int HTTP_NOT_MODIFIED = 304;
  211. public static final int HTTP_USE_PROXY = 305;
  212. /** 4XX: client error */
  213. public static final int HTTP_BAD_REQUEST = 400;
  214. public static final int HTTP_UNAUTHORIZED = 401;
  215. public static final int HTTP_PAYMENT_REQUIRED = 402;
  216. public static final int HTTP_FORBIDDEN = 403;
  217. public static final int HTTP_NOT_FOUND = 404;
  218. public static final int HTTP_BAD_METHOD = 405;
  219. public static final int HTTP_NOT_ACCEPTABLE = 406;
  220. public static final int HTTP_PROXY_AUTH = 407;
  221. public static final int HTTP_CLIENT_TIMEOUT = 408;
  222. public static final int HTTP_CONFLICT = 409;
  223. public static final int HTTP_GONE = 410;
  224. public static final int HTTP_LENGTH_REQUIRED = 411;
  225. public static final int HTTP_PRECON_FAILED = 412;
  226. public static final int HTTP_ENTITY_TOO_LARGE = 413;
  227. public static final int HTTP_REQ_TOO_LONG = 414;
  228. public static final int HTTP_UNSUPPORTED_TYPE = 415;
  229. /** 5XX: server error */
  230. public static final int HTTP_SERVER_ERROR = 500;
  231. public static final int HTTP_INTERNAL_ERROR = 501;
  232. public static final int HTTP_BAD_GATEWAY = 502;
  233. public static final int HTTP_UNAVAILABLE = 503;
  234. public static final int HTTP_GATEWAY_TIMEOUT = 504;
  235. public static final int HTTP_VERSION = 505;
  236. }