1 |
/* HttpURLConnection.java -- HTTP connection to web server |
// HttpURLConnection.java - Subclass of communications links using |
2 |
Copyright (C) 1998 Free Software Foundation, Inc. |
// Hypertext Transfer Protocol. |
3 |
|
|
4 |
|
/* Copyright (C) 1998, 1999, 2000, 2002 Free Software Foundation |
5 |
|
|
6 |
This file is part of GNU Classpath. |
This file is part of GNU Classpath. |
7 |
|
|
18 |
You should have received a copy of the GNU General Public License |
You should have received a copy of the GNU General Public License |
19 |
along with GNU Classpath; see the file COPYING. If not, write to the |
along with GNU Classpath; see the file COPYING. If not, write to the |
20 |
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
21 |
02111-1307 USA. |
02111-1307 USA. |
22 |
|
|
23 |
Linking this library statically or dynamically with other modules is |
Linking this library statically or dynamically with other modules is |
24 |
making a combined work based on this library. Thus, the terms and |
making a combined work based on this library. Thus, the terms and |
37 |
obligated to do so. If you do not wish to do so, delete this |
obligated to do so. If you do not wish to do so, delete this |
38 |
exception statement from your version. */ |
exception statement from your version. */ |
39 |
|
|
|
|
|
40 |
package java.net; |
package java.net; |
41 |
|
|
42 |
import java.io.IOException; |
import java.io.*; |
|
import java.io.InputStream; |
|
|
import java.io.PushbackInputStream; |
|
43 |
import java.security.Permission; |
import java.security.Permission; |
44 |
|
|
|
/** |
|
|
* This class provides a common abstract implementation for those |
|
|
* URL connection classes that will connect using the HTTP protocol. |
|
|
* In addition to the functionality provided by the URLConnection |
|
|
* class, it defines constants for HTTP return code values and |
|
|
* methods for setting the HTTP request method and determining whether |
|
|
* or not to follow redirects. |
|
|
* |
|
|
* @version 0.5 |
|
|
* |
|
|
* @author Aaron M. Renn (arenn@urbanophile.com) |
|
|
*/ |
|
|
public abstract class HttpURLConnection extends URLConnection |
|
|
{ |
|
|
|
|
|
/*************************************************************************/ |
|
|
|
|
|
/* |
|
|
* Class Variables |
|
|
*/ |
|
|
|
|
|
// HTTP return codes |
|
|
|
|
|
/** |
|
|
* Indicates that the client may continue with its request. This value |
|
|
* is specified as part of RFC 2068 but was not included in Sun's JDK, so |
|
|
* beware of using this value |
|
|
*/ |
|
|
static final int HTTP_CONTINUE = 100; |
|
|
|
|
|
/** |
|
|
* Indicates that the server received and is willing to comply with a |
|
|
* request to switch protocols initiated by the client. This value is |
|
|
* specified as part of RFC 2068 but was not included in Sun's JDK as of |
|
|
* release 1.2, so beware of using this value. |
|
|
*/ |
|
|
static final int HTTP_SWITCHING_PROTOCOLS = 101; |
|
|
|
|
|
/** |
|
|
* Indicates the request succeeded |
|
|
*/ |
|
|
public static final int HTTP_OK = 200; |
|
|
|
|
|
/** |
|
|
* The requested resource has been created. |
|
|
*/ |
|
|
public static final int HTTP_CREATED = 201; |
|
|
|
|
|
/** |
|
|
* The request has been accepted for processing but has not completed. |
|
|
* There is no guarantee that the requested action will actually ever |
|
|
* be completed succesfully, but everything is ok so far. |
|
|
*/ |
|
|
public static final int HTTP_ACCEPTED = 202; |
|
|
|
|
|
/** |
|
|
* The meta-information returned in the header is not the actual data |
|
|
* from the original server, but may be from a local or other copy. |
|
|
* Normally this still indicates a successful completion. |
|
|
*/ |
|
|
public static final int HTTP_NOT_AUTHORITATIVE = 203; |
|
|
|
|
|
/** |
|
|
* The server performed the request, but there is no data to send |
|
|
* back. This indicates that the user's display should not be changed. |
|
|
*/ |
|
|
public static final int HTTP_NO_CONTENT = 204; |
|
|
|
|
|
/** |
|
|
* The server performed the request, but there is no data to sent back, |
|
|
* however, the user's display should be "reset" to clear out any form |
|
|
* fields entered. |
|
|
*/ |
|
|
public static final int HTTP_RESET = 205; |
|
|
|
|
|
/** |
|
|
* The server completed the partial GET request for the resource. |
|
|
*/ |
|
|
public static final int HTTP_PARTIAL = 206; |
|
|
|
|
|
/** |
|
|
* There is a list of choices available for the requested resource |
|
|
*/ |
|
|
public static final int HTTP_MULT_CHOICE = 300; |
|
|
|
|
|
/** |
|
|
* The resource has been permanently moved to a new location. |
|
|
*/ |
|
|
public static final int HTTP_MOVED_PERM = 301; |
|
|
|
|
|
/** |
|
|
* The resource requested has been temporarily moved to a new location. |
|
|
*/ |
|
|
public static final int HTTP_MOVED_TEMP = 302; |
|
|
|
|
|
/** |
|
|
* The response to the request issued is available at another location |
|
|
*/ |
|
|
public static final int HTTP_SEE_OTHER = 303; |
|
|
|
|
|
/** |
|
|
* The document has not been modified since the criteria specified in |
|
|
* a conditional GET |
|
|
*/ |
|
|
public static final int HTTP_NOT_MODIFIED = 304; |
|
|
|
|
|
/** |
|
|
* The requested resource needs to be accessed through a proxy. |
|
|
*/ |
|
|
public static final int HTTP_USE_PROXY = 305; |
|
|
|
|
|
/** |
|
|
* The request was misformed or could not be understood. |
|
|
*/ |
|
|
public static final int HTTP_BAD_REQUEST = 400; |
|
|
|
|
|
/** |
|
|
* The request made requires user authorization. Try again with |
|
|
* a correct authentication header. |
|
|
*/ |
|
|
public static final int HTTP_UNAUTHORIZED = 401; |
|
|
|
|
|
/** |
|
|
* Code reserved for future use - I hope way in the future |
|
|
*/ |
|
|
public static final int HTTP_PAYMENT_REQUIRED = 402; |
|
|
|
|
|
/** |
|
|
* There is no permission to access the requested resource |
|
|
*/ |
|
|
public static final int HTTP_FORBIDDEN = 403; |
|
|
|
|
|
/** |
|
|
* The requested resource was not found |
|
|
*/ |
|
|
public static final int HTTP_NOT_FOUND = 404; |
|
|
|
|
|
/** |
|
|
* The specified request method is not allowed for this resource |
|
|
*/ |
|
|
public static final int HTTP_BAD_METHOD = 405; |
|
|
|
|
|
/** |
|
|
* Based on the input headers sent, the resource returned in response |
|
|
* to the request would not be acceptable to the client. |
|
|
*/ |
|
|
public static final int HTTP_NOT_ACCEPTABLE = 406; |
|
|
|
|
|
/** |
|
|
* The client must authenticate with a proxy prior to attempting this |
|
|
* request. |
|
|
*/ |
|
|
public static final int HTTP_PROXY_AUTH = 407; |
|
|
|
|
|
/** |
|
|
* The request timed out. |
|
|
*/ |
|
|
public static final int HTTP_CLIENT_TIMEOUT = 408; |
|
|
|
|
|
/** |
|
|
* There is a conflict between the current state of the resource and the |
|
|
* requested action. |
|
|
*/ |
|
|
public static final int HTTP_CONFLICT = 409; |
|
|
|
|
|
/** |
|
|
* The requested resource is no longer available. This ususally indicates |
|
|
* a permanent condition. |
|
|
*/ |
|
|
public static final int HTTP_GONE = 410; |
|
|
|
|
|
/** |
|
|
* A Content-Length header is required for this request, but was not |
|
|
* supplied |
|
|
*/ |
|
|
public static final int HTTP_LENGTH_REQUIRED = 411; |
|
|
|
|
|
/** |
|
|
* A client specified pre-condition was not met on the server. |
|
|
*/ |
|
|
public static final int HTTP_PRECON_FAILED = 412; |
|
|
|
|
|
/** |
|
|
* The request sent was too large for the server to handle |
|
|
*/ |
|
|
public static final int HTTP_ENTITY_TOO_LARGE = 413; |
|
|
|
|
|
/** |
|
|
* The name of the resource specified was too long |
|
|
*/ |
|
|
public static final int HTTP_REQ_TOO_LONG = 414; |
|
|
|
|
|
/** |
|
|
* The request is in a format not supported by the requested resource |
|
|
*/ |
|
|
public static final int HTTP_UNSUPPORTED_TYPE = 415; |
|
|
|
|
|
/** |
|
|
* This error code indicates that some sort of server error occurred |
|
|
*/ |
|
|
public static final int HTTP_SERVER_ERROR = 500; |
|
|
|
|
|
/** |
|
|
* The server encountered an unexpected error (such as a CGI script crash) |
|
|
* that prevents the request from being fulfilled |
|
|
*/ |
|
|
public static final int HTTP_INTERNAL_ERROR = 500; |
|
|
|
|
|
/** |
|
|
* The server does not support the requested functionality. |
|
|
* @since 1.3 |
|
|
*/ |
|
|
static final int HTTP_NOT_IMPLEMENTED = 501; |
|
|
|
|
|
/** |
|
|
* The proxy encountered a bad response from the server it was proxy-ing for |
|
|
*/ |
|
|
public static final int HTTP_BAD_GATEWAY = 502; |
|
|
|
|
|
/** |
|
|
* The HTTP service is not availalble, such as because it is overloaded |
|
|
* and does not want additional requests. |
|
|
*/ |
|
|
public static final int HTTP_UNAVAILABLE = 503; |
|
|
|
|
|
/** |
|
|
* The proxy timed out getting a reply from the remote server it was |
|
|
* proxy-ing for. |
|
|
*/ |
|
|
public static final int HTTP_GATEWAY_TIMEOUT = 504; |
|
|
|
|
|
/** |
|
|
* This server does not support the protocol version requested. |
|
|
*/ |
|
|
public static final int HTTP_VERSION = 505; |
|
|
|
|
|
// Non-HTTP response static variables |
|
|
|
|
|
/** |
|
|
* Flag to indicate whether or not redirects should be automatically |
|
|
* followed. |
|
|
*/ |
|
|
private static boolean follow_redirects = true; |
|
|
|
|
|
/** |
|
|
* This is a list of valid request methods, separated by "|" characters. |
|
|
*/ |
|
|
private static String valid_methods = "|GET|POST|HEAD|OPTIONS|PUT|DELETE|TRACE|"; |
|
|
|
|
|
/*************************************************************************/ |
|
|
|
|
|
/* |
|
|
* Instance Variables |
|
|
*/ |
|
|
|
|
|
/** |
|
|
* The requested method in use for this connection. |
|
|
*/ |
|
|
protected String method = "GET"; // GET is the default method |
|
|
|
|
|
/** |
|
|
* The response code received from the server |
|
|
*/ |
|
|
protected int responseCode = -1; |
|
|
|
|
|
/** |
|
|
* The response message string received from the server. |
|
|
*/ |
|
|
protected String responseMessage = null; |
|
|
|
|
|
/*************************************************************************/ |
|
|
|
|
|
/* |
|
|
* Class Methods |
|
|
*/ |
|
|
|
|
|
/** |
|
|
* Sets a flag indicating whether or not to automatically follow HTTP |
|
|
* redirects. If not otherwise set, this value defaults to true. Note |
|
|
* that this value cannot be set by applets. |
|
|
* |
|
|
* @param follow true if redirects should be followed, false otherwise |
|
|
*/ |
|
|
public static void |
|
|
setFollowRedirects(boolean follow) |
|
|
{ |
|
|
follow_redirects = follow; |
|
|
} |
|
|
|
|
|
/*************************************************************************/ |
|
|
|
|
|
/** |
|
|
* Returns a boolean indicating whether or not HTTP redirects will |
|
|
* automatically be followed or not. |
|
|
* |
|
|
* @return true if redirects will be followed, false otherwise |
|
|
*/ |
|
|
public static boolean |
|
|
getFollowRedirects() |
|
|
{ |
|
|
return(follow_redirects); |
|
|
} |
|
|
|
|
|
/*************************************************************************/ |
|
|
|
|
45 |
/* |
/* |
46 |
* Constructors |
* Written using on-line Java Platform 1.2 API Specification, as well |
47 |
|
* as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998). |
48 |
|
* Status: Believed complete and correct. |
49 |
*/ |
*/ |
50 |
|
|
51 |
/** |
/** |
52 |
* Create an HttpURLConnection for the specified URL |
* This class provides a common abstract implementation for those |
53 |
* |
* URL connection classes that will connect using the HTTP protocol. |
54 |
* @param url The URL to create this connection for. |
* In addition to the functionality provided by the URLConnection |
55 |
*/ |
* class, it defines constants for HTTP return code values and |
56 |
protected |
* methods for setting the HTTP request method and determining whether |
57 |
HttpURLConnection(URL url) |
* or not to follow redirects. |
58 |
{ |
* |
59 |
super(url); |
* @since 1.1 |
60 |
} |
* |
61 |
|
* @author Warren Levy (warrenl@cygnus.com) |
62 |
/*************************************************************************/ |
* @author Aaron M. Renn (arenn@urbanophile.com) |
|
|
|
|
/* |
|
|
* Instance Methods |
|
63 |
*/ |
*/ |
64 |
|
public abstract class HttpURLConnection extends URLConnection |
|
/** |
|
|
* Sets the HTTP request method for this object. Allowable methods are: |
|
|
* GET, POST, HEAD, OPTIONS, PUT, DELETE, and TRACE. Note that not all |
|
|
* protocol implementations will necessarily support all of these |
|
|
* request methods. The default value is GET. |
|
|
* |
|
|
* @param method The request method to use |
|
|
* |
|
|
* @exception ProtocolException If the requested method isn't valid or cannot be used |
|
|
*/ |
|
|
public synchronized void |
|
|
setRequestMethod(String method) throws ProtocolException |
|
|
{ |
|
|
if (valid_methods.indexOf("|" + method.toUpperCase() + "|") == -1) |
|
|
throw new ProtocolException(method.toUpperCase()); |
|
|
|
|
|
this.method = method; |
|
|
} |
|
|
|
|
|
/*************************************************************************/ |
|
|
|
|
|
/** |
|
|
* The request method currently in use for this connection. |
|
|
* |
|
|
* @return The request method |
|
|
*/ |
|
|
public String |
|
|
getRequestMethod() |
|
|
{ |
|
|
return(method); |
|
|
} |
|
|
|
|
|
/*************************************************************************/ |
|
|
|
|
|
/** |
|
|
* Returns the numeric response code received from the server, or -1 if |
|
|
* no response code has yet been received, or the response code could not |
|
|
* be determined. Note that all valid response codes have class variables |
|
|
* defined for them in this class. |
|
|
* |
|
|
* @return The response code |
|
|
* |
|
|
* @IOException If an error occurs |
|
|
*/ |
|
|
public int |
|
|
getResponseCode() throws IOException |
|
|
{ |
|
|
return(responseCode); |
|
|
} |
|
|
|
|
|
/*************************************************************************/ |
|
|
|
|
|
/** |
|
|
* Returns the response message (everything after the response code in the |
|
|
* reply string received from the server) or null if no connection has been |
|
|
* made or no response message could be determined from the server output |
|
|
* |
|
|
* @return The response message |
|
|
* |
|
|
* @exception IOException If an error occurs |
|
|
*/ |
|
|
public String |
|
|
getResponseMessage() throws IOException |
|
|
{ |
|
|
return(responseMessage); |
|
|
} |
|
|
|
|
|
/*************************************************************************/ |
|
|
|
|
|
/** |
|
|
* This method allows the caller to retrieve any data that might have |
|
|
* been sent despite the fact that an error occurred. For example, the |
|
|
* HTML page sent along with a 404 File Not Found error. If the socket |
|
|
* is not connected, or if no error occurred or no data was returned, |
|
|
* this method returns <code>null</code>. |
|
|
* |
|
|
* @return An <code>InputStream</code> for reading error data. |
|
|
*/ |
|
|
public InputStream |
|
|
getErrorStream() |
|
|
{ |
|
|
if (!connected) |
|
|
return(null); |
|
|
|
|
|
int code; |
|
|
try |
|
|
{ |
|
|
code = getResponseCode(); |
|
|
} |
|
|
catch(IOException e) |
|
|
{ |
|
|
code = -1; |
|
|
} |
|
|
|
|
|
if (code == -1) |
|
|
return(null); |
|
|
|
|
|
if (((code/100) != 4) || ((code/100) != 5)) |
|
|
return(null); |
|
|
|
|
|
try |
|
|
{ |
|
|
PushbackInputStream pbis = new PushbackInputStream(getInputStream()); |
|
|
|
|
|
int i = pbis.read(); |
|
|
if (i == -1) |
|
|
return(null); |
|
|
|
|
|
pbis.unread(i); |
|
|
return(pbis); |
|
|
} |
|
|
catch(IOException e) |
|
|
{ |
|
|
return(null); |
|
|
} |
|
|
} |
|
|
|
|
|
/*************************************************************************/ |
|
|
|
|
|
/** |
|
|
* This method returns a <code>Permission</code> object that represents |
|
|
* the permission needed in order to access this URL. |
|
|
* |
|
|
* @param The needed permissions for accessing this URL. |
|
|
*/ |
|
|
public Permission |
|
|
getPermission() throws IOException |
|
65 |
{ |
{ |
66 |
URL url = getURL(); |
/* HTTP Success Response Codes */ |
|
String host = url.getHost(); |
|
|
int port = url.getPort(); |
|
|
if (port == -1) |
|
|
port = 80; |
|
67 |
|
|
68 |
host = host + ":" + port; |
/** |
69 |
|
* Indicates that the client may continue with its request. This value |
70 |
|
* is specified as part of RFC 2068 but was not included in Sun's JDK, so |
71 |
|
* beware of using this value |
72 |
|
*/ |
73 |
|
static final int HTTP_CONTINUE = 100; |
74 |
|
|
75 |
|
/** |
76 |
|
* Indicates the request succeeded. |
77 |
|
*/ |
78 |
|
public static final int HTTP_OK = 200; |
79 |
|
|
80 |
|
/** |
81 |
|
* The requested resource has been created. |
82 |
|
*/ |
83 |
|
public static final int HTTP_CREATED = 201; |
84 |
|
|
85 |
|
/** |
86 |
|
* The request has been accepted for processing but has not completed. |
87 |
|
* There is no guarantee that the requested action will actually ever |
88 |
|
* be completed succesfully, but everything is ok so far. |
89 |
|
*/ |
90 |
|
public static final int HTTP_ACCEPTED = 202; |
91 |
|
|
92 |
|
/** |
93 |
|
* The meta-information returned in the header is not the actual data |
94 |
|
* from the original server, but may be from a local or other copy. |
95 |
|
* Normally this still indicates a successful completion. |
96 |
|
*/ |
97 |
|
public static final int HTTP_NOT_AUTHORITATIVE = 203; |
98 |
|
|
99 |
|
/** |
100 |
|
* The server performed the request, but there is no data to send |
101 |
|
* back. This indicates that the user's display should not be changed. |
102 |
|
*/ |
103 |
|
public static final int HTTP_NO_CONTENT = 204; |
104 |
|
|
105 |
|
/** |
106 |
|
* The server performed the request, but there is no data to sent back, |
107 |
|
* however, the user's display should be "reset" to clear out any form |
108 |
|
* fields entered. |
109 |
|
*/ |
110 |
|
public static final int HTTP_RESET = 205; |
111 |
|
|
112 |
|
/** |
113 |
|
* The server completed the partial GET request for the resource. |
114 |
|
*/ |
115 |
|
public static final int HTTP_PARTIAL = 206; |
116 |
|
|
117 |
|
|
118 |
|
/* HTTP Redirection Response Codes */ |
119 |
|
|
120 |
|
/** |
121 |
|
* There is a list of choices available for the requested resource. |
122 |
|
*/ |
123 |
|
public static final int HTTP_MULT_CHOICE = 300; |
124 |
|
|
125 |
|
/** |
126 |
|
* The resource has been permanently moved to a new location. |
127 |
|
*/ |
128 |
|
public static final int HTTP_MOVED_PERM = 301; |
129 |
|
|
130 |
|
/** |
131 |
|
* The resource requested has been temporarily moved to a new location. |
132 |
|
*/ |
133 |
|
public static final int HTTP_MOVED_TEMP = 302; |
134 |
|
|
135 |
|
/** |
136 |
|
* The response to the request issued is available at another location. |
137 |
|
*/ |
138 |
|
public static final int HTTP_SEE_OTHER = 303; |
139 |
|
|
140 |
|
/** |
141 |
|
* The document has not been modified since the criteria specified in |
142 |
|
* a conditional GET. |
143 |
|
*/ |
144 |
|
public static final int HTTP_NOT_MODIFIED = 304; |
145 |
|
|
146 |
|
|
147 |
|
/* HTTP Client Error Response Codes */ |
148 |
|
|
149 |
return(new SocketPermission(host, "connect")); |
/** |
150 |
|
* The request was misformed or could not be understood. |
151 |
|
*/ |
152 |
|
public static final int HTTP_BAD_REQUEST = 400; |
153 |
|
|
154 |
|
/** |
155 |
|
* The request made requires user authorization. Try again with |
156 |
|
* a correct authentication header. |
157 |
|
*/ |
158 |
|
public static final int HTTP_UNAUTHORIZED = 401; |
159 |
|
|
160 |
|
/** |
161 |
|
* Code reserved for future use - I hope way in the future. |
162 |
|
*/ |
163 |
|
public static final int HTTP_PAYMENT_REQUIRED = 402; |
164 |
|
|
165 |
|
/** |
166 |
|
* There is no permission to access the requested resource. |
167 |
|
*/ |
168 |
|
public static final int HTTP_FORBIDDEN = 403; |
169 |
|
|
170 |
|
/** |
171 |
|
* The requested resource was not found. |
172 |
|
*/ |
173 |
|
public static final int HTTP_NOT_FOUND = 404; |
174 |
|
|
175 |
|
/** |
176 |
|
* The specified request method is not allowed for this resource. |
177 |
|
*/ |
178 |
|
public static final int HTTP_BAD_METHOD = 405; |
179 |
|
|
180 |
|
/** |
181 |
|
* Based on the input headers sent, the resource returned in response |
182 |
|
* to the request would not be acceptable to the client. |
183 |
|
*/ |
184 |
|
public static final int HTTP_NOT_ACCEPTABLE = 406; |
185 |
|
|
186 |
|
/** |
187 |
|
* The client must authenticate with a proxy prior to attempting this |
188 |
|
* request. |
189 |
|
*/ |
190 |
|
public static final int HTTP_PROXY_AUTH = 407; |
191 |
|
|
192 |
|
/** |
193 |
|
* The request timed out. |
194 |
|
*/ |
195 |
|
public static final int HTTP_CLIENT_TIMEOUT = 408; |
196 |
|
|
197 |
|
/** |
198 |
|
* There is a conflict between the current state of the resource and the |
199 |
|
* requested action. |
200 |
|
*/ |
201 |
|
public static final int HTTP_CONFLICT = 409; |
202 |
|
|
203 |
|
/** |
204 |
|
* The requested resource is no longer available. This ususally indicates |
205 |
|
* a permanent condition. |
206 |
|
*/ |
207 |
|
public static final int HTTP_GONE = 410; |
208 |
|
|
209 |
|
/** |
210 |
|
* A Content-Length header is required for this request, but was not |
211 |
|
* supplied. |
212 |
|
*/ |
213 |
|
public static final int HTTP_LENGTH_REQUIRED = 411; |
214 |
|
|
215 |
|
/** |
216 |
|
* A client specified pre-condition was not met on the server. |
217 |
|
*/ |
218 |
|
public static final int HTTP_PRECON_FAILED = 412; |
219 |
|
|
220 |
|
/** |
221 |
|
* The request sent was too large for the server to handle. |
222 |
|
*/ |
223 |
|
public static final int HTTP_ENTITY_TOO_LARGE = 413; |
224 |
|
|
225 |
|
/** |
226 |
|
* The name of the resource specified was too long. |
227 |
|
*/ |
228 |
|
public static final int HTTP_REQ_TOO_LONG = 414; |
229 |
|
|
230 |
|
/** |
231 |
|
* The request is in a format not supported by the requested resource. |
232 |
|
*/ |
233 |
|
public static final int HTTP_UNSUPPORTED_TYPE = 415; |
234 |
|
|
235 |
|
|
236 |
|
/* HTTP Server Error Response Codes */ |
237 |
|
|
238 |
|
/** |
239 |
|
* This error code indicates that some sort of server error occurred. |
240 |
|
*/ |
241 |
|
public static final int HTTP_SERVER_ERROR = 500; |
242 |
|
|
243 |
|
/** |
244 |
|
* The server encountered an unexpected error (such as a CGI script crash) |
245 |
|
* that prevents the request from being fulfilled. |
246 |
|
*/ |
247 |
|
public static final int HTTP_INTERNAL_ERROR = 500; |
248 |
|
|
249 |
|
/** |
250 |
|
* The server does not support the requested functionality. |
251 |
|
* @since 1.3 |
252 |
|
*/ |
253 |
|
static final int HTTP_NOT_IMPLEMENTED = 501; |
254 |
|
|
255 |
|
/** |
256 |
|
* The proxy encountered a bad response from the server it was proxy-ing for |
257 |
|
*/ |
258 |
|
public static final int HTTP_BAD_GATEWAY = 502; |
259 |
|
|
260 |
|
/** |
261 |
|
* The HTTP service is not availalble, such as because it is overloaded |
262 |
|
* and does not want additional requests. |
263 |
|
*/ |
264 |
|
public static final int HTTP_UNAVAILABLE = 503; |
265 |
|
|
266 |
|
/** |
267 |
|
* The proxy timed out getting a reply from the remote server it was |
268 |
|
* proxy-ing for. |
269 |
|
*/ |
270 |
|
public static final int HTTP_GATEWAY_TIMEOUT = 504; |
271 |
|
|
272 |
|
/** |
273 |
|
* This server does not support the protocol version requested. |
274 |
|
*/ |
275 |
|
public static final int HTTP_VERSION = 505; |
276 |
|
|
277 |
|
// Non-HTTP response static variables |
278 |
|
|
279 |
|
/** |
280 |
|
* Flag to indicate whether or not redirects should be automatically |
281 |
|
* followed by default. |
282 |
|
*/ |
283 |
|
private static boolean followRedirects = true; |
284 |
|
|
285 |
|
/** |
286 |
|
* This is a list of valid request methods, separated by "|" characters. |
287 |
|
*/ |
288 |
|
private static String valid_methods |
289 |
|
= "|GET|POST|HEAD|OPTIONS|PUT|DELETE|TRACE|"; |
290 |
|
|
291 |
|
// Instance Variables |
292 |
|
|
293 |
|
/** |
294 |
|
* The requested method in use for this connection. Default is GET. |
295 |
|
*/ |
296 |
|
protected String method = "GET"; |
297 |
|
|
298 |
|
/** |
299 |
|
* The response code received from the server |
300 |
|
*/ |
301 |
|
protected int responseCode = -1; |
302 |
|
|
303 |
|
/** |
304 |
|
* The response message string received from the server. |
305 |
|
*/ |
306 |
|
protected String responseMessage = null; |
307 |
|
|
308 |
|
/** |
309 |
|
* If this instance should follow redirect requests. |
310 |
|
*/ |
311 |
|
protected boolean instanceFollowRedirects = followRedirects; |
312 |
|
|
313 |
|
/** |
314 |
|
* Whether we alreadt got a valid response code for this connection. |
315 |
|
* Used by <code>getResponceCode()</code> and |
316 |
|
* <code>getResponseMessage()</code>. |
317 |
|
*/ |
318 |
|
private boolean gotResponseVals = false; |
319 |
|
|
320 |
|
/** |
321 |
|
* Create an HttpURLConnection for the specified URL |
322 |
|
* |
323 |
|
* @param url The URL to create this connection for. |
324 |
|
*/ |
325 |
|
protected HttpURLConnection(URL url) |
326 |
|
{ |
327 |
|
super(url); |
328 |
|
} |
329 |
|
|
330 |
|
/** |
331 |
|
* Closes the connection to the server. |
332 |
|
*/ |
333 |
|
public abstract void disconnect(); |
334 |
|
|
335 |
|
/** |
336 |
|
* Returns a boolean indicating whether or not this connection is going |
337 |
|
* through a proxy |
338 |
|
* |
339 |
|
* @return true if through a proxy, false otherwise |
340 |
|
*/ |
341 |
|
public abstract boolean usingProxy(); |
342 |
|
|
343 |
|
/** |
344 |
|
* Sets whether HTTP redirects (requests with response code 3xx) should be |
345 |
|
* automatically followed by this class. True by default |
346 |
|
* |
347 |
|
* @param set true if redirects should be followed, false otherwis. |
348 |
|
* |
349 |
|
* @exception SecurityException If a security manager exists and its |
350 |
|
* checkSetFactory method doesn't allow the operation |
351 |
|
*/ |
352 |
|
public static void setFollowRedirects(boolean set) |
353 |
|
{ |
354 |
|
// Throw an exception if an extant security mgr precludes |
355 |
|
// setting the factory. |
356 |
|
SecurityManager s = System.getSecurityManager(); |
357 |
|
if (s != null) |
358 |
|
s.checkSetFactory(); |
359 |
|
|
360 |
|
followRedirects = set; |
361 |
|
} |
362 |
|
|
363 |
|
/** |
364 |
|
* Returns a boolean indicating whether or not HTTP redirects will |
365 |
|
* automatically be followed or not. |
366 |
|
* |
367 |
|
* @return true if redirects will be followed, false otherwise |
368 |
|
*/ |
369 |
|
public static boolean getFollowRedirects() |
370 |
|
{ |
371 |
|
return followRedirects; |
372 |
|
} |
373 |
|
|
374 |
|
/** |
375 |
|
* Returns the value of this HttpURLConnection's instanceFollowRedirects |
376 |
|
* field |
377 |
|
*/ |
378 |
|
public boolean getInstanceFollowRedirects () |
379 |
|
{ |
380 |
|
return instanceFollowRedirects; |
381 |
|
} |
382 |
|
|
383 |
|
/** |
384 |
|
* Sets the value of this HttpURLConnection's instanceFollowRedirects field |
385 |
|
*/ |
386 |
|
public void setInstanceFollowRedirects (boolean follow) |
387 |
|
{ |
388 |
|
instanceFollowRedirects = follow; |
389 |
|
} |
390 |
|
|
391 |
|
/** |
392 |
|
* Set the method for the URL request, one of: |
393 |
|
* GET POST HEAD OPTIONS PUT DELETE TRACE are legal |
394 |
|
* |
395 |
|
* @exception ProtocolException If the method cannot be reset or if the |
396 |
|
* requested method isn't valid for HTTP |
397 |
|
*/ |
398 |
|
public void setRequestMethod(String method) throws ProtocolException |
399 |
|
{ |
400 |
|
if (connected) |
401 |
|
throw new ProtocolException("Already connected"); |
402 |
|
|
403 |
|
method = method.toUpperCase(); |
404 |
|
if (valid_methods.indexOf("|" + method + "|") != -1) |
405 |
|
this.method = method; |
406 |
|
else |
407 |
|
throw new ProtocolException("Invalid HTTP request method: " + method); |
408 |
|
|
409 |
|
} |
410 |
|
|
411 |
|
/** |
412 |
|
* The request method currently in use for this connection. |
413 |
|
* |
414 |
|
* @return The request method |
415 |
|
*/ |
416 |
|
public String getRequestMethod() |
417 |
|
{ |
418 |
|
return method; |
419 |
|
} |
420 |
|
|
421 |
|
/** |
422 |
|
* Gets the status code from an HTTP response message, or -1 if |
423 |
|
* the response code could not be determined. |
424 |
|
* Note that all valid response codes have class variables |
425 |
|
* defined for them in this class. |
426 |
|
* |
427 |
|
* @return The response code |
428 |
|
* |
429 |
|
* @exception IOException If an error occurs |
430 |
|
*/ |
431 |
|
public int getResponseCode() throws IOException |
432 |
|
{ |
433 |
|
if (!gotResponseVals) |
434 |
|
getResponseVals(); |
435 |
|
return responseCode; |
436 |
|
} |
437 |
|
|
438 |
|
/** |
439 |
|
* Gets the HTTP response message, if any, returned along with the |
440 |
|
* response code from a server. Null if no response message was set |
441 |
|
* or an error occured while connecting. |
442 |
|
* |
443 |
|
* @return The response message |
444 |
|
* |
445 |
|
* @exception IOException If an error occurs |
446 |
|
*/ |
447 |
|
public String getResponseMessage() throws IOException |
448 |
|
{ |
449 |
|
if (!gotResponseVals) |
450 |
|
getResponseVals(); |
451 |
|
return responseMessage; |
452 |
|
} |
453 |
|
|
454 |
|
private void getResponseVals() throws IOException |
455 |
|
{ |
456 |
|
// getHeaderField() will connect for us, but do it here first in |
457 |
|
// order to pick up IOExceptions. |
458 |
|
if (!connected) |
459 |
|
connect(); |
460 |
|
|
461 |
|
gotResponseVals = true; |
462 |
|
// Response is the first header received from the connection. |
463 |
|
String respField = getHeaderField(0); |
464 |
|
|
465 |
|
if (respField == null || ! respField.startsWith("HTTP/")) |
466 |
|
{ |
467 |
|
// Set to default values on failure. |
468 |
|
responseCode = -1; |
469 |
|
responseMessage = null; |
470 |
|
return; |
471 |
|
} |
472 |
|
|
473 |
|
int firstSpc, nextSpc; |
474 |
|
firstSpc = respField.indexOf(' '); |
475 |
|
nextSpc = respField.indexOf(' ', firstSpc + 1); |
476 |
|
responseMessage = respField.substring(nextSpc + 1); |
477 |
|
String codeStr = respField.substring(firstSpc + 1, nextSpc); |
478 |
|
try |
479 |
|
{ |
480 |
|
responseCode = Integer.parseInt(codeStr); |
481 |
|
} |
482 |
|
catch (NumberFormatException e) |
483 |
|
{ |
484 |
|
// Set to default values on failure. |
485 |
|
responseCode = -1; |
486 |
|
responseMessage = null; |
487 |
|
} |
488 |
|
} |
489 |
|
|
490 |
|
/** |
491 |
|
* Returns a permission object representing the permission necessary to make |
492 |
|
* the connection represented by this object |
493 |
|
* |
494 |
|
* @exception IOException If an error occurs |
495 |
|
*/ |
496 |
|
public Permission getPermission() throws IOException |
497 |
|
{ |
498 |
|
return new SocketPermission (url.getHost (), "connect"); |
499 |
|
} |
500 |
|
|
501 |
|
/** |
502 |
|
* Returns the error stream if the connection failed but the server sent |
503 |
|
* useful data nonetheless |
504 |
|
*/ |
505 |
|
public InputStream getErrorStream () |
506 |
|
{ |
507 |
|
// FIXME: implement this |
508 |
|
return null; |
509 |
|
} |
510 |
|
|
511 |
|
/** |
512 |
|
* Returns the value of the named field parsed as date |
513 |
|
*/ |
514 |
|
public long getHeaderFieldDate (String key, long value) |
515 |
|
{ |
516 |
|
// FIXME: implement this correctly |
517 |
|
// http://www.w3.org/Protocols/HTTP-NG/ng-notes.txt |
518 |
|
|
519 |
|
return super.getHeaderFieldDate (key, value); |
520 |
|
} |
521 |
} |
} |
|
|
|
|
/*************************************************************************/ |
|
|
|
|
|
/** |
|
|
* Closes the connection to the server. |
|
|
*/ |
|
|
public abstract void |
|
|
disconnect(); |
|
|
|
|
|
/*************************************************************************/ |
|
|
|
|
|
/** |
|
|
* Returns a boolean indicating whether or not this connection is going |
|
|
* through a proxy |
|
|
* |
|
|
* @return true if through a proxy, false otherwise |
|
|
*/ |
|
|
public abstract boolean |
|
|
usingProxy(); |
|
|
|
|
|
} // class HttpURLConnection |
|
|
|
|