View Javadoc

1   /*
2    * $Header: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/util/HttpURLConnection.java,v 1.12.2.2 2004/02/22 18:21:16 olegk Exp $
3    * $Revision: 1.12.2.2 $
4    * $Date: 2004/02/22 18:21:16 $
5    *
6    * ====================================================================
7    *
8    *  Copyright 1999-2004 The Apache Software Foundation
9    *
10   *  Licensed under the Apache License, Version 2.0 (the "License");
11   *  you may not use this file except in compliance with the License.
12   *  You may obtain a copy of the License at
13   *
14   *      http://www.apache.org/licenses/LICENSE-2.0
15   *
16   *  Unless required by applicable law or agreed to in writing, software
17   *  distributed under the License is distributed on an "AS IS" BASIS,
18   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19   *  See the License for the specific language governing permissions and
20   *  limitations under the License.
21   * ====================================================================
22   *
23   * This software consists of voluntary contributions made by many
24   * individuals on behalf of the Apache Software Foundation.  For more
25   * information on the Apache Software Foundation, please see
26   * <http://www.apache.org/>.
27   *
28   * [Additional notices, if required by prior licensing conditions]
29   *
30   */
31  
32  package org.apache.commons.httpclient.util;
33  
34  import org.apache.commons.httpclient.HttpMethod;
35  import org.apache.commons.httpclient.Header;
36  
37  import org.apache.commons.logging.LogFactory;
38  import org.apache.commons.logging.Log;
39  import java.io.IOException;
40  import java.io.InputStream;
41  import java.io.OutputStream;
42  import java.net.URL;
43  import java.net.ProtocolException;
44  import java.security.Permission;
45  
46  /***
47   * Provides a <code>HttpURLConnection</code> wrapper around HttpClient's
48   * <code>HttpMethod</code>. This allows existing code to easily switch to
49   * HttpClieht without breaking existing interfaces using the JDK
50   * <code>HttpURLConnection</code>.
51   *
52   * Note 1: The current implementations wraps only a connected
53   * <code>HttpMethod</code>, ie a method that has alreayd been used to connect
54   * to an HTTP server.
55   *
56   * Note 2: It is a best try effort as different version of the JDK have
57   * different behaviours for <code>HttpURLConnection</code> (And I'm not even
58   * including the numerous <code>HttpURLConnection</code> bugs!).
59   *
60   * @author <a href="mailto:vmassol@apache.org">Vincent Massol</a>
61   * @author <a href="mailto:jsdever@apache.org">Jeff Dever</a>
62   * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
63   *
64   * @since 2.0
65   *
66   * @version $Id: HttpURLConnection.java,v 1.12.2.2 2004/02/22 18:21:16 olegk Exp $
67   */
68  public class HttpURLConnection extends java.net.HttpURLConnection {
69  
70      // -------------------------------------------------------- Class Variables
71     
72      /*** Log object for this class. */
73      private static final Log LOG = LogFactory.getLog(HttpURLConnection.class);
74  
75  
76      // ----------------------------------------------------- Instance Variables
77  
78      /***
79       * The <code>HttpMethod</code> object that was used to connect to the
80       * HTTP server. It contains all the returned data.
81       */
82      private HttpMethod method;
83  
84      /***
85       * The URL to which we are connected
86       */
87      private URL url;
88  
89  
90  
91      // ----------------------------------------------------------- Constructors
92  
93      /***
94       * Creates an <code>HttpURLConnection</code> from a <code>HttpMethod</code>.
95       *
96       * @param method the theMethod that was used to connect to the HTTP
97       *        server and which contains the returned data.
98       * @param url the URL to which we are connected (includes query string)
99       */
100     public HttpURLConnection(HttpMethod method, URL url) {
101         super(url);
102         this.method = method;
103         this.url = url;
104     }
105 
106     /***
107      * Create an instance.
108      * @param url The URL.
109      * @see java.net.HttpURLConnection#HttpURLConnection(URL)
110      */
111     protected HttpURLConnection(URL url) {
112         super(url);
113         throw new RuntimeException("An HTTP URL connection can only be "
114             + "constructed from a HttpMethod class");
115     }
116 
117 
118     // --------------------------------------------------------- Public Methods
119 
120     /*** 
121      * Gets an input stream for the HttpMethod response body.
122      * @throws IOException If an IO problem occurs.
123      * @return The input stream.
124      * @see java.net.HttpURLConnection#getInputStream()
125      * @see org.apache.commons.httpclient.HttpMethod#getResponseBodyAsStream()
126      */
127     public InputStream getInputStream() throws IOException {
128         LOG.trace("enter HttpURLConnection.getInputStream()");
129         return this.method.getResponseBodyAsStream();
130     }
131 
132     /***
133      * Not yet implemented.
134      * Return the error stream.
135      * @see java.net.HttpURLConnection#getErrorStream()
136      */
137     public InputStream getErrorStream() {
138         LOG.trace("enter HttpURLConnection.getErrorStream()");
139         throw new RuntimeException("Not implemented yet");
140     }
141 
142     /***
143      * Not yet implemented.
144      * @see java.net.HttpURLConnection#disconnect()
145      */
146     public void disconnect() {
147         LOG.trace("enter HttpURLConnection.disconnect()");
148         throw new RuntimeException("Not implemented yet");
149     }
150 
151     /***
152      * Not available: the data must have already been retrieved.
153      * @throws IOException If an IO problem occurs.
154      * @see java.net.HttpURLConnection#connect()
155      */
156     public void connect() throws IOException {
157         LOG.trace("enter HttpURLConnection.connect()");
158         throw new RuntimeException("This class can only be used with already"
159             + "retrieved data");
160     }
161 
162     /***
163      * Not yet implemented.
164      * @return true if we are using a proxy.
165      * @see java.net.HttpURLConnection#usingProxy()
166      */
167     public boolean usingProxy() {
168         LOG.trace("enter HttpURLConnection.usingProxy()");
169         throw new RuntimeException("Not implemented yet");
170     }
171 
172     /***
173      * Return the request method.
174      * @return The request method.
175      * @see java.net.HttpURLConnection#getRequestMethod()
176      * @see org.apache.commons.httpclient.HttpMethod#getName()
177      */
178     public String getRequestMethod() {
179         LOG.trace("enter HttpURLConnection.getRequestMethod()");
180         return this.method.getName();
181     }
182 
183     /***
184      * Return the response code.
185      * @return The response code.
186      * @throws IOException If an IO problem occurs.
187      * @see java.net.HttpURLConnection#getResponseCode()
188      * @see org.apache.commons.httpclient.HttpMethod#getStatusCode()
189      */
190     public int getResponseCode() throws IOException {
191         LOG.trace("enter HttpURLConnection.getResponseCode()");
192         return this.method.getStatusCode();
193     }
194 
195     /***
196      * Return the response message
197      * @return The response message
198      * @throws IOException If an IO problem occurs.
199      * @see java.net.HttpURLConnection#getResponseMessage()
200      * @see org.apache.commons.httpclient.HttpMethod#getStatusText()
201      */
202     public String getResponseMessage() throws IOException {
203         LOG.trace("enter HttpURLConnection.getResponseMessage()");
204         return this.method.getStatusText();
205     }
206 
207     /***
208      * Return the header field
209      * @param name the name of the header
210      * @return the header field.
211      * @see java.net.HttpURLConnection#getHeaderField(String)
212      * @see org.apache.commons.httpclient.HttpMethod#getResponseHeaders()
213      */
214     public String getHeaderField(String name) {
215         LOG.trace("enter HttpURLConnection.getHeaderField(String)");
216         // Note: Return the last matching header in the Header[] array, as in
217         // the JDK implementation.
218         Header[] headers = this.method.getResponseHeaders();
219         for (int i = headers.length - 1; i >= 0; i--) {
220             if (headers[i].getName().equalsIgnoreCase(name)) {
221                 return headers[i].getValue();
222             }
223         }
224 
225         return null;
226     }
227 
228     /***
229      * Return the header field key
230      * @param keyPosition The key position
231      * @return The header field key.
232      * @see java.net.HttpURLConnection#getHeaderFieldKey(int)
233      * @see org.apache.commons.httpclient.HttpMethod#getResponseHeaders()
234      */
235     public String getHeaderFieldKey(int keyPosition) {
236         LOG.trace("enter HttpURLConnection.getHeaderFieldKey(int)");
237 
238         // Note: HttpClient does not consider the returned Status Line as
239         // a response header. However, getHeaderFieldKey(0) is supposed to 
240         // return null. Hence the special case below ...
241         
242         if (keyPosition == 0) {
243             return null;
244         }
245 
246         // Note: HttpClient does not currently keep headers in the same order
247         // that they are read from the HTTP server.
248 
249         Header[] headers = this.method.getResponseHeaders();
250         if (keyPosition < 0 || keyPosition > headers.length) {
251             return null;
252         }
253 
254         return headers[keyPosition - 1].getName();
255     }
256 
257     /***
258      * Return the header field at the specified position
259      * @param position The position
260      * @return The header field.
261      * @see java.net.HttpURLConnection#getHeaderField(int)
262      * @see org.apache.commons.httpclient.HttpMethod#getResponseHeaders()
263      */
264     public String getHeaderField(int position) {
265         LOG.trace("enter HttpURLConnection.getHeaderField(int)");
266 
267         // Note: HttpClient does not consider the returned Status Line as
268         // a response header. However, getHeaderField(0) is supposed to 
269         // return the status line. Hence the special case below ...
270         
271         if (position == 0) {
272             return this.method.getStatusLine().toString();
273         }
274 
275         // Note: HttpClient does not currently keep headers in the same order
276         // that they are read from the HTTP server.
277 
278         Header[] headers = this.method.getResponseHeaders();
279         if (position < 0 || position > headers.length) {
280             return null;
281         }
282 
283         return headers[position - 1].getValue();
284     }
285 
286     /***
287      * Return the URL
288      * @return The URL.
289      * @see java.net.HttpURLConnection#getURL()
290      */
291     public URL getURL() {
292         LOG.trace("enter HttpURLConnection.getURL()");
293         return this.url;
294     }
295 
296     // Note: We don't implement the following methods so that they default to
297     // the JDK implementation. They will all call
298     // <code>getHeaderField(String)</code> which we have overridden.
299 
300     // java.net.HttpURLConnection#getHeaderFieldDate(String, long)
301     // java.net.HttpURLConnection#getContentLength()
302     // java.net.HttpURLConnection#getContentType()
303     // java.net.HttpURLConnection#getContentEncoding()
304     // java.net.HttpURLConnection#getDate()
305     // java.net.HttpURLConnection#getHeaderFieldInt(String, int)
306     // java.net.HttpURLConnection#getExpiration()
307     // java.net.HttpURLConnection#getLastModified()
308 
309     /***
310      * Not available: the data must have already been retrieved.
311      */
312     public void setInstanceFollowRedirects(boolean isFollowingRedirects) {
313         LOG.trace("enter HttpURLConnection.setInstanceFollowRedirects(boolean)");
314         throw new RuntimeException("This class can only be used with already"
315             + "retrieved data");
316     }
317 
318     /***
319      * Not yet implemented.
320      */
321     public boolean getInstanceFollowRedirects() {
322         LOG.trace("enter HttpURLConnection.getInstanceFollowRedirects()");
323         throw new RuntimeException("Not implemented yet");
324     }
325 
326     /***
327      * Not available: the data must have already been retrieved.
328      * @see java.net.HttpURLConnection#setRequestMethod(String)
329      */
330     public void setRequestMethod(String method) throws ProtocolException {
331         LOG.trace("enter HttpURLConnection.setRequestMethod(String)");
332         throw new RuntimeException("This class can only be used with already"
333             + "retrieved data");
334     }
335 
336     /***
337      * Not yet implemented.
338      * @see java.net.HttpURLConnection#getPermission()
339      */
340     public Permission getPermission() throws IOException {
341         LOG.trace("enter HttpURLConnection.getPermission()");
342         throw new RuntimeException("Not implemented yet");
343     }
344 
345     /***
346      * Not yet implemented.
347      * @see java.net.HttpURLConnection#getContent()
348      */
349     public Object getContent() throws IOException {
350         LOG.trace("enter HttpURLConnection.getContent()");
351         throw new RuntimeException("Not implemented yet");
352     }
353 
354     /***
355      * Not yet implemented.
356      */
357     public Object getContent(Class[] classes) throws IOException {
358         LOG.trace("enter HttpURLConnection.getContent(Class[])");
359         throw new RuntimeException("Not implemented yet");
360     }
361 
362     /***
363      * @see java.net.HttpURLConnection#getOutputStream()
364      */
365     public OutputStream getOutputStream() throws IOException {
366         LOG.trace("enter HttpURLConnection.getOutputStream()");
367         throw new RuntimeException("This class can only be used with already"
368             + "retrieved data");
369     }
370 
371     /***
372      * Not available: the data must have already been retrieved.
373      * @see java.net.HttpURLConnection#setDoInput(boolean)
374      */
375     public void setDoInput(boolean isInput) {
376         LOG.trace("enter HttpURLConnection.setDoInput()");
377         throw new RuntimeException("This class can only be used with already"
378             + "retrieved data");
379     }
380 
381     /***
382      * Not yet implemented.
383      * @see java.net.HttpURLConnection#getDoInput()
384      */
385     public boolean getDoInput() {
386         LOG.trace("enter HttpURLConnection.getDoInput()");
387         throw new RuntimeException("Not implemented yet");
388     }
389 
390     /***
391      * Not available: the data must have already been retrieved.
392      * @see java.net.HttpURLConnection#setDoOutput(boolean)
393      */
394     public void setDoOutput(boolean isOutput) {
395         LOG.trace("enter HttpURLConnection.setDoOutput()");
396         throw new RuntimeException("This class can only be used with already"
397             + "retrieved data");
398     }
399 
400     /***
401      * Not yet implemented.
402      * @see java.net.HttpURLConnection#getDoOutput()
403      */
404     public boolean getDoOutput() {
405         LOG.trace("enter HttpURLConnection.getDoOutput()");
406         throw new RuntimeException("Not implemented yet");
407     }
408 
409     /***
410      * Not available: the data must have already been retrieved.
411      * @see java.net.HttpURLConnection#setAllowUserInteraction(boolean)
412      */
413     public void setAllowUserInteraction(boolean isAllowInteraction) {
414         LOG.trace("enter HttpURLConnection.setAllowUserInteraction(boolean)");
415         throw new RuntimeException("This class can only be used with already"
416             + "retrieved data");
417     }
418 
419     /***
420      * Not yet implemented.
421      * @see java.net.HttpURLConnection#getAllowUserInteraction()
422      */
423     public boolean getAllowUserInteraction() {
424         LOG.trace("enter HttpURLConnection.getAllowUserInteraction()");
425         throw new RuntimeException("Not implemented yet");
426     }
427 
428     /***
429      * Not available: the data must have already been retrieved.
430      * @see java.net.HttpURLConnection#setUseCaches(boolean)
431      */
432     public void setUseCaches(boolean isUsingCaches) {
433         LOG.trace("enter HttpURLConnection.setUseCaches(boolean)");
434         throw new RuntimeException("This class can only be used with already"
435             + "retrieved data");
436     }
437 
438     /***
439      * Not yet implemented.
440      * @see java.net.HttpURLConnection#getUseCaches()
441      */
442     public boolean getUseCaches() {
443         LOG.trace("enter HttpURLConnection.getUseCaches()");
444         throw new RuntimeException("Not implemented yet");
445     }
446 
447     /***
448      * Not available: the data must have already been retrieved.
449      * @see java.net.HttpURLConnection#setIfModifiedSince(long)
450      */
451     public void setIfModifiedSince(long modificationDate) {
452         LOG.trace("enter HttpURLConnection.setIfModifiedSince(long)");
453         throw new RuntimeException("This class can only be used with already"
454             + "retrieved data");
455     }
456 
457     /***
458      * Not yet implemented.
459      * @see java.net.HttpURLConnection#getIfModifiedSince()
460      */
461     public long getIfModifiedSince() {
462         LOG.trace("enter HttpURLConnection.getIfmodifiedSince()");
463         throw new RuntimeException("Not implemented yet");
464     }
465 
466     /***
467      * Not available: the data must have already been retrieved.
468      * @see java.net.HttpURLConnection#getDefaultUseCaches()
469      */
470     public boolean getDefaultUseCaches() {
471         LOG.trace("enter HttpURLConnection.getDefaultUseCaches()");
472         throw new RuntimeException("Not implemented yet");
473     }
474 
475     /***
476      * Not available: the data must have already been retrieved.
477      * @see java.net.HttpURLConnection#setDefaultUseCaches(boolean)
478      */
479     public void setDefaultUseCaches(boolean isUsingCaches) {
480         LOG.trace("enter HttpURLConnection.setDefaultUseCaches(boolean)");
481         throw new RuntimeException("This class can only be used with already"
482             + "retrieved data");
483     }
484 
485     /***
486      * Not available: the data must have already been retrieved.
487      * @see java.net.HttpURLConnection#setRequestProperty(String,String)
488      */
489     public void setRequestProperty(String key, String value) {
490         LOG.trace("enter HttpURLConnection.setRequestProperty()");
491         throw new RuntimeException("This class can only be used with already"
492             + "retrieved data");
493     }
494 
495     /***
496      * Not yet implemented.
497      * @see java.net.HttpURLConnection#getRequestProperty(String)
498      */
499     public String getRequestProperty(String key) {
500         LOG.trace("enter HttpURLConnection.getRequestProperty()");
501         throw new RuntimeException("Not implemented yet");
502     }
503 
504 }
505