1
2
3
4
5
6
7
8
9
10
11 package org.mule.transport.http;
12
13 import org.mule.api.MuleContext;
14 import org.mule.api.MuleEvent;
15 import org.mule.api.MuleMessage;
16 import org.mule.api.construct.FlowConstruct;
17 import org.mule.api.endpoint.ImmutableEndpoint;
18 import org.mule.api.endpoint.InboundEndpoint;
19 import org.mule.api.lifecycle.InitialisationException;
20 import org.mule.api.processor.MessageProcessor;
21 import org.mule.config.i18n.CoreMessages;
22 import org.mule.transport.tcp.TcpConnector;
23
24 import java.io.UnsupportedEncodingException;
25 import java.util.HashMap;
26 import java.util.HashSet;
27 import java.util.Iterator;
28 import java.util.Map;
29 import java.util.Set;
30
31 import org.apache.commons.codec.binary.Base64;
32 import org.apache.commons.httpclient.HttpClient;
33 import org.apache.commons.httpclient.HttpConnectionManager;
34 import org.apache.commons.httpclient.HttpMethod;
35 import org.apache.commons.httpclient.HttpState;
36 import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
37 import org.apache.commons.httpclient.UsernamePasswordCredentials;
38 import org.apache.commons.httpclient.auth.AuthScope;
39 import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59 public class HttpConnector extends TcpConnector
60 {
61
62 public static final String HTTP = "http";
63 public static final String HTTP_PREFIX = "http.";
64
65
66
67
68 public static final String HTTP_STATUS_PROPERTY = HTTP_PREFIX + "status";
69 public static final String HTTP_VERSION_PROPERTY = HTTP_PREFIX + "version";
70
71
72
73
74 @Deprecated
75 public static final String HTTP_CUSTOM_HEADERS_MAP_PROPERTY = HTTP_PREFIX + "custom.headers";
76
77 public static final String HTTP_METHOD_PROPERTY = HTTP_PREFIX + "method";
78
79
80
81
82 public static final String HTTP_REQUEST_PROPERTY = HTTP_PREFIX + "request";
83
84
85
86
87 public static final String HTTP_REQUEST_PATH_PROPERTY = HTTP_PREFIX + "request.path";
88
89
90
91
92
93 public static final String HTTP_CONTEXT_PATH_PROPERTY = HTTP_PREFIX + "context.path";
94
95
96
97
98
99 public static final String HTTP_PARAMS_PROPERTY = HTTP_PREFIX + "params";
100 public static final String HTTP_GET_BODY_PARAM_PROPERTY = HTTP_PREFIX + "get.body.param";
101 public static final String DEFAULT_HTTP_GET_BODY_PARAM_PROPERTY = "body";
102 public static final String HTTP_POST_BODY_PARAM_PROPERTY = HTTP_PREFIX + "post.body.param";
103
104 public static final String HTTP_DISABLE_STATUS_CODE_EXCEPTION_CHECK = HTTP_PREFIX + "disable.status.code.exception.check";
105 public static final String HTTP_ENCODE_PARAMVALUE = HTTP_PREFIX + "encode.paramvalue";
106
107 public static final Set<String> HTTP_INBOUND_PROPERTIES;
108
109 static
110 {
111 Set<String> props = new HashSet<String>();
112 props.add(HTTP_CONTEXT_PATH_PROPERTY);
113 props.add(HTTP_GET_BODY_PARAM_PROPERTY);
114 props.add(HTTP_METHOD_PROPERTY);
115 props.add(HTTP_PARAMS_PROPERTY);
116 props.add(HTTP_POST_BODY_PARAM_PROPERTY);
117 props.add(HTTP_REQUEST_PROPERTY);
118 props.add(HTTP_REQUEST_PATH_PROPERTY);
119 props.add(HTTP_STATUS_PROPERTY);
120 props.add(HTTP_VERSION_PROPERTY);
121 props.add(HTTP_ENCODE_PARAMVALUE);
122 HTTP_INBOUND_PROPERTIES = props;
123 }
124
125 public static final String HTTP_COOKIE_SPEC_PROPERTY = "cookieSpec";
126 public static final String HTTP_COOKIES_PROPERTY = "cookies";
127 public static final String HTTP_ENABLE_COOKIES_PROPERTY = "enableCookies";
128
129 public static final String COOKIE_SPEC_NETSCAPE = "netscape";
130 public static final String COOKIE_SPEC_RFC2109 = "rcf2109";
131
132 private String proxyHostname = null;
133
134 private int proxyPort = HttpConstants.DEFAULT_HTTP_PORT;
135
136 private String proxyUsername = null;
137
138 private String proxyPassword = null;
139
140 private String cookieSpec;
141
142 private boolean enableCookies = false;
143
144 protected HttpConnectionManager clientConnectionManager;
145
146 public HttpConnector(MuleContext context)
147 {
148 super(context);
149 }
150
151 @Override
152 protected void doInitialise() throws InitialisationException
153 {
154 super.doInitialise();
155 if (clientConnectionManager == null)
156 {
157 clientConnectionManager = new MultiThreadedHttpConnectionManager();
158 HttpConnectionManagerParams params = new HttpConnectionManagerParams();
159 if (getSendBufferSize() != INT_VALUE_NOT_SET)
160 {
161 params.setSendBufferSize(getSendBufferSize());
162 }
163 if (getReceiveBufferSize() != INT_VALUE_NOT_SET)
164 {
165 params.setReceiveBufferSize(getReceiveBufferSize());
166 }
167 if (getClientSoTimeout() != INT_VALUE_NOT_SET)
168 {
169 params.setSoTimeout(getClientSoTimeout());
170 }
171 if (getSocketSoLinger() != INT_VALUE_NOT_SET)
172 {
173 params.setLinger(getSocketSoLinger());
174 }
175
176 params.setTcpNoDelay(isSendTcpNoDelay());
177 params.setMaxTotalConnections(dispatchers.getMaxTotal());
178 params.setDefaultMaxConnectionsPerHost(dispatchers.getMaxTotal());
179 clientConnectionManager.setParams(params);
180 }
181 }
182
183 @Override
184 public void registerListener(InboundEndpoint endpoint, MessageProcessor listener, FlowConstruct flowConstruct) throws Exception
185 {
186 if (endpoint != null)
187 {
188 Map endpointProperties = endpoint.getProperties();
189 if (endpointProperties != null)
190 {
191
192 Map newProperties = new HashMap(endpointProperties.size());
193 for (Iterator entries = endpointProperties.entrySet().iterator(); entries.hasNext();)
194 {
195 Map.Entry entry = (Map.Entry) entries.next();
196 Object key = entry.getKey();
197 Object normalizedKey = HttpConstants.ALL_HEADER_NAMES.get(key);
198 if (normalizedKey != null)
199 {
200
201 key = normalizedKey;
202 }
203 newProperties.put(key, entry.getValue());
204 }
205
206 endpoint.getProperties().clear();
207 endpoint.getProperties().putAll(newProperties);
208 }
209 }
210
211 super.registerListener(endpoint, listener, flowConstruct);
212 }
213
214
215
216
217
218
219
220 @Override
221 protected Object getReceiverKey(FlowConstruct flowConstruct, InboundEndpoint endpoint)
222 {
223 String key = endpoint.getEndpointURI().toString();
224 int i = key.indexOf('?');
225 if (i > -1)
226 {
227 key = key.substring(0, i);
228 }
229 return key;
230 }
231
232
233
234
235 @Override
236 public String getProtocol()
237 {
238 return HTTP;
239 }
240
241 public String getProxyHostname()
242 {
243 return proxyHostname;
244 }
245
246 public String getProxyPassword()
247 {
248 return proxyPassword;
249 }
250
251 public int getProxyPort()
252 {
253 return proxyPort;
254 }
255
256 public String getProxyUsername()
257 {
258 return proxyUsername;
259 }
260
261 public void setProxyHostname(String host)
262 {
263 proxyHostname = host;
264 }
265
266 public void setProxyPassword(String string)
267 {
268 proxyPassword = string;
269 }
270
271 public void setProxyPort(int port)
272 {
273 proxyPort = port;
274 }
275
276 public void setProxyUsername(String string)
277 {
278 proxyUsername = string;
279 }
280
281 @Override
282 public Map getReceivers()
283 {
284 return this.receivers;
285 }
286
287 public String getCookieSpec()
288 {
289 return cookieSpec;
290 }
291
292 public void setCookieSpec(String cookieSpec)
293 {
294 if (!(COOKIE_SPEC_NETSCAPE.equalsIgnoreCase(cookieSpec) || COOKIE_SPEC_RFC2109.equalsIgnoreCase(cookieSpec)))
295 {
296 throw new IllegalArgumentException(
297 CoreMessages.propertyHasInvalidValue("cookieSpec", cookieSpec).toString());
298 }
299 this.cookieSpec = cookieSpec;
300 }
301
302 public boolean isEnableCookies()
303 {
304 return enableCookies;
305 }
306
307 public void setEnableCookies(boolean enableCookies)
308 {
309 this.enableCookies = enableCookies;
310 }
311
312
313 public HttpConnectionManager getClientConnectionManager()
314 {
315 return clientConnectionManager;
316 }
317
318 public void setClientConnectionManager(HttpConnectionManager clientConnectionManager)
319 {
320 this.clientConnectionManager = clientConnectionManager;
321 }
322
323 protected HttpClient doClientConnect() throws Exception
324 {
325 HttpState state = new HttpState();
326
327 if (getProxyUsername() != null)
328 {
329 state.setProxyCredentials(
330 new AuthScope(null, -1, null, null),
331 new UsernamePasswordCredentials(getProxyUsername(), getProxyPassword()));
332 }
333
334 HttpClient client = new HttpClient();
335 client.setState(state);
336 client.setHttpConnectionManager(getClientConnectionManager());
337
338 return client;
339 }
340
341 protected void setupClientAuthorization(MuleEvent event, HttpMethod httpMethod,
342 HttpClient client, ImmutableEndpoint endpoint)
343 throws UnsupportedEncodingException
344 {
345 httpMethod.setDoAuthentication(true);
346 client.getParams().setAuthenticationPreemptive(true);
347
348 if (event != null && event.getCredentials() != null)
349 {
350 MuleMessage msg = event.getMessage();
351 String authScopeHost = msg.getOutboundProperty(HTTP_PREFIX + "auth.scope.host", event.getEndpoint().getEndpointURI().getHost());
352 int authScopePort = msg.getOutboundProperty(HTTP_PREFIX + "auth.scope.port", event.getEndpoint().getEndpointURI().getPort());
353 String authScopeRealm = msg.getOutboundProperty(HTTP_PREFIX + "auth.scope.realm", AuthScope.ANY_REALM);
354 String authScopeScheme = msg.getOutboundProperty(HTTP_PREFIX + "auth.scope.scheme", AuthScope.ANY_SCHEME);
355 client.getState().setCredentials(
356 new AuthScope(authScopeHost, authScopePort, authScopeRealm, authScopeScheme),
357 new UsernamePasswordCredentials(event.getCredentials().getUsername(), new String(
358 event.getCredentials().getPassword())));
359 }
360 else if (endpoint.getEndpointURI().getUserInfo() != null
361 && endpoint.getProperty(HttpConstants.HEADER_AUTHORIZATION) == null)
362 {
363
364 StringBuffer header = new StringBuffer(128);
365 header.append("Basic ");
366 header.append(new String(Base64.encodeBase64(endpoint.getEndpointURI().getUserInfo().getBytes(
367 endpoint.getEncoding()))));
368 httpMethod.addRequestHeader(HttpConstants.HEADER_AUTHORIZATION, header.toString());
369 }
370
371 else if (event!=null && event.getMessage().getOutboundProperty(HttpConstants.HEADER_AUTHORIZATION) != null &&
372 httpMethod.getRequestHeader(HttpConstants.HEADER_AUTHORIZATION)==null)
373 {
374 String auth = event.getMessage().getOutboundProperty(HttpConstants.HEADER_AUTHORIZATION);
375 httpMethod.addRequestHeader(HttpConstants.HEADER_AUTHORIZATION, auth);
376 }
377 else
378 {
379
380 client.getParams().setAuthenticationPreemptive(false);
381 }
382 }
383
384
385
386
387 public static String normalizeUrl(String url)
388 {
389 if (url == null)
390 {
391 url = "/";
392 }
393 else if (!url.startsWith("/"))
394 {
395 url = "/" + url;
396 }
397 return url;
398 }
399 }