Coverage Report - org.mule.transport.http.HttpConnector
 
Classes in this File Line Coverage Branch Coverage Complexity
HttpConnector
82%
76/93
59%
20/34
1.714
 
 1  
 /*
 2  
  * $Id: HttpConnector.java 10961 2008-02-22 19:01:02Z dfeist $
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
 5  
  *
 6  
  * The software in this package is published under the terms of the CPAL v1.0
 7  
  * license, a copy of which has been included with this distribution in the
 8  
  * LICENSE.txt file.
 9  
  */
 10  
 
 11  
 package org.mule.transport.http;
 12  
 
 13  
 import org.mule.api.MuleEvent;
 14  
 import org.mule.api.MuleMessage;
 15  
 import org.mule.api.endpoint.ImmutableEndpoint;
 16  
 import org.mule.api.endpoint.InboundEndpoint;
 17  
 import org.mule.api.lifecycle.InitialisationException;
 18  
 import org.mule.api.service.Service;
 19  
 import org.mule.api.transport.Connector;
 20  
 import org.mule.api.transport.MessageReceiver;
 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.Iterator;
 27  
 import java.util.Map;
 28  
 
 29  
 import org.apache.commons.codec.binary.Base64;
 30  
 import org.apache.commons.httpclient.HttpClient;
 31  
 import org.apache.commons.httpclient.HttpConnectionManager;
 32  
 import org.apache.commons.httpclient.HttpMethod;
 33  
 import org.apache.commons.httpclient.HttpState;
 34  
 import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
 35  
 import org.apache.commons.httpclient.UsernamePasswordCredentials;
 36  
 import org.apache.commons.httpclient.auth.AuthScope;
 37  
 import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
 38  
 
 39  
 import sun.rmi.transport.Endpoint;
 40  
 
 41  
 /**
 42  
  * <code>HttpConnector</code> provides a way of receiving and sending http requests
 43  
  * and responses. The Connector itself handles dispatching http requests. The
 44  
  * <code>HttpMessageReceiver</code> handles the receiving requests and processing
 45  
  * of headers This endpoint recognises the following properties - <p/>
 46  
  * <ul>
 47  
  * <li>hostname - The hostname to send and receive http requests</li>
 48  
  * <li>port - The port to listen on. The industry standard is 80 and if this propert
 49  
  * is not set it will default to 80</li>
 50  
  * <li>proxyHostname - If you access the web through a proxy, this holds the server
 51  
  * address</li>
 52  
  * <li>proxyPort - The port the proxy is configured on</li>
 53  
  * <li>proxyUsername - If the proxy requires authentication supply a username</li>
 54  
  * <li>proxyPassword - If the proxy requires authentication supply a password</li>
 55  
  * </ul>
 56  
  * 
 57  
  */
 58  
 
 59  150
 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  
      * MuleEvent property to pass back the status for the response
 67  
      */
 68  
     public static final String HTTP_STATUS_PROPERTY = HTTP_PREFIX + "status";
 69  
     public static final String HTTP_VERSION_PROPERTY = HTTP_PREFIX + "version";
 70  
     public static final String HTTP_CUSTOM_HEADERS_MAP_PROPERTY = HTTP_PREFIX + "custom.headers";
 71  
     public static final String HTTP_METHOD_PROPERTY = HTTP_PREFIX + "method";
 72  
     public static final String HTTP_REQUEST_PROPERTY = HTTP_PREFIX + "request";
 73  
 
 74  
     /**
 75  
      * Allows the user to set a {@link org.apache.commons.httpclient.params.HttpMethodParams} object in the client
 76  
      * request to be set on the HttpMethod request object
 77  
      */
 78  
     public static final String HTTP_PARAMS_PROPERTY = HTTP_PREFIX + "params";
 79  
     public static final String HTTP_GET_BODY_PARAM_PROPERTY = HTTP_PREFIX + "get.body.param";
 80  
     public static final String DEFAULT_HTTP_GET_BODY_PARAM_PROPERTY = "body";
 81  
     public static final String HTTP_POST_BODY_PARAM_PROPERTY = HTTP_PREFIX + "post.body.param";
 82  
 
 83  
     public static final String HTTP_COOKIE_SPEC_PROPERTY = "cookieSpec";
 84  
     public static final String HTTP_COOKIES_PROPERTY = "cookies";
 85  
     public static final String HTTP_ENABLE_COOKIES_PROPERTY = "enableCookies";
 86  
 
 87  
     public static final String COOKIE_SPEC_NETSCAPE = "netscape";
 88  
     public static final String COOKIE_SPEC_RFC2109 = "rcf2109";
 89  
 
 90  150
     private String proxyHostname = null;
 91  
 
 92  150
     private int proxyPort = HttpConstants.DEFAULT_HTTP_PORT;
 93  
 
 94  150
     private String proxyUsername = null;
 95  
 
 96  150
     private String proxyPassword = null;
 97  
 
 98  
     private String cookieSpec;
 99  
 
 100  150
     private boolean enableCookies = false;
 101  
 
 102  
     protected HttpConnectionManager clientConnectionManager;
 103  
 
 104  
 
 105  
     //@Override
 106  
     protected void doInitialise() throws InitialisationException
 107  
     {
 108  150
         super.doInitialise();
 109  150
         if (clientConnectionManager == null)
 110  
         {
 111  150
             clientConnectionManager = new MultiThreadedHttpConnectionManager();
 112  150
             HttpConnectionManagerParams params = new HttpConnectionManagerParams();
 113  150
             if (getSendBufferSize() != INT_VALUE_NOT_SET)
 114  
             {
 115  14
                 params.setSendBufferSize(getSendBufferSize());
 116  
             }
 117  150
             if (getReceiveBufferSize() != INT_VALUE_NOT_SET)
 118  
             {
 119  14
                 params.setReceiveBufferSize(getReceiveBufferSize());
 120  
             }
 121  150
             if (getClientSoTimeout() != INT_VALUE_NOT_SET)
 122  
             {
 123  14
                 params.setSoTimeout(getClientSoTimeout());
 124  
             }
 125  150
             if (getSocketSoLinger() != INT_VALUE_NOT_SET)
 126  
             {
 127  14
                 params.setLinger(getSocketSoLinger());
 128  
             }
 129  
 
 130  150
             params.setTcpNoDelay(isSendTcpNoDelay());
 131  150
             params.setMaxTotalConnections(getDispatcherThreadingProfile().getMaxThreadsActive());
 132  150
             params.setDefaultMaxConnectionsPerHost(getDispatcherThreadingProfile().getMaxThreadsActive());
 133  
 
 134  150
             clientConnectionManager.setParams(params);
 135  
         }
 136  150
     }
 137  
 
 138  
     /**
 139  
      * @see Connector#registerListener(Service, Endpoint)
 140  
      */
 141  
     public MessageReceiver registerListener(Service service, InboundEndpoint endpoint) throws Exception
 142  
     {
 143  150
         if (endpoint != null)
 144  
         {
 145  142
             Map endpointProperties = endpoint.getProperties();
 146  142
             if (endpointProperties != null)
 147  
             {
 148  
                 // normalize properties for HTTP
 149  142
                 Map newProperties = new HashMap(endpointProperties.size());
 150  142
                 for (Iterator entries = endpointProperties.entrySet().iterator(); entries.hasNext();)
 151  
                 {
 152  0
                     Map.Entry entry = (Map.Entry)entries.next();
 153  0
                     Object key = entry.getKey();
 154  0
                     Object normalizedKey = HttpConstants.ALL_HEADER_NAMES.get(key);
 155  0
                     if (normalizedKey != null)
 156  
                     {
 157  
                         // normalized property exists
 158  0
                         key = normalizedKey;
 159  
                     }
 160  0
                     newProperties.put(key, entry.getValue());
 161  0
                 }
 162  
                 // set normalized properties back on the endpoint
 163  142
                 endpoint.getProperties().clear();
 164  142
                 endpoint.getProperties().putAll(newProperties);
 165  
             }
 166  
         }
 167  
         // proceed as usual
 168  150
         return super.registerListener(service, endpoint);
 169  
     }
 170  
 
 171  
     /**
 172  
      * The method determines the key used to store the receiver against.
 173  
      *
 174  
      * @param service the service for which the endpoint is being registered
 175  
      * @param endpoint the endpoint being registered for the service
 176  
      * @return the key to store the newly created receiver against
 177  
      */
 178  
     protected Object getReceiverKey(Service service, InboundEndpoint endpoint)
 179  
     {
 180  670
         String key = endpoint.getEndpointURI().toString();
 181  670
         int i = key.indexOf('?');
 182  670
         if (i > -1)
 183  
         {
 184  0
             key = key.substring(0, i);
 185  
         }
 186  670
         return key;
 187  
     }
 188  
 
 189  
     /**
 190  
      * @see org.mule.api.transport.Connector#getProtocol()
 191  
      */
 192  
     public String getProtocol()
 193  
     {
 194  766
         return HTTP;
 195  
     }
 196  
 
 197  
     /**
 198  
      * @return
 199  
      */
 200  
     public String getProxyHostname()
 201  
     {
 202  148
         return proxyHostname;
 203  
     }
 204  
 
 205  
     /**
 206  
      * @return
 207  
      */
 208  
     public String getProxyPassword()
 209  
     {
 210  8
         return proxyPassword;
 211  
     }
 212  
 
 213  
     /**
 214  
      * @return
 215  
      */
 216  
     public int getProxyPort()
 217  
     {
 218  8
         return proxyPort;
 219  
     }
 220  
 
 221  
     /**
 222  
      * @return
 223  
      */
 224  
     public String getProxyUsername()
 225  
     {
 226  72
         return proxyUsername;
 227  
     }
 228  
 
 229  
     /**
 230  
      * @param host
 231  
      */
 232  
     public void setProxyHostname(String host)
 233  
     {
 234  14
         proxyHostname = host;
 235  14
     }
 236  
 
 237  
     /**
 238  
      * @param string
 239  
      */
 240  
     public void setProxyPassword(String string)
 241  
     {
 242  14
         proxyPassword = string;
 243  14
     }
 244  
 
 245  
     /**
 246  
      * @param port
 247  
      */
 248  
     public void setProxyPort(int port)
 249  
     {
 250  14
         proxyPort = port;
 251  14
     }
 252  
 
 253  
     /**
 254  
      * @param string
 255  
      */
 256  
     public void setProxyUsername(String string)
 257  
     {
 258  14
         proxyUsername = string;
 259  14
     }
 260  
 
 261  
     public Map getReceivers()
 262  
     {
 263  12
         return this.receivers;
 264  
     }
 265  
 
 266  
     public String getCookieSpec()
 267  
     {
 268  160
         return cookieSpec;
 269  
     }
 270  
 
 271  
     public void setCookieSpec(String cookieSpec)
 272  
     {
 273  14
         if (!(COOKIE_SPEC_NETSCAPE.equalsIgnoreCase(cookieSpec) || COOKIE_SPEC_RFC2109.equalsIgnoreCase(cookieSpec)))
 274  
         {
 275  0
             throw new IllegalArgumentException(
 276  
                 CoreMessages.propertyHasInvalidValue("cookieSpec", cookieSpec).toString());
 277  
         }
 278  14
         this.cookieSpec = cookieSpec;
 279  14
     }
 280  
 
 281  
     public boolean isEnableCookies()
 282  
     {
 283  160
         return enableCookies;
 284  
     }
 285  
 
 286  
     public void setEnableCookies(boolean enableCookies)
 287  
     {
 288  16
         this.enableCookies = enableCookies;
 289  16
     }
 290  
 
 291  
 
 292  
     public HttpConnectionManager getClientConnectionManager()
 293  
     {
 294  66
         return clientConnectionManager;
 295  
     }
 296  
 
 297  
     public void setClientConnectionManager(HttpConnectionManager clientConnectionManager)
 298  
     {
 299  0
         this.clientConnectionManager = clientConnectionManager;
 300  0
     }
 301  
 
 302  
     protected HttpClient doClientConnect() throws Exception
 303  
     {
 304  64
         HttpState state = new HttpState();
 305  
 
 306  64
         if (getProxyUsername() != null)
 307  
         {
 308  0
             state.setProxyCredentials(
 309  
                     new AuthScope(null, -1, null, null),
 310  
                     new UsernamePasswordCredentials(getProxyUsername(), getProxyPassword()));
 311  
         }
 312  
 
 313  64
         HttpClient client = new HttpClient();
 314  64
         client.setState(state);
 315  64
         client.setHttpConnectionManager(getClientConnectionManager());
 316  
 
 317  64
         return client;
 318  
     }
 319  
 
 320  
     protected void setupClientAuthorization(MuleEvent event, HttpMethod httpMethod,
 321  
                                             HttpClient client, ImmutableEndpoint endpoint)
 322  
             throws UnsupportedEncodingException
 323  
     {
 324  140
         httpMethod.setDoAuthentication(true);
 325  140
         if (event != null && event.getCredentials() != null)
 326  
         {
 327  2
             MuleMessage msg = event.getMessage();
 328  2
             String authScopeHost = msg.getStringProperty(HTTP_PREFIX + "auth.scope.host", null);
 329  2
             int authScopePort = msg.getIntProperty(HTTP_PREFIX + "auth.scope.port", -1);
 330  2
             String authScopeRealm = msg.getStringProperty(HTTP_PREFIX + "auth.scope.realm", null);
 331  2
             String authScopeScheme = msg.getStringProperty(HTTP_PREFIX + "auth.scope.scheme", null);
 332  2
             client.getState().setCredentials(
 333  
                 new AuthScope(authScopeHost, authScopePort, authScopeRealm, authScopeScheme),
 334  
                 new UsernamePasswordCredentials(event.getCredentials().getUsername(), new String(
 335  
                     event.getCredentials().getPassword())));
 336  2
             client.getParams().setAuthenticationPreemptive(true);
 337  2
         }
 338  138
         else if (endpoint.getEndpointURI().getUserInfo() != null
 339  
             && endpoint.getProperty(HttpConstants.HEADER_AUTHORIZATION) == null)
 340  
         {
 341  
             // Add User Creds
 342  0
             StringBuffer header = new StringBuffer(128);
 343  0
             header.append("Basic ");
 344  0
             header.append(new String(Base64.encodeBase64(endpoint.getEndpointURI().getUserInfo().getBytes(
 345  
                 endpoint.getEncoding()))));
 346  0
             httpMethod.addRequestHeader(HttpConstants.HEADER_AUTHORIZATION, header.toString());
 347  0
         }
 348  
         else
 349  
         {
 350  
             // don't use preemptive if there are no credentials to send
 351  138
             client.getParams().setAuthenticationPreemptive(false);
 352  
         }
 353  
 
 354  140
     }
 355  
 
 356  
 }