KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > quercus > lib > curl > HttpRequest


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Nam Nguyen
28  */

29
30 package com.caucho.quercus.lib.curl;
31
32 import com.caucho.quercus.QuercusModuleException;
33 import com.caucho.quercus.env.BinaryBuilderValue;
34 import com.caucho.quercus.env.BinaryValue;
35 import com.caucho.quercus.env.Env;
36 import com.caucho.quercus.env.StringValue;
37 import com.caucho.util.L10N;
38
39 import java.io.Closeable JavaDoc;
40 import java.io.IOException JavaDoc;
41 import java.io.InputStream JavaDoc;
42 import java.net.ConnectException JavaDoc;
43 import java.net.MalformedURLException JavaDoc;
44 import java.net.ProtocolException JavaDoc;
45 import java.net.SocketTimeoutException JavaDoc;
46 import java.net.URL JavaDoc;
47 import java.net.UnknownHostException JavaDoc;
48 import java.util.HashMap JavaDoc;
49 import java.util.Map JavaDoc;
50 import java.util.logging.Level JavaDoc;
51 import java.util.logging.Logger JavaDoc;
52 import java.util.zip.GZIPInputStream JavaDoc;
53 import java.util.zip.InflaterInputStream JavaDoc;
54
55 /**
56  * Represents a generic Http request.
57  */

58 public class HttpRequest
59   implements Closeable JavaDoc
60 {
61   private static final Logger JavaDoc log
62     = Logger.getLogger(HttpRequest.class.getName());
63   private static final L10N L = new L10N(HttpRequest.class);
64
65   private CurlResource _curl;
66   private HttpConnection _conn;
67
68   public HttpRequest(CurlResource curlResource)
69   {
70     _curl = curlResource;
71   }
72
73   /**
74    * Returns a HttpRequest specific to the Http request method.
75    */

76   public static final HttpRequest getRequest(CurlResource curl)
77   {
78     String JavaDoc requestMethod = curl.getRequestMethod();
79
80     if (requestMethod.equals("GET"))
81       return new HttpGetRequest(curl);
82     else if (requestMethod.equals("POST"))
83       return new HttpPostRequest(curl);
84     else if (requestMethod.equals("PUT"))
85       return new HttpPutRequest(curl);
86     else
87       return new HttpRequest(curl);
88   }
89
90   /**
91    * Opens the connection.
92    */

93   protected final void create(Env env)
94     throws MalformedURLException JavaDoc, IOException JavaDoc
95   {
96     URL JavaDoc url = getURL(env, _curl.getURL(), _curl.getPort());
97
98     if (url == null)
99       return;
100
101     if (_curl.getIsProxying()) {
102       URL JavaDoc proxyURL = getURL(env, _curl.getProxyURL(), _curl.getProxyPort());
103
104       _conn = new HttpConnection(url,
105                                 _curl.getUsername(),
106                                 _curl.getPassword(),
107                                 proxyURL,
108                                 _curl.getProxyUsername(),
109                                 _curl.getProxyPassword(),
110                                 _curl.getProxyType());
111     }
112     else {
113       _conn = new HttpConnection(url,
114                                 _curl.getUsername(),
115                                 _curl.getPassword());
116     }
117   }
118
119
120   /**
121    * Initializes the connection.
122    */

123   protected void init(Env env)
124     throws ProtocolException JavaDoc
125   {
126     _conn.setRequestMethod(_curl.getRequestMethod());
127
128     HashMap JavaDoc<String JavaDoc,String JavaDoc> _properties = _curl.getRequestPropertiesMap();
129
130     for (Map.Entry JavaDoc<String JavaDoc, String JavaDoc> entry: _properties.entrySet()) {
131       _conn.setRequestProperty(entry.getKey(), entry.getValue());
132     }
133
134     _conn.setInstanceFollowRedirects(_curl.getIsFollowingRedirects());
135
136     int timeout = _curl.getConnectTimeout();
137     if (timeout >= 0)
138       _conn.setConnectTimeout(timeout);
139
140     timeout = _curl.getReadTimeout();
141     if (timeout >= 0)
142       _conn.setReadTimeout(timeout);
143   }
144
145   /**
146    * Attempt to connect to the server.
147    */

148   protected void connect(Env env)
149     throws ConnectException JavaDoc, SocketTimeoutException JavaDoc,
150            UnknownHostException JavaDoc, IOException JavaDoc
151   {
152     _conn.connect();
153   }
154
155   /**
156    * Transfer data to the server.
157    */

158   protected void transfer(Env env)
159     throws IOException JavaDoc
160   {
161
162   }
163
164   /**
165    * Closes the connection and sends data and connection info to curl.
166    */

167   protected void finish(Env env)
168     throws IOException JavaDoc
169   {
170     _curl.setResponseCode(_conn.getResponseCode());
171
172     _curl.setHeader(getHeader(new BinaryBuilderValue()));
173     _curl.setBody(getBody(new BinaryBuilderValue()));
174
175     _curl.setContentLength(_conn.getContentLength());
176
177     _curl.setCookie(_conn.getHeaderField("Set-Cookie"));
178
179     _conn.close();
180   }
181
182   /**
183    * Perform this request.
184    */

185   public final void execute(Env env)
186   {
187     try {
188       create(env);
189
190       init(env);
191
192       connect(env);
193
194       transfer(env);
195
196       finish(env);
197     }
198     catch (MalformedURLException JavaDoc e) {
199       error(env, CurlModule.CURLE_URL_MALFORMAT, e.getMessage(), e);
200     }
201     catch (SocketTimeoutException JavaDoc e) {
202       error(env, CurlModule.CURLE_OPERATION_TIMEOUTED, "connection timed out", e);
203     }
204     catch (ConnectException JavaDoc e) {
205       error(env, CurlModule.CURLE_COULDNT_CONNECT, e.getMessage(), e);
206     }
207     catch (ProtocolException JavaDoc e) {
208       throw new QuercusModuleException(e.getMessage());
209       //error(0, e.getMessage(), e);
210
}
211     catch (UnknownHostException JavaDoc e) {
212       error(env, CurlModule.CURLE_COULDNT_RESOLVE_HOST, "unknown host: " + e.getMessage(), e);
213     }
214     catch (IOException JavaDoc e) {
215       error(env, CurlModule.CURLE_RECV_ERROR, e.getMessage(), e);
216     }
217   }
218
219   protected final CurlResource getCurlResource()
220   {
221     return _curl;
222   }
223
224   protected final HttpConnection getHttpConnection()
225   {
226     return _conn;
227   }
228
229   protected final void error(Env env, int code, String JavaDoc error)
230   {
231     log.log(Level.FINE, error);
232
233     if (_curl.getIsVerbose())
234       env.warning(L.l(error));
235
236     _curl.setError(error);
237     _curl.setErrorCode(code);
238   }
239
240   protected final void error(Env env, int code, String JavaDoc error, Throwable JavaDoc e)
241   {
242     log.log(Level.FINE, error, e);
243
244     if (_curl.getIsVerbose())
245       env.warning(L.l(error));
246
247     _curl.setError(error);
248     _curl.setErrorCode(code);
249   }
250
251   /**
252    * Returns a valid URL or null on error.
253    */

254   protected final URL JavaDoc getURL(Env env, String JavaDoc urlString, int port)
255     throws MalformedURLException JavaDoc
256   {
257     URL JavaDoc url;
258
259     if (urlString.indexOf("://") < 0)
260       url = new URL JavaDoc("http://" + urlString);
261     else
262       url = new URL JavaDoc(urlString);
263
264     if (port >= 0)
265       url = new URL JavaDoc(url.getProtocol(), url.getHost(), port, url.getFile());
266
267     return url;
268   }
269
270   /**
271    * Returns the server response header.
272    */

273   private final BinaryValue getHeader(BinaryBuilderValue bb)
274   {
275     // Append server response to the very top
276
bb.appendBytes(_conn.getHeaderField(0));
277     bb.appendBytes("\r\n");
278
279     String JavaDoc key;
280     int i = 1;
281
282     while ((key = _conn.getHeaderFieldKey(i)) != null) {
283       bb.appendBytes(key);
284       bb.appendBytes(": ");
285       bb.appendBytes(_conn.getHeaderField(i));
286       bb.appendBytes("\r\n");
287       i++;
288     }
289
290     bb.appendBytes("\r\n");
291
292     return bb;
293   }
294
295   /**
296    * Returns the server response body.
297    */

298   private final StringValue getBody(BinaryBuilderValue bb)
299     throws SocketTimeoutException JavaDoc, IOException JavaDoc
300   {
301     InputStream JavaDoc in;
302
303     if ((_conn.getResponseCode() < 400))
304       in = _conn.getInputStream();
305     else
306       in = _conn.getErrorStream();
307
308     if (in == null)
309       return StringValue.EMPTY;
310
311     String JavaDoc encoding = _conn.getHeaderField("Content-Encoding");
312
313     if (encoding != null) {
314       if (encoding.equals("gzip"))
315         in = new GZIPInputStream JavaDoc(in);
316       else if (encoding.equals("deflate"))
317         in = new InflaterInputStream JavaDoc(in);
318       else if (encoding.equals("identity")) {
319       }
320       else {
321         _curl.setError(encoding);
322         _curl.setErrorCode(CurlModule.CURLE_BAD_CONTENT_ENCODING);
323         return StringValue.EMPTY;
324       }
325     }
326
327     int len;
328     do {
329       bb.prepareReadBuffer();
330
331       len = in.read(bb.getBuffer(), bb.getOffset(),
332           bb.getLength() - bb.getOffset());
333
334       if (len > 0)
335         bb.setOffset(bb.getOffset() + len);
336     } while (len > 0);
337
338     return bb;
339   }
340
341   /**
342    * Disconnects the connection.
343    */

344   public void close()
345   {
346     if (_conn != null)
347       _conn.close();
348   }
349 }
350
Popular Tags