Package com.eviware.soapui.impl.wsdl.submit.filters

Source Code of com.eviware.soapui.impl.wsdl.submit.filters.HttpRequestFilter

/*
*  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.filters;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.MessagingException;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.PreencodedMimeBodyPart;

import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.URI;
import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.xmlbeans.XmlBoolean;

import com.eviware.soapui.SoapUI;
import com.eviware.soapui.impl.rest.RestRequest;
import com.eviware.soapui.impl.rest.support.RestParamProperty;
import com.eviware.soapui.impl.rest.support.RestParamsPropertyHolder;
import com.eviware.soapui.impl.rest.support.RestParamsPropertyHolder.ParameterStyle;
import com.eviware.soapui.impl.rest.support.RestUtils;
import com.eviware.soapui.impl.support.http.HttpRequestInterface;
import com.eviware.soapui.impl.wsdl.submit.transports.http.BaseHttpRequestTransport;
import com.eviware.soapui.impl.wsdl.submit.transports.http.support.attachments.AttachmentDataSource;
import com.eviware.soapui.impl.wsdl.submit.transports.http.support.attachments.AttachmentUtils;
import com.eviware.soapui.impl.wsdl.submit.transports.http.support.attachments.RestRequestDataSource;
import com.eviware.soapui.impl.wsdl.submit.transports.http.support.attachments.RestRequestMimeMessageRequestEntity;
import com.eviware.soapui.impl.wsdl.support.FileAttachment;
import com.eviware.soapui.impl.wsdl.support.PathUtils;
import com.eviware.soapui.impl.wsdl.teststeps.HttpTestRequest;
import com.eviware.soapui.model.iface.Attachment;
import com.eviware.soapui.model.iface.SubmitContext;
import com.eviware.soapui.model.propertyexpansion.PropertyExpander;
import com.eviware.soapui.settings.HttpSettings;
import com.eviware.soapui.support.StringUtils;
import com.eviware.soapui.support.editor.inspectors.attachments.ContentTypeHandler;
import com.eviware.soapui.support.types.StringToStringMap;

/**
* RequestFilter that adds SOAP specific headers
*
* @author Ole.Matzura
*/

public class HttpRequestFilter extends AbstractRequestFilter
{
  @SuppressWarnings( "deprecation" )
  @Override
  public void filterHttpRequest( SubmitContext context, HttpRequestInterface<?> request )
  {
    HttpMethod httpMethod = ( HttpMethod )context.getProperty( BaseHttpRequestTransport.HTTP_METHOD );

    String path = PropertyExpander.expandProperties( context, request.getPath() );
    StringBuffer query = new StringBuffer();

    StringToStringMap responseProperties = ( StringToStringMap )context
        .getProperty( BaseHttpRequestTransport.RESPONSE_PROPERTIES );

    MimeMultipart formMp = "multipart/form-data".equals( request.getMediaType() )
        && httpMethod instanceof EntityEnclosingMethod ? new MimeMultipart() : null;

    RestParamsPropertyHolder params = request.getParams();

    for( int c = 0; c < params.getPropertyCount(); c++ )
    {
      RestParamProperty param = params.getPropertyAt( c );

      String value = PropertyExpander.expandProperties( context, param.getValue() );
      responseProperties.put( param.getName(), value );

      List<String> valueParts = sendEmptyParameters( request ) ? RestUtils.splitMultipleParametersEmptyIncluded(
          value, request.getMultiValueDelimiter() ) : RestUtils.splitMultipleParameters( value,
          request.getMultiValueDelimiter() );

      // skip HEADER and TEMPLATE parameter encoding (TEMPLATE is encoded by
      // the URI handling further down)
      if( value != null && param.getStyle() != ParameterStyle.HEADER && param.getStyle() != ParameterStyle.TEMPLATE
          && !param.isDisableUrlEncoding() )
      {
        try
        {
          String encoding = System.getProperty( "soapui.request.encoding", request.getEncoding() );

          if( StringUtils.hasContent( encoding ) )
          {
            value = URLEncoder.encode( value, encoding );
            for( int i = 0; i < valueParts.size(); i++ )
              valueParts.set( i, URLEncoder.encode( valueParts.get( i ), encoding ) );
          }
          else
          {
            value = URLEncoder.encode( value );
            for( int i = 0; i < valueParts.size(); i++ )
              valueParts.set( i, URLEncoder.encode( valueParts.get( i ) ) );
          }
        }
        catch( UnsupportedEncodingException e1 )
        {
          SoapUI.logError( e1 );
          value = URLEncoder.encode( value );
          for( int i = 0; i < valueParts.size(); i++ )
            valueParts.set( i, URLEncoder.encode( valueParts.get( i ) ) );
        }
        // URLEncoder replaces space with "+", but we want "%20".
        value = value.replaceAll( "\\+", "%20" );
        for( int i = 0; i < valueParts.size(); i++ )
          valueParts.set( i, valueParts.get( i ).replaceAll( "\\+", "%20" ) );
      }

      if( !sendEmptyParameters( request ) )
      {
        if( !StringUtils.hasContent( value ) && !param.getRequired() )
          continue;
      }

      switch( param.getStyle() )
      {
      case HEADER :
        for( String valuePart : valueParts )
          httpMethod.addRequestHeader( param.getName(), valuePart );
        break;
      case QUERY :
        if( formMp == null || !request.isPostQueryString() )
        {
          for( String valuePart : valueParts )
          {
            if( query.length() > 0 )
              query.append( '&' );

            query.append( URLEncoder.encode( param.getName() ) );
            query.append( '=' );
            if( StringUtils.hasContent( valuePart ) )
              query.append( valuePart );
          }
        }
        else
        {
          try
          {
            addFormMultipart( request, formMp, param.getName(), responseProperties.get( param.getName() ) );
          }
          catch( MessagingException e )
          {
            e.printStackTrace();
          }
        }

        break;
      case TEMPLATE :
        path = path.replaceAll( "\\{" + param.getName() + "\\}", value == null ? "" : value );
        break;
      case MATRIX :
        if( param.getType().equals( XmlBoolean.type.getName() ) )
        {
          if( value.toUpperCase().equals( "TRUE" ) || value.equals( "1" ) )
          {
            path += ";" + param.getName();
          }
        }
        else
        {
          path += ";" + param.getName();
          if( StringUtils.hasContent( value ) )
          {
            path += "=" + value;
          }
        }
      case PLAIN :
        break;
      }
    }

    if( request.getSettings().getBoolean( HttpSettings.FORWARD_SLASHES ) )
      path = PathUtils.fixForwardSlashesInPath( path );

    if( PathUtils.isHttpPath( path ) )
    {
      try
      {
        // URI(String) automatically URLencodes the input, so we need to
        // decode it first...
        URI uri = new URI( path, false );
        context.setProperty( BaseHttpRequestTransport.REQUEST_URI, uri );
        httpMethod.setURI( uri );
      }
      catch( Exception e )
      {
        e.printStackTrace();
      }
    }
    else if( StringUtils.hasContent( path ) )
    {
      try
      {
        // URI(String) automatically URLencodes the input, so we need to
        // decode it first...
        URI uri = new URI( path, false );
        httpMethod.setPath( uri.toString() );
      }
      catch( Exception e )
      {
        e.printStackTrace();
        httpMethod.setPath( path );
      }
    }

    if( query.length() > 0 && !request.isPostQueryString() )
    {
      httpMethod.setQueryString( query.toString() );
    }

    if( request instanceof RestRequest )
    {
      String acceptEncoding = ( ( RestRequest )request ).getAccept();
      if( StringUtils.hasContent( acceptEncoding ) )
      {
        httpMethod.setRequestHeader( "Accept", acceptEncoding );
      }
    }

    String encoding = System.getProperty( "soapui.request.encoding", StringUtils.unquote( request.getEncoding() ) );

    if( formMp != null )
    {
      // create request message
      try
      {
        if( request.hasRequestBody() && httpMethod instanceof EntityEnclosingMethod )
        {
          String requestContent = PropertyExpander.expandProperties( context, request.getRequestContent(),
              request.isEntitizeProperties() );
          if( StringUtils.hasContent( requestContent ) )
          {
            initRootPart( request, requestContent, formMp );
          }
        }

        for( Attachment attachment : request.getAttachments() )
        {
          MimeBodyPart part = new PreencodedMimeBodyPart( "binary" );

          if( attachment instanceof FileAttachment<?> )
          {
            String name = attachment.getName();
            if( StringUtils.hasContent( attachment.getContentID() ) && !name.equals( attachment.getContentID() ) )
              name = attachment.getContentID();

            part.setDisposition( "form-data; name=\"" + name + "\"; filename=\"" + attachment.getName() + "\"" );
          }
          else
            part.setDisposition( "form-data; name=\"" + attachment.getName() + "\"" );

          part.setDataHandler( new DataHandler( new AttachmentDataSource( attachment ) ) );

          formMp.addBodyPart( part );
        }

        MimeMessage message = new MimeMessage( AttachmentUtils.JAVAMAIL_SESSION );
        message.setContent( formMp );
        message.saveChanges();
        RestRequestMimeMessageRequestEntity mimeMessageRequestEntity = new RestRequestMimeMessageRequestEntity(
            message, request );
        ( ( EntityEnclosingMethod )httpMethod ).setRequestEntity( mimeMessageRequestEntity );
        httpMethod.setRequestHeader( "Content-Type", mimeMessageRequestEntity.getContentType() );
        httpMethod.setRequestHeader( "MIME-Version", "1.0" );
      }
      catch( Throwable e )
      {
        SoapUI.logError( e );
      }
    }
    else if( request.hasRequestBody() && httpMethod instanceof EntityEnclosingMethod )
    {
      if( StringUtils.hasContent( request.getMediaType() ) )
        httpMethod.setRequestHeader( "Content-Type", getContentTypeHeader( request.getMediaType(), encoding ) );

      if( request.isPostQueryString() )
      {
        ( ( EntityEnclosingMethod )httpMethod ).setRequestEntity( new StringRequestEntity( query.toString() ) );
      }
      else
      {
        String requestContent = PropertyExpander.expandProperties( context, request.getRequestContent(),
            request.isEntitizeProperties() );
        List<Attachment> attachments = new ArrayList<Attachment>();

        for( Attachment attachment : request.getAttachments() )
        {
          if( attachment.getContentType().equals( request.getMediaType() ) )
          {
            attachments.add( attachment );
          }
        }

        if( StringUtils.hasContent( requestContent ) && attachments.isEmpty() )
        {
          try
          {
            byte[] content = encoding == null ? requestContent.getBytes() : requestContent.getBytes( encoding );
            ( ( EntityEnclosingMethod )httpMethod ).setRequestEntity( new ByteArrayRequestEntity( content ) );
          }
          catch( UnsupportedEncodingException e )
          {
            ( ( EntityEnclosingMethod )httpMethod ).setRequestEntity( new ByteArrayRequestEntity( requestContent
                .getBytes() ) );
          }
        }
        else if( attachments.size() > 0 )
        {
          try
          {
            MimeMultipart mp = null;

            if( StringUtils.hasContent( requestContent ) )
            {
              mp = new MimeMultipart();
              initRootPart( request, requestContent, mp );
            }
            else if( attachments.size() == 1 )
            {
              ( ( EntityEnclosingMethod )httpMethod ).setRequestEntity( new InputStreamRequestEntity(
                  attachments.get( 0 ).getInputStream() ) );

              httpMethod.setRequestHeader( "Content-Type",
                  getContentTypeHeader( request.getMediaType(), encoding ) );
            }

            if( ( ( EntityEnclosingMethod )httpMethod ).getRequestEntity() == null )
            {
              if( mp == null )
                mp = new MimeMultipart();

              // init mimeparts
              AttachmentUtils.addMimeParts( request, attachments, mp, new StringToStringMap() );

              // create request message
              MimeMessage message = new MimeMessage( AttachmentUtils.JAVAMAIL_SESSION );
              message.setContent( mp );
              message.saveChanges();
              RestRequestMimeMessageRequestEntity mimeMessageRequestEntity = new RestRequestMimeMessageRequestEntity(
                  message, request );
              ( ( EntityEnclosingMethod )httpMethod ).setRequestEntity( mimeMessageRequestEntity );
              httpMethod.setRequestHeader( "Content-Type",
                  getContentTypeHeader( mimeMessageRequestEntity.getContentType(), encoding ) );
              httpMethod.setRequestHeader( "MIME-Version", "1.0" );
            }
          }
          catch( Exception e )
          {
            e.printStackTrace();
          }
        }
      }
    }
  }

  private boolean sendEmptyParameters( HttpRequestInterface<?> request )
  {
    return request instanceof HttpTestRequest && ( ( HttpTestRequest )request ).isSendEmptyParameters();
  }

  private String getContentTypeHeader( String contentType, String encoding )
  {
    return ( encoding == null || encoding.trim().length() == 0 ) ? contentType : contentType + ";charset=" + encoding;
  }

  private void addFormMultipart( HttpRequestInterface<?> request, MimeMultipart formMp, String name, String value )
      throws MessagingException
  {
    MimeBodyPart part = new MimeBodyPart();

    if( value.startsWith( "file:" ) )
    {
      String fileName = value.substring( 5 );
      File file = new File( fileName );
      part.setDisposition( "form-data; name=\"" + name + "\"; filename=\"" + file.getName() + "\"" );
      if( file.exists() )
      {
        part.setDataHandler( new DataHandler( new FileDataSource( file ) ) );
      }
      else
      {
        for( Attachment attachment : request.getAttachments() )
        {
          if( attachment.getName().equals( fileName ) )
          {
            part.setDataHandler( new DataHandler( new AttachmentDataSource( attachment ) ) );
            break;
          }
        }
      }

      part.setHeader( "Content-Type", ContentTypeHandler.getContentTypeFromFilename( file.getName() ) );
      part.setHeader( "Content-Transfer-Encoding", "binary" );
    }
    else
    {
      part.setDisposition( "form-data; name=\"" + name + "\"" );
      part.setText( value, System.getProperty( "soapui.request.encoding", request.getEncoding() ) );
    }

    if( part != null )
    {
      formMp.addBodyPart( part );
    }
  }

  protected void initRootPart( HttpRequestInterface<?> wsdlRequest, String requestContent, MimeMultipart mp )
      throws MessagingException
  {
    MimeBodyPart rootPart = new PreencodedMimeBodyPart( "8bit" );
    // rootPart.setContentID( AttachmentUtils.ROOTPART_SOAPUI_ORG );
    mp.addBodyPart( rootPart, 0 );

    DataHandler dataHandler = new DataHandler( new RestRequestDataSource( wsdlRequest, requestContent ) );
    rootPart.setDataHandler( dataHandler );
  }
}
TOP

Related Classes of com.eviware.soapui.impl.wsdl.submit.filters.HttpRequestFilter

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.