View Javadoc

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