Package com.eviware.soapui.impl.wsdl.submit.transports.http

Source Code of com.eviware.soapui.impl.wsdl.submit.transports.http.HttpClientRequestTransport

/*
*  soapUI, copyright (C) 2004-2011 eviware.com
*
*  soapUI is free software; you can redistribute it and/or modify it under the
*  terms of version 2.1 of the GNU Lesser General Public License as published by
*  the Free Software Foundation.
*
*  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
*  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*  See the GNU Lesser General Public License for more details at gnu.org.
*/

package com.eviware.soapui.impl.wsdl.submit.transports.http;

import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethodBase;
import org.apache.commons.httpclient.HttpState;
import org.apache.commons.httpclient.URI;
import org.apache.log4j.Logger;

import com.eviware.soapui.SoapUI;
import com.eviware.soapui.impl.support.AbstractHttpRequestInterface;
import com.eviware.soapui.impl.support.http.HttpRequestInterface;
import com.eviware.soapui.impl.wsdl.AbstractWsdlModelItem;
import com.eviware.soapui.impl.wsdl.WsdlProject;
import com.eviware.soapui.impl.wsdl.submit.RequestFilter;
import com.eviware.soapui.impl.wsdl.submit.transports.http.support.attachments.MimeMessageResponse;
import com.eviware.soapui.impl.wsdl.submit.transports.http.support.methods.ExtendedDeleteMethod;
import com.eviware.soapui.impl.wsdl.submit.transports.http.support.methods.ExtendedGetMethod;
import com.eviware.soapui.impl.wsdl.submit.transports.http.support.methods.ExtendedHeadMethod;
import com.eviware.soapui.impl.wsdl.submit.transports.http.support.methods.ExtendedOptionsMethod;
import com.eviware.soapui.impl.wsdl.submit.transports.http.support.methods.ExtendedPostMethod;
import com.eviware.soapui.impl.wsdl.submit.transports.http.support.methods.ExtendedPutMethod;
import com.eviware.soapui.impl.wsdl.submit.transports.http.support.methods.ExtendedTraceMethod;
import com.eviware.soapui.impl.wsdl.support.PathUtils;
import com.eviware.soapui.impl.wsdl.support.http.HttpClientSupport;
import com.eviware.soapui.impl.wsdl.support.http.SoapUIHostConfiguration;
import com.eviware.soapui.impl.wsdl.support.wss.WssCrypto;
import com.eviware.soapui.model.iface.Request;
import com.eviware.soapui.model.iface.Response;
import com.eviware.soapui.model.iface.SubmitContext;
import com.eviware.soapui.model.propertyexpansion.PropertyExpander;
import com.eviware.soapui.model.settings.Settings;
import com.eviware.soapui.model.support.ModelSupport;
import com.eviware.soapui.settings.HttpSettings;
import com.eviware.soapui.support.StringUtils;
import com.eviware.soapui.support.types.StringToStringMap;
import com.eviware.soapui.support.types.StringToStringsMap;

/**
* HTTP transport that uses HttpClient to send/receive SOAP messages
*
* @author Ole.Matzura
*/

public class HttpClientRequestTransport implements BaseHttpRequestTransport
{
  private List<RequestFilter> filters = new ArrayList<RequestFilter>();
  private final static Logger log = Logger.getLogger( HttpClientRequestTransport.class );

  public HttpClientRequestTransport()
  {
  }

  public void addRequestFilter( RequestFilter filter )
  {
    filters.add( filter );
  }

  public void removeRequestFilter( RequestFilter filter )
  {
    filters.remove( filter );
  }

  public void abortRequest( SubmitContext submitContext )
  {
    HttpMethodBase postMethod = ( HttpMethodBase )submitContext.getProperty( HTTP_METHOD );
    if( postMethod != null )
      postMethod.abort();
  }

  public Response sendRequest( SubmitContext submitContext, Request request ) throws Exception
  {
    AbstractHttpRequestInterface<?> httpRequest = ( AbstractHttpRequestInterface<?> )request;

    HttpClient httpClient = HttpClientSupport.getHttpClient();
    ExtendedHttpMethod httpMethod = createHttpMethod( httpRequest );
    boolean createdState = false;

    HttpState httpState = ( HttpState )submitContext.getProperty( SubmitContext.HTTP_STATE_PROPERTY );
    if( httpState == null )
    {
      httpState = new HttpState();
      submitContext.setProperty( SubmitContext.HTTP_STATE_PROPERTY, httpState );
      createdState = true;
    }

    HostConfiguration hostConfiguration = new HostConfiguration();

    String localAddress = System.getProperty( "soapui.bind.address", httpRequest.getBindAddress() );
    if( localAddress == null || localAddress.trim().length() == 0 )
      localAddress = SoapUI.getSettings().getString( HttpSettings.BIND_ADDRESS, null );

    if( localAddress != null && localAddress.trim().length() > 0 )
    {
      try
      {
        hostConfiguration.setLocalAddress( InetAddress.getByName( localAddress ) );
      }
      catch( Exception e )
      {
        SoapUI.logError( e, "Failed to set localAddress to [" + localAddress + "]" );
      }
    }

    submitContext.removeProperty( RESPONSE );
    submitContext.setProperty( HTTP_METHOD, httpMethod );
    submitContext.setProperty( POST_METHOD, httpMethod );
    submitContext.setProperty( HTTP_CLIENT, httpClient );
    submitContext.setProperty( REQUEST_CONTENT, httpRequest.getRequestContent() );
    submitContext.setProperty( HOST_CONFIGURATION, hostConfiguration );
    submitContext.setProperty( WSDL_REQUEST, httpRequest );
    submitContext.setProperty( RESPONSE_PROPERTIES, new StringToStringMap() );

    for( RequestFilter filter : filters )
    {
      filter.filterRequest( submitContext, httpRequest );
    }

    try
    {
      Settings settings = httpRequest.getSettings();

      // custom http headers last so they can be overridden
      StringToStringsMap headers = httpRequest.getRequestHeaders();

      // first remove so we don't get any unwanted duplicates
      for( String header : headers.keySet() )
      {
        httpMethod.removeRequestHeader( header );
      }

      // now add
      for( String header : headers.keySet() )
      {
        for( String headerValue : headers.get( header ) )
        {
          headerValue = PropertyExpander.expandProperties( submitContext, headerValue );
          httpMethod.addRequestHeader( header, headerValue );
        }
      }

      // do request
      WsdlProject project = ( WsdlProject )ModelSupport.getModelItemProject( httpRequest );
      WssCrypto crypto = null;
      if( project != null && project.getWssContainer() != null )
      {
        crypto = project.getWssContainer().getCryptoByName(
            PropertyExpander.expandProperties( submitContext, httpRequest.getSslKeystore() ) );
      }

      if( crypto != null && WssCrypto.STATUS_OK.equals( crypto.getStatus() ) )
      {
        hostConfiguration.getParams().setParameter( SoapUIHostConfiguration.SOAPUI_SSL_CONFIG,
            crypto.getSource() + " " + crypto.getPassword() );
      }

      // dump file?
      httpMethod.setDumpFile( PathUtils.expandPath( httpRequest.getDumpFile(),
          ( AbstractWsdlModelItem<?> )httpRequest, submitContext ) );

      // fix absolute URIs due to peculiarity in httpclient
      URI uri = ( URI )submitContext.getProperty( BaseHttpRequestTransport.REQUEST_URI );
      if( uri != null && uri.isAbsoluteURI() )
      {
        hostConfiguration.setHost( uri.getHost(), uri.getPort() );
        String str = uri.toString();
        int ix = str.indexOf( '/', str.indexOf( "//" ) + 2 );
        if( ix != -1 )
        {
          uri = new URI( str.substring( ix ), true );
          String qs = httpMethod.getQueryString();
          httpMethod.setURI( uri );
          if( StringUtils.hasContent( qs ) )
            httpMethod.setQueryString( qs );

          submitContext.setProperty( BaseHttpRequestTransport.REQUEST_URI, uri );
        }
      }

      // include request time?
      if( settings.getBoolean( HttpSettings.INCLUDE_REQUEST_IN_TIME_TAKEN ) )
        httpMethod.initStartTime();

      // submit!
      httpClient.executeMethod( hostConfiguration, httpMethod, httpState );
      httpMethod.getTimeTaken();

      if( isRedirectResponse( httpMethod ) && httpRequest.isFollowRedirects() )
      {
        ExtendedGetMethod returnMethod = followRedirects( httpClient, 0, httpMethod, httpState );
        httpMethod.releaseConnection();
        httpMethod = returnMethod;
        submitContext.setProperty( HTTP_METHOD, httpMethod );
      }
    }
    catch( Throwable t )
    {
      httpMethod.setFailed( t );

      if( t instanceof Exception )
        throw ( Exception )t;

      SoapUI.logError( t );
      throw new Exception( t );
    }
    finally
    {
      for( int c = filters.size() - 1; c >= 0; c-- )
      {
        RequestFilter filter = filters.get( c );
        filter.afterRequest( submitContext, httpRequest );
      }

      if( !submitContext.hasProperty( RESPONSE ) )
      {
        createDefaultResponse( submitContext, httpRequest, httpMethod );
      }

      Response response = ( Response )submitContext.getProperty( BaseHttpRequestTransport.RESPONSE );
      StringToStringMap responseProperties = ( StringToStringMap )submitContext
          .getProperty( BaseHttpRequestTransport.RESPONSE_PROPERTIES );

      for( String key : responseProperties.keySet() )
      {
        response.setProperty( key, responseProperties.get( key ) );
      }

      if( httpMethod != null )
      {
        httpMethod.releaseConnection();
      }
      else
        log.error( "PostMethod is null" );

      if( createdState )
      {
        submitContext.setProperty( SubmitContext.HTTP_STATE_PROPERTY, null );
      }
    }

    return ( Response )submitContext.getProperty( BaseHttpRequestTransport.RESPONSE );
  }

  private boolean isRedirectResponse( ExtendedHttpMethod httpMethod )
  {
    switch( httpMethod.getStatusCode() )
    {
    case 301 :
    case 302 :
    case 303 :
    case 307 :
      return true;
    }

    return false;
  }

  private ExtendedGetMethod followRedirects( HttpClient httpClient, int redirectCount, ExtendedHttpMethod httpMethod,
      HttpState httpState ) throws Exception
  {
    ExtendedGetMethod getMethod = new ExtendedGetMethod();
    for( Header header : httpMethod.getRequestHeaders() )
      getMethod.addRequestHeader( header );

    URI uri = new URI( httpMethod.getResponseHeader( "Location" ).getValue(), true );
    getMethod.setURI( uri );
    HostConfiguration host = new HostConfiguration();
    host.setHost( uri );
    httpClient.executeMethod( host, getMethod, httpState );
    if( isRedirectResponse( getMethod ) )
    {
      if( redirectCount == 10 )
        throw new Exception( "Maximum number of Redirects reached [10]" );

      try
      {
        return followRedirects( httpClient, redirectCount + 1, getMethod, httpState );
      }
      finally
      {
        getMethod.releaseConnection();
      }
    }
    else
      return getMethod;

  }

  private void createDefaultResponse( SubmitContext submitContext, AbstractHttpRequestInterface<?> httpRequest,
      ExtendedHttpMethod httpMethod )
  {
    String requestContent = ( String )submitContext.getProperty( BaseHttpRequestTransport.REQUEST_CONTENT );

    // check content-type for multiplart
    Header responseContentTypeHeader = httpMethod.getResponseHeader( "Content-Type" );
    Response response = null;

    if( responseContentTypeHeader != null
        && responseContentTypeHeader.getValue().toUpperCase().startsWith( "MULTIPART" ) )
    {
      response = new MimeMessageResponse( httpRequest, httpMethod, requestContent, submitContext );
    }
    else
    {
      response = new SinglePartHttpResponse( httpRequest, httpMethod, requestContent, submitContext );
    }

    submitContext.setProperty( BaseHttpRequestTransport.RESPONSE, response );
  }

  private ExtendedHttpMethod createHttpMethod( AbstractHttpRequestInterface<?> httpRequest )
  {
    if( httpRequest instanceof HttpRequestInterface<?> )
    {
      HttpRequestInterface<?> restRequest = ( HttpRequestInterface<?> )httpRequest;
      switch( restRequest.getMethod() )
      {
      case GET :
        return new ExtendedGetMethod();
      case HEAD :
        return new ExtendedHeadMethod();
      case DELETE :
        return new ExtendedDeleteMethod();
      case PUT :
        return new ExtendedPutMethod();
      case OPTIONS :
        return new ExtendedOptionsMethod();
      case TRACE :
        return new ExtendedTraceMethod();
      }
    }

    ExtendedPostMethod extendedPostMethod = new ExtendedPostMethod();

    extendedPostMethod.setAfterRequestInjection( httpRequest.getAfterRequestInjection() );
    return extendedPostMethod;
  }

}
TOP

Related Classes of com.eviware.soapui.impl.wsdl.submit.transports.http.HttpClientRequestTransport

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.