Package com.eviware.soapui.impl.wsdl.monitor.jettyproxy

Source Code of com.eviware.soapui.impl.wsdl.monitor.jettyproxy.ProxyServlet

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

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpState;
import org.apache.commons.httpclient.URI;
import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
import org.mortbay.util.IO;

import com.eviware.soapui.impl.wsdl.WsdlProject;
import com.eviware.soapui.impl.wsdl.actions.monitor.SoapMonitorAction;
import com.eviware.soapui.impl.wsdl.actions.monitor.SoapMonitorAction.LaunchForm;
import com.eviware.soapui.impl.wsdl.monitor.CaptureInputStream;
import com.eviware.soapui.impl.wsdl.monitor.JProxyServletWsdlMonitorMessageExchange;
import com.eviware.soapui.impl.wsdl.monitor.SoapMonitor;
import com.eviware.soapui.impl.wsdl.submit.transports.http.ExtendedHttpMethod;
import com.eviware.soapui.impl.wsdl.submit.transports.http.support.methods.ExtendedGetMethod;
import com.eviware.soapui.impl.wsdl.submit.transports.http.support.methods.ExtendedPostMethod;
import com.eviware.soapui.impl.wsdl.support.http.HttpClientSupport;
import com.eviware.soapui.model.settings.Settings;
import com.eviware.soapui.support.types.StringToStringsMap;

public class ProxyServlet implements Servlet
{
  protected ServletConfig config;
  protected ServletContext context;
  protected SoapMonitor monitor;
  protected WsdlProject project;
  protected HttpState httpState = new HttpState();
  protected Settings settings;

  static HashSet<String> dontProxyHeaders = new HashSet<String>();
  {
    dontProxyHeaders.add( "proxy-connection" );
    dontProxyHeaders.add( "connection" );
    dontProxyHeaders.add( "keep-alive" );
    dontProxyHeaders.add( "transfer-encoding" );
    dontProxyHeaders.add( "te" );
    dontProxyHeaders.add( "trailer" );
    dontProxyHeaders.add( "proxy-authorization" );
    dontProxyHeaders.add( "proxy-authenticate" );
    dontProxyHeaders.add( "upgrade" );
  }

  public ProxyServlet( SoapMonitor soapMonitor )
  {
    this.monitor = soapMonitor;
    this.project = monitor.getProject();
    settings = project.getSettings();
  }

  public void destroy()
  {
  }

  public ServletConfig getServletConfig()
  {
    return config;
  }

  public String getServletInfo()
  {
    return "SoapUI Monitor";
  }

  public void init( ServletConfig config ) throws ServletException
  {
    this.config = config;
    this.context = config.getServletContext();
  }

  public void service( ServletRequest request, ServletResponse response ) throws ServletException, IOException
  {
    monitor.fireOnRequest( request, response );
    if( response.isCommitted() )
      return;

    ExtendedHttpMethod method;
    HttpServletRequest httpRequest = ( HttpServletRequest )request;
    if( httpRequest.getMethod().equals( "GET" ) )
      method = new ExtendedGetMethod();
    else
      method = new ExtendedPostMethod();

    method.setDecompress( false );

    // for this create ui server and port, properties.
    JProxyServletWsdlMonitorMessageExchange capturedData = new JProxyServletWsdlMonitorMessageExchange( project );
    capturedData.setRequestHost( httpRequest.getServerName() );
    capturedData.setRequestMethod( httpRequest.getMethod() );
    capturedData.setRequestHeader( httpRequest );
    capturedData.setHttpRequestParameters( httpRequest );
    capturedData.setTargetURL( httpRequest.getRequestURL().toString() );

    CaptureInputStream capture = new CaptureInputStream( httpRequest.getInputStream() );

    // check connection header
    String connectionHeader = httpRequest.getHeader( "Connection" );
    if( connectionHeader != null )
    {
      connectionHeader = connectionHeader.toLowerCase();
      if( connectionHeader.indexOf( "keep-alive" ) < 0 && connectionHeader.indexOf( "close" ) < 0 )
        connectionHeader = null;
    }

    // copy headers
    boolean xForwardedFor = false;
    @SuppressWarnings( "unused" )
    long contentLength = -1;
    Enumeration<?> headerNames = httpRequest.getHeaderNames();
    while( headerNames.hasMoreElements() )
    {
      String hdr = ( String )headerNames.nextElement();
      String lhdr = hdr.toLowerCase();

      if( dontProxyHeaders.contains( lhdr ) )
        continue;
      if( connectionHeader != null && connectionHeader.indexOf( lhdr ) >= 0 )
        continue;

      if( "content-length".equals( lhdr ) )
        contentLength = request.getContentLength();

      Enumeration<?> vals = httpRequest.getHeaders( hdr );
      while( vals.hasMoreElements() )
      {
        String val = ( String )vals.nextElement();
        if( val != null )
        {
          method.setRequestHeader( lhdr, val );
          xForwardedFor |= "X-Forwarded-For".equalsIgnoreCase( hdr );
        }
      }
    }

    // Proxy headers
    method.setRequestHeader( "Via", "SoapUI Monitor" );
    if( !xForwardedFor )
      method.addRequestHeader( "X-Forwarded-For", request.getRemoteAddr() );

    if( method instanceof ExtendedPostMethod )
      ( ( ExtendedPostMethod )method ).setRequestEntity( new InputStreamRequestEntity( capture, request
          .getContentType() ) );

    HostConfiguration hostConfiguration = new HostConfiguration();

    StringBuffer url = new StringBuffer( "http://" );
    url.append( httpRequest.getServerName() );
    if( httpRequest.getServerPort() != 80 )
      url.append( ":" + httpRequest.getServerPort() );
    if( httpRequest.getServletPath() != null )
    {
      url.append( httpRequest.getServletPath() );
      method.setPath( httpRequest.getServletPath() );
      if( httpRequest.getQueryString() != null )
      {
        url.append( "?" + httpRequest.getQueryString() );
        method.setPath( httpRequest.getServletPath() + "?" + httpRequest.getQueryString() );
      }
    }
    hostConfiguration.setHost( new URI( url.toString(), true ) );

    // SoapUI.log("PROXY to:" + url);

    monitor.fireBeforeProxy( request, response, method, hostConfiguration );

    if( settings.getBoolean( LaunchForm.SSLTUNNEL_REUSESTATE ) )
    {
      if( httpState == null )
        httpState = new HttpState();
      HttpClientSupport.getHttpClient().executeMethod( hostConfiguration, method, httpState );
    }
    else
    {
      HttpClientSupport.getHttpClient().executeMethod( hostConfiguration, method );
    }

    // wait for transaction to end and store it.
    capturedData.stopCapture();

    capturedData.setRequest( capture.getCapturedData() );
    capturedData.setRawResponseBody( method.getResponseBody() );
    capturedData.setResponseHeader( method );
    capturedData.setRawRequestData( getRequestToBytes( request.toString(), method, capture ) );
    capturedData.setRawResponseData( getResponseToBytes( response.toString(), method,
        capturedData.getRawResponseBody() ) );
    capturedData.setResponseContent( new String( method.getDecompressedResponseBody() ) );

    monitor.fireAfterProxy( request, response, method, capturedData );

    if( !response.isCommitted() )
    {
      StringToStringsMap responseHeaders = capturedData.getResponseHeaders();
      // capturedData = null;

      // copy headers to response
      HttpServletResponse httpResponse = ( HttpServletResponse )response;
      for( String name : responseHeaders.keySet() )
      {
        for( String header : responseHeaders.get( name ) )
          httpResponse.addHeader( name, header );
      }

      IO.copy( new ByteArrayInputStream( capturedData.getRawResponseBody() ), httpResponse.getOutputStream() );
    }

    synchronized( this )
    {
      if( checkContentType( method ) )
      {
        monitor.addMessageExchange( capturedData );
      }
    }
  }

  private boolean checkContentType( ExtendedHttpMethod method )
  {
    String[] contentTypes = settings
        .getString( LaunchForm.SET_CONTENT_TYPES, SoapMonitorAction.defaultContentTypes() ).split( "," );
    List<String> contentTypelist = new ArrayList<String>();
    for( String ct : contentTypes )
    {
      contentTypelist.add( ct.trim().replace( "*", "" ) );
    }

    Header[] headers = method.getResponseHeaders( "Content-Type" );
    for( Header header : headers )
    {
      for( String contentType : contentTypelist )
      {
        if( header.getValue().indexOf( contentType ) > 0 )
        {
          return true;
        }
      }
    }
    return false;
  }

  private byte[] getResponseToBytes( String status, ExtendedHttpMethod postMethod, byte[] res )
  {
    String response = status.trim() + "\r\n";

    Header[] headers = postMethod.getResponseHeaders();
    for( Header header : headers )
    {
      response += header.toString().trim() + "\r\n";
    }
    response += "\r\n";

    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try
    {
      out.write( response.getBytes() );
      out.write( res );
    }
    catch( IOException e )
    {
      e.printStackTrace();
    }
    return out.toByteArray();
  }

  private byte[] getRequestToBytes( String footer, ExtendedHttpMethod postMethod, CaptureInputStream capture )
  {
    ByteArrayOutputStream out = new ByteArrayOutputStream();

    try
    {
      out.write( footer.trim().getBytes() );
      out.write( "\r\n\r\n".getBytes() );
      out.write( capture.getCapturedData() );
    }
    catch( IOException e )
    {
      e.printStackTrace();
    }

    return out.toByteArray();
  }

}
TOP

Related Classes of com.eviware.soapui.impl.wsdl.monitor.jettyproxy.ProxyServlet

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.