Source code: org/mule/providers/http/HttpConnector.java
1 /*
2 * $Header: /cvsroot/mule/mule/src/java/org/mule/providers/http/HttpConnector.java,v 1.7 2003/10/20 21:44:38 rossmason Exp $
3 * $Revision: 1.7 $
4 * $Date: 2003/10/20 21:44:38 $
5 * ------------------------------------------------------------------------------------------------------
6 *
7 * Copyright (c) Cubis Limited. All rights reserved.
8 * http://www.cubis.co.uk
9 *
10 * The software in this package is published under the terms of the BSD
11 * style license a copy of which has been included with this distribution in
12 * the LICENSE.txt file.
13 *
14 */
15
16 package org.mule.providers.http;
17
18 import java.net.URI;
19 import java.util.HashMap;
20 import java.util.Map;
21
22 import org.apache.commons.httpclient.ConnectMethod;
23 import org.apache.commons.httpclient.HttpConnection;
24 import org.apache.commons.httpclient.HttpMethod;
25 import org.apache.commons.httpclient.HttpState;
26 import org.apache.commons.httpclient.HttpStatus;
27 import org.apache.commons.httpclient.UsernamePasswordCredentials;
28 import org.apache.commons.httpclient.methods.GetMethod;
29 import org.apache.commons.httpclient.protocol.Protocol;
30 import org.mule.MuleException;
31 import org.mule.providers.AbstractConnector;
32 import org.mule.umo.UMOEvent;
33 import org.mule.umo.UMOProviderDescriptor;
34 import org.mule.umo.UMOSession;
35 import org.mule.umo.impl.MuleEvent;
36 import org.mule.umo.provider.UMOMessageAdapter;
37 import org.mule.util.Utility;
38
39 /**
40 * <p><code>HttpConnector</code> provides a way of receiving and sending http
41 * requests and responses. The UMOConnector itself handles dispatching http requests.
42 * The <code>HttpReceiver</code> handles the receiving requests and processing of headers
43 * </p>
44 * <p> This connector recognises the following properties -
45 * <ul>
46 * <li>transport.http.hostname - The hostname to send and receive http requests</li>
47 * <li>transport.http.port - The port to listen on. The industry standard is 80 and if this propert is not set it will default to 80</li>
48 * <li>transport.http.proxyHostname - If you access the web through a proxy, this holds the server address</li>
49 * <li>transport.http.proxyPort - The port the proxy is configured on</li>
50 * <li>transport.http.proxyUsername - If the proxy requires authentication supply a username</li>
51 * <li>transport.http.proxyPassword - If the proxy requires authentication supply a password</li>
52 * </ul>
53 * </p>
54 * @author <a href="mailto:ross.mason@cubis.co.uk">Ross Mason</a>
55 * @version $Revision: 1.7 $
56 */
57 public class HttpConnector extends AbstractConnector
58 {
59 // HTTP status codes
60 public static String STATUS_OK = "200 Mule: Message Processed Successfully";
61 public static String STATUS_UNAUTH = "401 Mule: the requested was unauthorised";
62 public static String STATUS_SENDER = "400";
63 public static String STATUS_ISE = "500 Mule: Iternal Server Error";
64
65 // HTTP prefix
66 public static String HTTP = "HTTP/1.0 ";
67 public static String HTTP11 = "HTTP/1.1 ";
68
69 public static final String HEADER_PROTOCOL_10 = "HTTP/1.0";
70 public static final String HEADER_PROTOCOL_11 = "HTTP/1.1";
71 public static final String HEADER_PROTOCOL_V10 = "1.0".intern();
72 public static final String HEADER_PROTOCOL_V11 = "1.1".intern();
73 public static final String HEADER_POST = "POST";
74 public static final String HEADER_HOST = "Host";
75 public static final String HEADER_CONTENT_DESCRIPTION = "Content-Description";
76 public static final String HEADER_CONTENT_TYPE = "Content-Type";
77 public static final String HEADER_CONTENT_TRANSFER_ENCODING = "Content-Transfer-Encoding";
78 public static final String HEADER_CONTENT_LENGTH = "Content-Length";
79 public static final String HEADER_CONTENT_LOCATION = "Content-Location";
80 public static final String HEADER_CONTENT_ID = "Content-Id";
81
82 public static String CRLF = "\r\n";
83 //Mime/Content separator
84 public static String HEADER_CONTENT_SEPARATOR = CRLF + CRLF;
85
86 // public static final String HEADER_AUTHORIZATION = "Authorization";
87 // public static final String HEADER_PROXY_AUTHORIZATION = "Proxy-Authorization";
88 // public static final String HEADER_EXPECT = "Expect";
89 // public static final String HEADER_EXPECT_100_Continue = "100-continue";
90 // public static final String HEADER_USER_AGENT = "User-Agent";
91 // public static final String HEADER_CACHE_CONTROL = "Cache-Control";
92 // public static final String HEADER_CACHE_CONTROL_NOCACHE = "no-cache";
93 // public static final String HEADER_PRAGMA = "Pragma";
94
95 //Used if the enpoint passed is a relative path
96 public static final String HOSTNAME_PROPERTY = "transport.http.hostname";
97 public static final String PORT_PROPERTY = "transport.http.port";
98
99 //Proxy settings
100 public static final String PROXY_HOSTNAME_PROPERTY = "transport.http.proxyHostname";
101 public static final String PROXY_PORT_PROPERTY = "transport.http.proxyPort";
102 public static final String PROXY_USERNAME_PROPERTY = "transport.http.proxyUsername";
103 public static final String PROXY_PASSWORD_PROPERTY = "transport.http.proxyPassword";
104
105 /** Event property to pass back the status for the response */
106 public static final String STATUS_PROPERTY = "transport.http.status";
107
108 public static final int DEFAULT_PORT = 80;
109
110 private String hostname = null;
111 private int port = DEFAULT_PORT;
112 private String proxyHostname = null;
113 private int proxyPort = DEFAULT_PORT;
114 private String proxyUsername = null;
115 private String proxyPassword = null;
116 private String defaultEndpoint = null;
117
118 private HttpState state = null;
119
120 private Map listeners = new HashMap();
121
122 /**
123 * Creates and initialises a new connector instance
124 */
125 public void create() throws Exception
126 {
127 setHostname((String) properties.get(HOSTNAME_PROPERTY));
128 setPort(Utility.getIntProperty(properties, PORT_PROPERTY, DEFAULT_PORT));
129
130 setProxyHostname((String) properties.get(PROXY_HOSTNAME_PROPERTY));
131 setProxyPort(Utility.getIntProperty(properties, PROXY_PORT_PROPERTY, DEFAULT_PORT));
132 setProxyUsername((String) properties.get(PROXY_USERNAME_PROPERTY));
133 setProxyPassword((String) properties.get(PROXY_PASSWORD_PROPERTY));
134
135 HttpState state = new HttpState();
136 if (getProxyUsername() != null)
137 {
138 state.setProxyCredentials(null, new UsernamePasswordCredentials(getProxyUsername(), getProxyPassword()));
139 }
140
141 }
142
143 /* (non-Javadoc)
144 * @see org.mule.umo.provider.UMOConnector#getProtocol()
145 */
146 public String getProtocol()
147 {
148 return "http";
149 }
150
151 /* (non-Javadoc)
152 * @see org.mule.providers.AbstractConnector#startConnector()
153 */
154 protected void startConnector() throws Exception
155 {
156 // noop
157
158 }
159
160 /* (non-Javadoc)
161 * @see org.mule.providers.AbstractConnector#stopConnector()
162 */
163 protected void stopConnector() throws Exception
164 {
165 // noop
166
167 }
168
169 /* (non-Javadoc)
170 * @see org.mule.umo.provider.UMOConnector#dispatch(org.mule.umo.UMOEvent)
171 */
172 public void dispatch(UMOEvent event) throws Exception
173 {
174 send(event);
175 }
176
177 /* (non-Javadoc)
178 * @see org.mule.umo.provider.UMOConnector#getMessageAdapter(java.lang.Object)
179 */
180 public UMOMessageAdapter getMessageAdapter(Object message) throws Exception
181 {
182 return new HttpMessageAdapter(message);
183 }
184
185 /* (non-Javadoc)
186 * @see org.mule.umo.provider.UMOConnector#registerListener(org.mule.umo.UMOSession, org.mule.umo.UMOProviderDescriptor)
187 */
188 public void registerListener(UMOSession session, UMOProviderDescriptor provider) throws Exception
189 {
190 String endpoint = provider.getEndpoint();
191 if (endpoint == null || "".equals(endpoint))
192 {
193 throw new MuleException("Endpoint can not be null when registering a listener");
194 }
195 if (listeners.get(endpoint) != null)
196 {
197 throw new MuleException("There is already a listener on port: " + endpoint);
198 }
199 int port;
200 try
201 {
202 port = Integer.parseInt(endpoint);
203 }
204 catch (NumberFormatException e)
205 {
206 throw new MuleException("The port: " + endpoint + " is not valid");
207 }
208
209 HttpReceiver receiver =
210 new HttpReceiver(session, provider, session.getDescriptor().getExceptionStrategy(), port);
211
212 listeners.put(receiver, endpoint);
213 log.debug("Added listener for: " + endpoint);
214 }
215
216 /* (non-Javadoc)
217 * @see org.mule.umo.provider.UMOConnector#removeListener(org.mule.umo.UMOSession, org.mule.umo.UMOProviderDescriptor)
218 */
219 public void removeListener(UMOSession session, UMOProviderDescriptor provider) throws Exception
220 {
221 log.debug("Removing listener for: " + provider.getEndpoint());
222 listeners.remove(provider.getEndpoint());
223 }
224
225 /* (non-Javadoc)
226 * @see org.mule.umo.provider.UMOConnector#send(org.mule.umo.UMOEvent)
227 */
228 public UMOEvent send(UMOEvent event) throws Exception
229 {
230 String endpoint = event.getProvider().getEndpoint();
231 if (endpoint == null || defaultEndpoint == null)
232 {
233 throw new MuleException("There is no endpoint spsecifed for this event");
234 }
235 URI uri = new URI(endpoint);
236
237 HttpConnection connection = null; //(HttpConnection)connections.get(uri);
238 //if(connection==null)
239 //{
240 String schema = uri.getScheme();
241 if ((schema == null) || (schema.equals("")))
242 {
243 schema = getProtocol();
244 //If the protocol is not set on the endpoint
245 //check if the hostname for the connector is set
246 //if so assume the theendpoint is a relative path
247 //and prepend the host
248 if (getHostname() != null)
249 {
250 String url =
251 schema
252 + "://"
253 + getHostname()
254 + ":"
255 + getPort()
256 + (endpoint.startsWith("/") ? endpoint : "/" + endpoint);
257 uri = new URI(url);
258 }
259 }
260 Protocol protocol = Protocol.getProtocol(schema);
261
262 String host = uri.getHost();
263 int port = uri.getPort();
264 connection = new HttpConnection(host, port, protocol);
265
266 connection.setProxyHost(getProxyHostname());
267 connection.setProxyPort(getProxyPort());
268 //connections.put(uri, connection);
269
270 //}
271
272 HttpMethod method = new GetMethod(uri.toString());
273
274 try
275 {
276 if (connection.isProxied() && connection.isSecure())
277 {
278 method = new ConnectMethod(method);
279 }
280 method.execute(state, connection);
281
282 if (method.getStatusCode() == HttpStatus.SC_OK)
283 {
284 MuleEvent retEvent = new MuleEvent(method.getResponseBodyAsString(), event.getProvider(), null);
285
286 return retEvent;
287 }
288 else
289 {
290 throw new MuleException("HTTP request failed with return code: " + method.getStatusLine().toString());
291 }
292 }
293 catch (MuleException e)
294 {
295 throw e;
296 }
297 catch (Exception e)
298 {
299 throw new MuleException("HTTP connector failed to make request: " + e, e);
300 }
301 finally
302 {
303 method.releaseConnection();
304 }
305 }
306
307 /**
308 * @return
309 */
310 public String getHostname()
311 {
312 return hostname;
313 }
314
315 /**
316 * @return
317 */
318 public int getPort()
319 {
320 return port;
321 }
322
323 /**
324 * @return
325 */
326 public String getProxyHostname()
327 {
328 return proxyHostname;
329 }
330
331 /**
332 * @return
333 */
334 public String getProxyPassword()
335 {
336 return proxyPassword;
337 }
338
339 /**
340 * @return
341 */
342 public int getProxyPort()
343 {
344 return proxyPort;
345 }
346
347 /**
348 * @return
349 */
350 public String getProxyUsername()
351 {
352 return proxyUsername;
353 }
354
355 /**
356 * @param string
357 */
358 public void setHostname(String host)
359 {
360 hostname = host;
361 }
362
363 /**
364 * @param string
365 */
366 public void setPort(int port)
367 {
368 this.port = port;
369 }
370
371 /**
372 * @param string
373 */
374 public void setProxyHostname(String host)
375 {
376 proxyHostname = host;
377 }
378
379 /**
380 * @param string
381 */
382 public void setProxyPassword(String string)
383 {
384 proxyPassword = string;
385 }
386
387 /**
388 * @param string
389 */
390 public void setProxyPort(int port)
391 {
392 proxyPort = port;
393 }
394
395 /**
396 * @param string
397 */
398 public void setProxyUsername(String string)
399 {
400 proxyUsername = string;
401 }
402
403 /* (non-Javadoc)
404 * @see org.mule.providers.AbstractConnector#destroyConnector()
405 */
406 protected void shutdownConnector() throws Exception
407 {
408 stopConnector();
409
410 }
411
412 }