1 10 11 package org.mule.providers.http; 12 13 import java.io.IOException ; 14 import java.net.Socket ; 15 import java.util.HashMap ; 16 import java.util.Iterator ; 17 import java.util.Map ; 18 19 import javax.resource.spi.work.Work ; 20 21 import org.apache.commons.httpclient.Cookie; 22 import org.apache.commons.httpclient.Header; 23 import org.apache.commons.lang.ObjectUtils; 24 import org.mule.config.i18n.Message; 25 import org.mule.config.i18n.Messages; 26 import org.mule.impl.MuleEvent; 27 import org.mule.impl.MuleMessage; 28 import org.mule.impl.MuleSession; 29 import org.mule.impl.RequestContext; 30 import org.mule.providers.AbstractMessageReceiver; 31 import org.mule.providers.ConnectException; 32 import org.mule.providers.NullPayload; 33 import org.mule.providers.tcp.TcpMessageReceiver; 34 import org.mule.umo.UMOComponent; 35 import org.mule.umo.UMOMessage; 36 import org.mule.umo.endpoint.UMOEndpoint; 37 import org.mule.umo.endpoint.UMOEndpointURI; 38 import org.mule.umo.lifecycle.InitialisationException; 39 import org.mule.umo.provider.UMOConnector; 40 import org.mule.umo.provider.UMOMessageAdapter; 41 import org.mule.util.MapUtils; 42 43 47 public class HttpMessageReceiver extends TcpMessageReceiver 48 { 49 50 public HttpMessageReceiver(UMOConnector connector, UMOComponent component, UMOEndpoint endpoint) 51 throws InitialisationException 52 { 53 super(connector, component, endpoint); 54 } 55 56 protected Work createWork(Socket socket) throws IOException 57 { 58 return new HttpWorker(socket); 59 } 60 61 public void doConnect() throws ConnectException 62 { 63 if (shouldConnect()) 66 { 67 super.doConnect(); 68 } 69 } 70 71 protected boolean shouldConnect() 72 { 73 StringBuffer requestUri = new StringBuffer (80); 74 requestUri.append(endpoint.getProtocol()).append("://"); 75 requestUri.append(endpoint.getEndpointURI().getHost()); 76 requestUri.append(":").append(endpoint.getEndpointURI().getPort()); 77 requestUri.append("*"); 78 AbstractMessageReceiver[] temp = connector.getReceivers(requestUri.toString()); 79 for (int i = 0; i < temp.length; i++) 80 { 81 AbstractMessageReceiver abstractMessageReceiver = temp[i]; 82 if (abstractMessageReceiver.isConnected()) 83 { 84 return false; 85 } 86 } 87 return true; 88 } 89 90 private class HttpWorker implements Work 91 { 92 93 private HttpServerConnection conn = null; 94 private String cookieSpec; 95 private boolean enableCookies = false; 96 97 public HttpWorker(Socket socket) throws IOException 98 { 99 if (endpoint.getEncoding() != null) 100 { 101 conn = new HttpServerConnection(socket, endpoint.getEncoding()); 102 } 103 else 104 { 105 conn = new HttpServerConnection(socket); 106 } 107 108 cookieSpec = MapUtils.getString(endpoint.getProperties(), 109 HttpConnector.HTTP_COOKIE_SPEC_PROPERTY, ((HttpConnector)connector).getCookieSpec()); 110 111 enableCookies = MapUtils.getBooleanValue(endpoint.getProperties(), 112 HttpConnector.HTTP_ENABLE_COOKIES_PROPERTY, ((HttpConnector)connector).isEnableCookies()); 113 } 114 115 public void run() 116 { 117 try 118 { 119 do 120 { 121 conn.setKeepAlive(false); 122 HttpRequest request = conn.readRequest(); 123 if (request == null) 124 { 125 break; 126 } 127 128 Map headers = new HashMap (); 129 for (Iterator rhi = request.getHeaderIterator(); rhi.hasNext();) 130 { 131 Header header = (Header)rhi.next(); 132 String headerName = header.getName(); 133 Object headerValue = header.getValue(); 134 135 if (headerName.startsWith("X-MULE")) 137 { 138 headerName = headerName.substring(2); 139 } 140 else if (headerName.equals(HttpConnector.HTTP_COOKIES_PROPERTY)) 142 { 143 if (enableCookies) 144 { 145 Cookie[] cookies = CookieHelper.parseCookies(header, cookieSpec); 146 if (cookies.length > 0) 147 { 148 headerValue = cookies; 150 } 151 else 152 { 153 continue; 155 } 156 } 157 else 158 { 159 continue; 161 } 162 } 163 164 headers.put(headerName, headerValue); 166 } 167 168 RequestLine reqLine = request.getRequestLine(); 169 headers.put(HttpConnector.HTTP_METHOD_PROPERTY, reqLine.getMethod()); 170 headers.put(HttpConnector.HTTP_REQUEST_PROPERTY, reqLine.getUri()); 171 headers.put(HttpConnector.HTTP_VERSION_PROPERTY, reqLine.getHttpVersion().toString()); 172 headers.put(HttpConnector.HTTP_COOKIE_SPEC_PROPERTY, cookieSpec); 173 174 UMOMessageAdapter adapter; 176 Object body; 177 if (endpoint.isStreaming() && request.getBody() != null) 178 { 179 adapter = connector.getStreamMessageAdapter(request.getBody(), conn.getOutputStream()); 180 for (Iterator iterator = headers.entrySet().iterator(); iterator.hasNext();) 181 { 182 Map.Entry entry = (Map.Entry )iterator.next(); 183 adapter.setProperty((String )entry.getKey(), entry.getValue()); 184 } 185 } 186 else 187 { 188 if (headers.get(HttpConnector.HTTP_VERSION_PROPERTY).equals(HttpConstants.HTTP11)) 193 { 194 String expectHeaderValue = ObjectUtils.toString( 197 headers.get(HttpConstants.HEADER_EXPECT)).toLowerCase(); 198 if (HttpConstants.HEADER_EXPECT_CONTINUE_REQUEST_VALUE.equals(expectHeaderValue)) 199 { 200 HttpResponse expected = new HttpResponse(); 201 expected.setStatusLine(reqLine.getHttpVersion(), HttpConstants.SC_CONTINUE); 202 final MuleEvent event = new MuleEvent(new MuleMessage(expected), endpoint, 203 new MuleSession(component), true); 204 RequestContext.setEvent(event); 205 expected = (HttpResponse)connector.getDefaultResponseTransformer().transform( 206 expected); 207 conn.writeResponse(expected); 208 } 209 } 210 211 body = request.getBodyBytes(); 212 if (body == null) 213 { 214 body = reqLine.getUri(); 215 } 216 adapter = connector.getMessageAdapter(new Object []{body, headers}); 217 } 218 219 UMOMessage message = new MuleMessage(adapter); 220 221 if (logger.isDebugEnabled()) 222 { 223 logger.debug(message.getProperty(HttpConnector.HTTP_REQUEST_PROPERTY)); 224 } 225 226 AbstractMessageReceiver receiver = getTargetReceiver(message, endpoint); 229 230 HttpResponse response; 233 if (receiver != null) 234 { 235 UMOMessage returnMessage = receiver.routeMessage(message, endpoint.isSynchronous(), 239 null); 240 Object tempResponse; 241 if (returnMessage != null) 242 { 243 tempResponse = returnMessage.getPayload(); 244 } 245 else 246 { 247 tempResponse = new NullPayload(); 248 } 249 if (tempResponse instanceof HttpResponse) 253 { 254 response = (HttpResponse)tempResponse; 255 } 256 else 257 { 258 response = (HttpResponse)connector.getDefaultResponseTransformer().transform( 259 tempResponse); 260 } 261 response.disableKeepAlive(!((HttpConnector)connector).isKeepAlive()); 262 } 263 else 264 { 265 UMOEndpointURI uri = endpoint.getEndpointURI(); 266 String failedPath = uri.getScheme() + "://" + uri.getHost() + ":" + uri.getPort() 267 + getRequestPath(message); 268 269 if (logger.isDebugEnabled()) 270 { 271 logger.debug("Failed to bind to " + failedPath); 272 } 273 274 response = new HttpResponse(); 275 response.setStatusLine(reqLine.getHttpVersion(), HttpConstants.SC_NOT_FOUND); 276 response.setBodyString(new Message(Messages.CANNOT_BIND_TO_ADDRESS_X, failedPath).toString()); 277 RequestContext.setEvent(new MuleEvent(new MuleMessage(response), endpoint, 278 new MuleSession(component), true)); 279 response = (HttpResponse)connector.getDefaultResponseTransformer() 282 .transform(response); 283 } 284 285 conn.writeResponse(response); 286 } 287 while (conn.isKeepAlive()); 288 } 289 catch (Exception e) 290 { 291 handleException(e); 292 } 293 finally 294 { 295 conn.close(); 296 conn = null; 297 } 298 } 299 300 public void release() 301 { 302 conn.close(); 303 conn = null; 304 } 305 } 306 307 protected String getRequestPath(UMOMessage message) 308 { 309 String path = (String )message.getProperty(HttpConnector.HTTP_REQUEST_PROPERTY); 310 int i = path.indexOf("?"); 311 if (i > -1) 312 { 313 path = path.substring(0, i); 314 } 315 return path; 316 } 317 318 protected AbstractMessageReceiver getTargetReceiver(UMOMessage message, UMOEndpoint endpoint) 319 throws ConnectException 320 { 321 String path = (String )message.getProperty(HttpConnector.HTTP_REQUEST_PROPERTY); 322 int i = path.indexOf("?"); 323 if (i > -1) 324 { 325 path = path.substring(0, i); 326 } 327 328 StringBuffer requestUri = new StringBuffer (); 329 requestUri.append(endpoint.getProtocol()).append("://"); 330 requestUri.append(endpoint.getEndpointURI().getHost()); 331 requestUri.append(":").append(endpoint.getEndpointURI().getPort()); 332 333 if (logger.isTraceEnabled()) 335 { 336 logger.trace("Looking up receiver on connector: " + connector.getName() + " with URI key: " 337 + requestUri.toString()); 338 } 339 340 AbstractMessageReceiver receiver = connector.getReceiver(requestUri.toString()); 341 342 if (receiver == null && !"/".equals(path)) 345 { 346 int x = path.lastIndexOf("/"); 348 if (x > 1 && path.indexOf(".") > x) 349 { 350 requestUri.append(path.substring(0, x)); 351 } 352 else 353 { 354 requestUri.append(path); 355 } 356 357 if (logger.isTraceEnabled()) 358 { 359 logger.trace("Secondary lookup of receiver on connector: " + connector.getName() 360 + " with URI key: " + requestUri.toString()); 361 } 362 363 receiver = connector.getReceiver(requestUri.toString()); 365 if (receiver == null && logger.isWarnEnabled()) 366 { 367 logger.warn("No receiver found with secondary lookup on connector: " + connector.getName() 368 + " with URI key: " + requestUri.toString()); 369 logger.warn("Receivers on connector are: " 370 + MapUtils.toString(connector.getReceivers(), true)); 371 } 372 } 373 374 return receiver; 375 } 376 377 } 378 | Popular Tags |