KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > fr > jayasoft > ivy > url > HttpClientHandler


1 /*
2  * This file is subject to the license found in LICENCE.TXT in the root directory of the project.
3  *
4  * #SNAPSHOT#
5  */

6 package fr.jayasoft.ivy.url;
7
8 import java.io.File JavaDoc;
9 import java.io.IOException JavaDoc;
10 import java.io.InputStream JavaDoc;
11 import java.net.URL JavaDoc;
12 import java.net.UnknownHostException JavaDoc;
13 import java.text.ParseException JavaDoc;
14 import java.text.SimpleDateFormat JavaDoc;
15 import java.util.ArrayList JavaDoc;
16 import java.util.List JavaDoc;
17 import java.util.Locale JavaDoc;
18
19 import org.apache.commons.httpclient.Header;
20 import org.apache.commons.httpclient.HttpClient;
21 import org.apache.commons.httpclient.HttpException;
22 import org.apache.commons.httpclient.HttpMethodBase;
23 import org.apache.commons.httpclient.HttpStatus;
24 import org.apache.commons.httpclient.UsernamePasswordCredentials;
25 import org.apache.commons.httpclient.auth.AuthPolicy;
26 import org.apache.commons.httpclient.methods.GetMethod;
27 import org.apache.commons.httpclient.methods.HeadMethod;
28
29 import fr.jayasoft.ivy.util.CopyProgressListener;
30 import fr.jayasoft.ivy.util.Credentials;
31 import fr.jayasoft.ivy.util.FileUtil;
32 import fr.jayasoft.ivy.util.Message;
33
34 /**
35  * @author Xavier Hanin
36  *
37  */

38 public class HttpClientHandler extends AbstractURLHandler {
39     private static final SimpleDateFormat JavaDoc LAST_MODIFIED_FORMAT = new SimpleDateFormat JavaDoc("EEE, d MMM yyyy HH:mm:ss z", Locale.US);
40     
41     // proxy configuration: obtain from system properties
42
private int _proxyPort;
43
44     private String JavaDoc _proxyRealm = null;
45     private String JavaDoc _proxyHost = null;
46     private String JavaDoc _proxyUserName = null;
47     private String JavaDoc _proxyPasswd = null;
48     
49     private HttpClientHelper _httpClientHelper;
50     
51     public HttpClientHandler() {
52         configureProxy();
53     }
54
55     private void configureProxy() {
56         _proxyRealm = null;
57         //no equivalent for realm in jdk proxy support ?
58
_proxyHost = System.getProperty("http.proxyHost");
59         //TODO constant is better ...
60
if(useProxy()) {
61             _proxyPort = Integer.parseInt(System.getProperty("http.proxyPort", "80"));
62             _proxyUserName = System.getProperty("http.proxyUser");
63             _proxyPasswd = System.getProperty("http.proxyPassword");
64             //It seems there is no equivalent in HttpClient for
65
// 'http.nonProxyHosts' property
66
Message.verbose("proxy configured: host="+_proxyHost+" port="+_proxyPort+" user="+_proxyUserName);
67         } else {
68             Message.verbose("no proxy configured");
69         }
70     }
71     
72     
73     
74     public InputStream JavaDoc openStream(URL JavaDoc url) throws IOException JavaDoc {
75         GetMethod get = doGet(url);
76         return new GETInputStream(get);
77     }
78     
79     public void download(URL JavaDoc src, File JavaDoc dest, CopyProgressListener l) throws IOException JavaDoc {
80         GetMethod get = doGet(src);
81         FileUtil.copy(get.getResponseBodyAsStream(), dest, l);
82         get.releaseConnection();
83     }
84     
85     public URLInfo getURLInfo(URL JavaDoc url) {
86         return getURLInfo(url, 0);
87     }
88
89     public URLInfo getURLInfo(URL JavaDoc url, int timeout) {
90         HeadMethod head = null;
91         try {
92             head = doHead(url, timeout);
93             int status = head.getStatusCode();
94             head.releaseConnection();
95             if (status == HttpStatus.SC_OK) {
96                 return new URLInfo(true, getResponseContentLength(head), getLastModified(head));
97             }
98             if (status == HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED) {
99                 Message.error("Your proxy requires authentication.");
100             }else if (String.valueOf(status).startsWith("4")) {
101                 Message.verbose("CLIENT ERROR: "+head.getStatusText()+" url="+url);
102             }else if (String.valueOf(status).startsWith("5")) {
103                 Message.warn("SERVER ERROR: "+head.getStatusText()+" url="+url);
104             }
105             Message.debug("HTTP response status: "+status +"="+head.getStatusText()+" url="+url);
106         } catch (HttpException e) {
107             Message.error("HttpClientHandler: "+e.getMessage()+":" + e.getReasonCode()+"="+e.getReason()+" url="+url);
108         } catch (UnknownHostException JavaDoc e) {
109             Message.warn("Host " + e.getMessage() +" not found. url="+url);
110             Message.info("You probably access the destination server through a proxy server that is not well configured.");
111         }catch (IOException JavaDoc e) {
112             Message.error("HttpClientHandler: "+e.getMessage()+" url="+url);
113         } finally{
114             if(head != null) {
115                 head.releaseConnection();
116             }
117         }
118         return UNAVAILABLE;
119     }
120     
121     private long getLastModified(HeadMethod head) {
122         Header header = head.getResponseHeader("last-modified");
123         if (header != null) {
124             String JavaDoc lastModified = header.getValue();
125             try {
126                 return LAST_MODIFIED_FORMAT.parse(lastModified).getTime();
127             } catch (ParseException JavaDoc e) {
128             }
129             return System.currentTimeMillis();
130         } else {
131             return System.currentTimeMillis();
132         }
133     }
134
135     private long getResponseContentLength(HeadMethod head) {
136         return getHttpClientHelper().getResponseContentLength(head);
137     }
138
139     private HttpClientHelper getHttpClientHelper() {
140         if (_httpClientHelper == null) {
141             // use commons httpclient 3.0 if available
142
try {
143                 HttpMethodBase.class.getMethod("getResponseContentLength", new Class JavaDoc[0]);
144                 _httpClientHelper = new HttpClientHelper3x();
145                 Message.verbose("using commons httpclient 3.x helper");
146             } catch (SecurityException JavaDoc e) {
147                 Message.verbose("unable to get access to getResponseContentLength of commons-httpclient HeadMethod. Please use commons-httpclient 3.0 or use ivy with sufficient security permissions.");
148                 Message.verbose("exception: "+e.getMessage());
149                 _httpClientHelper = new HttpClientHelper2x();
150                 Message.verbose("using commons httpclient 2.x helper");
151             } catch (NoSuchMethodException JavaDoc e) {
152                 _httpClientHelper = new HttpClientHelper2x();
153                 Message.verbose("using commons httpclient 2.x helper");
154             }
155         }
156         return _httpClientHelper;
157     }
158     
159     public int getHttpClientMajorVersion() {
160         HttpClientHelper helper = getHttpClientHelper();
161         return helper.getHttpClientMajorVersion();
162     }
163
164     private GetMethod doGet(URL JavaDoc url) throws IOException JavaDoc, HttpException {
165         HttpClient client = getClient(url);
166
167         GetMethod get = new GetMethod(url.toExternalForm());
168         get.setDoAuthentication(useAuthentication(url) || useProxyAuthentication());
169         client.executeMethod(get);
170         return get;
171     }
172
173     private HeadMethod doHead(URL JavaDoc url, int timeout) throws IOException JavaDoc, HttpException {
174         HttpClient client = getClient(url);
175         client.setTimeout(timeout);
176
177         HeadMethod head = new HeadMethod(url.toExternalForm());
178         head.setDoAuthentication(useAuthentication(url) || useProxyAuthentication());
179         client.executeMethod(head);
180         return head;
181     }
182
183     private HttpClient getClient(URL JavaDoc url) {
184         HttpClient client = new HttpClient();
185         
186         List JavaDoc authPrefs = new ArrayList JavaDoc(2);
187         authPrefs.add(AuthPolicy.DIGEST);
188         authPrefs.add(AuthPolicy.BASIC);
189         // Exclude the NTLM authentication scheme because it is not supported by this class
190
client.getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
191
192         if (useProxy()) {
193             client.getHostConfiguration().setProxy(_proxyHost, _proxyPort);
194             if (useProxyAuthentication()) {
195                 client.getState().setProxyCredentials(_proxyRealm, _proxyHost,
196                     new UsernamePasswordCredentials(_proxyUserName, _proxyPasswd));
197             }
198         }
199         Credentials c = getCredentials(url);
200         if (c != null) {
201             Message.debug("found credentials for "+url+": "+c);
202             client.getState().setCredentials(
203                 c.getRealm(),
204                 c.getHost(),
205                 new UsernamePasswordCredentials(c.getUserName(), c.getPasswd())
206             );
207         }
208         return client;
209     }
210
211     private boolean useProxy() {
212         return _proxyHost != null && _proxyHost.trim().length() > 0;
213     }
214     private boolean useAuthentication(URL JavaDoc url) {
215         return getCredentials(url) != null;
216     }
217     
218     private Credentials getCredentials(URL JavaDoc url) {
219         return CredentialsStore.INSTANCE.getCredentials(null, url.getHost());
220     }
221
222     private boolean useProxyAuthentication() {
223         return (_proxyUserName != null && _proxyUserName.trim().length() > 0);
224     }
225     
226     private static final class GETInputStream extends InputStream JavaDoc {
227         private InputStream JavaDoc _is;
228         private GetMethod _get;
229
230         private GETInputStream(GetMethod get) throws IOException JavaDoc {
231             _get = get;
232             _is = get.getResponseBodyAsStream();
233         }
234
235         public int available() throws IOException JavaDoc {
236             return _is.available();
237         }
238
239         public void close() throws IOException JavaDoc {
240             _is.close();
241             _get.releaseConnection();
242         }
243
244         public boolean equals(Object JavaDoc obj) {
245             return _is.equals(obj);
246         }
247
248         public int hashCode() {
249             return _is.hashCode();
250         }
251
252         public void mark(int readlimit) {
253             _is.mark(readlimit);
254         }
255
256         public boolean markSupported() {
257             return _is.markSupported();
258         }
259
260         public int read() throws IOException JavaDoc {
261             return _is.read();
262         }
263
264         public int read(byte[] b, int off, int len) throws IOException JavaDoc {
265             return _is.read(b, off, len);
266         }
267
268         public int read(byte[] b) throws IOException JavaDoc {
269             return _is.read(b);
270         }
271
272         public void reset() throws IOException JavaDoc {
273             _is.reset();
274         }
275
276         public long skip(long n) throws IOException JavaDoc {
277             return _is.skip(n);
278         }
279
280         public String JavaDoc toString() {
281             return _is.toString();
282         }
283     }
284     private static final class HttpClientHelper3x implements HttpClientHelper {
285         private HttpClientHelper3x() {
286         }
287
288         public long getResponseContentLength(HeadMethod head) {
289             return head.getResponseContentLength();
290         }
291
292         /**
293          * {@inheritDoc}
294          */

295         public int getHttpClientMajorVersion() {
296             return 3;
297         }
298     }
299     private static final class HttpClientHelper2x implements HttpClientHelper {
300         private HttpClientHelper2x() {
301         }
302
303         public long getResponseContentLength(HeadMethod head) {
304             Header header = head.getResponseHeader("Content-Length");
305             if (header != null) {
306                 try {
307                     return Integer.parseInt(header.getValue());
308                 } catch (NumberFormatException JavaDoc e) {
309                     Message.verbose("Invalid content-length value: " + e.getMessage());
310                 }
311             }
312             return 0;
313         }
314
315         /**
316          * {@inheritDoc}
317          */

318         public int getHttpClientMajorVersion() {
319             return 2;
320         }
321     }
322     public interface HttpClientHelper {
323         long getResponseContentLength(HeadMethod head);
324         int getHttpClientMajorVersion();
325     }
326 }
327
Popular Tags