Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/sonalb/net/http/HTTPRedirectHandler.java


1   /*
2    * -*- mode: java; c-basic-indent: 4; indent-tabs-mode: nil -*-
3    * :indentSize=4:noTabs=true:tabSize=4:indentOnTab=true:indentOnEnter=true:mode=java:
4    * ex: set tabstop=4 expandtab:
5    *
6    * MrPostman - webmail <-> email gateway
7    * Copyright (C) 2002-2003 MrPostman Development Group
8    * Projectpage: http://mrbook.org/mrpostman/
9    *
10   *
11   * This program is free software; you can redistribute it and/or modify
12   * it under the terms of the GNU General Public License as published by
13   * the Free Software Foundation; either version 2 of the License, or
14   * (at your option) any later version.
15   *
16   * This program is distributed in the hope that it will be useful,
17   * but WITHOUT ANY WARRANTY; without even the implied warranty of
18   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   * GNU General Public License for more details.
20   * In particular, this implies that users are responsible for
21   * using MrPostman after reading the terms and conditions given
22   * by their web-mail provider.
23   *
24   * You should have received a copy of the GNU General Public License
25   * Named LICENSE in the base directory of this distribution,
26   * if not, write to the Free Software
27   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28   */
29  
30  package com.sonalb.net.http;
31  
32  import com.sonalb.net.http.cookie.Client;
33  import com.sonalb.net.http.cookie.CookieJar;
34  import com.sonalb.net.http.cookie.MalformedCookieException;
35  
36  import java.io.IOException;
37  import java.io.InputStream;
38  
39  import java.net.HttpURLConnection;
40  import java.net.URL;
41  
42  import java.util.Map;
43  import java.util.Iterator;
44  import java.util.List;
45  
46  /**
47  
48   * Convenience class that combines cookie-handling and redirect-handling logic. When the connect()
49  
50   * method is invoked, the handler cyclically processes HTTP Redirects (if any), and also takes care of
51  
52   * cookie-handling while doing so. The maximum number of redirects defaults to 10. The handler determines
53  
54   * a successful run, when the HTTP response code is equal to a specified success code. This code defaults
55  
56   * to 200 (OK).
57  
58   * @author Sonal Bansal
59  
60   */
61  public class HTTPRedirectHandler {
62      public static final String CVSID = "$Id: HTTPRedirectHandler.java,v 1.7 2003/02/22 09:17:19 lbruand Exp $";
63      HttpURLConnection huc;
64      CookieJar cj = new CookieJar();
65      Client client = new Client();
66      boolean bCookies = true;
67      int successCode = 200;
68      int maxRedirects = 10;
69      boolean bConnected = false;
70      boolean bConnectMethodAlreadyCalled = false;
71      InputStream is;
72  
73      /**
74  
75       * Creates a handler for the input HttpURLConnection. The HttpURLConnection must NOT be
76  
77       * connected yet.
78  
79       */
80      public HTTPRedirectHandler(HttpURLConnection huc) {
81          if (huc == null) {
82              throw new NullPointerException();
83          }
84  
85          this.huc = huc;
86      }
87  
88      /**
89  
90       * Sets the Client to be used for this handler.
91  
92       */
93      public void setClient(Client cl) {
94          if (cl == null) {
95              throw new IllegalArgumentException("Null argument.");
96          }
97  
98          synchronized (client) {
99              client = cl;
100         }
101     }
102 
103     /**
104 
105      * Enables/Disables automated cookie-handling.
106 
107      */
108     public void handleCookies(boolean b) {
109         bCookies = b;
110     }
111 
112     /**
113 
114      * Sets the HTTP response code designating a successful run.
115 
116      * @param i the code; non-positive values ignored
117 
118      */
119     public void setSuccessCode(int i) {
120         if (i > 0) {
121             successCode = i;
122         }
123     }
124 
125     /**
126 
127      * Sets the CookieJar containing Cookies to be used during cookie-handling.
128 
129      */
130     public void setCookieJar(CookieJar cj) {
131         if ((cj == null) || cj.isEmpty()) {
132             return;
133         }
134 
135         this.cj = cj;
136     }
137 
138     /**
139 
140      * Adds some Cookies to the existing Cookies in an HTTPRedirectHandler.
141 
142      * @param cj the Cookies to be added
143 
144      */
145     public void addCookies(CookieJar cj) {
146         if ((cj == null) || cj.isEmpty()) {
147             return;
148         }
149 
150         this.cj.addAll(cj);
151     }
152 
153     /**
154 
155      * Gets the CookieJar containing any pre-existing Cookies, as well as new ones extracted
156 
157      * during processing.
158 
159      * @return the CookieJar; always non-null
160 
161      */
162     public CookieJar getCookieJar() {
163         return (cj);
164     }
165 
166     /**
167 
168      * Gets the InputStream for the final successful response.
169 
170      * @throws IllegalStateException when called before successful connection.
171 
172      */
173     public InputStream getInputStream() {
174         if (!bConnected) {
175             throw new IllegalStateException("Not Connected");
176         }
177 
178         return (is);
179     }
180 
181     /**
182 
183      * Gets the HttpURLConnection for the final successful response.
184 
185      */
186     public HttpURLConnection getConnection() {
187         if (!bConnected) {
188             throw new IllegalStateException("Not Connected");
189         }
190 
191         return (huc);
192     }
193 
194     /**
195 
196      * Sets the maximum number of redirects that will be followed.
197 
198      * @param i the max number; non-positive values are ignored
199 
200      */
201     public void setMaxRedirects(int i) {
202         if (i > 0) {
203             maxRedirects = i;
204         }
205     }
206 
207     /**
208 
209      * Connects to initial HttpURLConnection (specified during construction), and initiates
210 
211      * cookie-handling and redirect-handling. It can only be called once per instance.
212 
213      * @throws IOException if there is an I/O problem
214 
215      * @throws MalformedCookieException if there was a problem with cookie-handling
216 
217      * @throws IllegalStateException if this method has already been called
218 
219      */
220     public void connect() throws IOException, MalformedCookieException {
221         if (bConnectMethodAlreadyCalled) {
222             throw new IllegalStateException("No can do.");
223         }
224         Map requestProps = huc.getRequestProperties();
225         bConnectMethodAlreadyCalled = true;
226 
227         int code;
228 
229         URL url;
230 
231         huc.setFollowRedirects(false);
232 
233         if (!cj.isEmpty()) {
234             client.setCookies(huc, cj);
235         }
236 
237         is = huc.getInputStream();
238 
239         cj.addAll(client.getCookies(huc));
240 
241         while (((code = huc.getResponseCode()) != successCode) && (maxRedirects > 0)) {
242             if ((code < 300) || (code > 399)) {
243                 throw new IOException("Can't deal with this response code (" + code + ").");
244             }
245 
246             is.close();
247 
248             is = null;
249 
250             url = new URL(huc.getHeaderField("location"));
251             
252             
253             huc.disconnect();
254 
255             huc = null;
256 
257             huc = (HttpURLConnection) url.openConnection();
258             if (requestProps != null) {
259                 StringBuffer sb;
260                 for (Iterator i = requestProps.entrySet().iterator(); i.hasNext();) {
261                     Map.Entry e = (Map.Entry) i.next();
262                     sb = new StringBuffer();
263                     for (Iterator j = ((List) e.getValue()).iterator(); j.hasNext();) {
264                         if (sb.length() != 0) {
265                             sb.append(", ");
266                         }
267                         sb.append((String) j.next());
268                     }
269                     huc.setRequestProperty((String) e.getKey(), sb.toString());
270                 }
271                 requestProps = null;
272             }
273 
274 
275             client.setCookies(huc, cj);
276 
277             huc.setFollowRedirects(false);
278 
279             huc.connect();
280 
281             is = huc.getInputStream();
282 
283             cj.addAll(client.getCookies(huc));
284 
285             maxRedirects--;
286         }
287 
288         if ((maxRedirects <= 0) && (code != successCode)) {
289             throw new IOException("Max redirects exhausted.");
290         }
291 
292         bConnected = true;
293     }
294 
295     /**
296 
297      * Checks whether this handler has successfully connected.
298 
299      */
300     public boolean isConnected() {
301         return (bConnected);
302     }
303 }