View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2008 eviware.com 
3    *
4    *  soapUI is free software; you can redistribute it and/or modify it under the 
5    *  terms of version 2.1 of the GNU Lesser General Public License as published by 
6    *  the Free Software Foundation.
7    *
8    *  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
9    *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
10   *  See the GNU Lesser General Public License for more details at gnu.org.
11   */
12  
13  package com.eviware.soapui.impl.wsdl.submit.transports.http;
14  
15  import com.eviware.soapui.SoapUI;
16  import com.eviware.soapui.impl.rest.RestRequest;
17  import com.eviware.soapui.impl.support.AbstractHttpRequest;
18  import com.eviware.soapui.impl.wsdl.WsdlProject;
19  import com.eviware.soapui.impl.wsdl.submit.RequestFilter;
20  import com.eviware.soapui.impl.wsdl.submit.transports.http.support.attachments.MimeMessageResponse;
21  import com.eviware.soapui.impl.wsdl.submit.transports.http.support.methods.ExtendedDeleteMethod;
22  import com.eviware.soapui.impl.wsdl.submit.transports.http.support.methods.ExtendedGetMethod;
23  import com.eviware.soapui.impl.wsdl.submit.transports.http.support.methods.ExtendedPostMethod;
24  import com.eviware.soapui.impl.wsdl.submit.transports.http.support.methods.ExtendedPutMethod;
25  import com.eviware.soapui.impl.wsdl.support.http.HttpClientSupport;
26  import com.eviware.soapui.impl.wsdl.support.http.SoapUIHostConfiguration;
27  import com.eviware.soapui.impl.wsdl.support.wss.WssCrypto;
28  import com.eviware.soapui.model.iface.Response;
29  import com.eviware.soapui.model.iface.SubmitContext;
30  import com.eviware.soapui.model.propertyexpansion.PropertyExpansionUtils;
31  import com.eviware.soapui.model.settings.Settings;
32  import com.eviware.soapui.model.support.ModelSupport;
33  import com.eviware.soapui.settings.HttpSettings;
34  import com.eviware.soapui.support.types.StringToStringMap;
35  import org.apache.commons.httpclient.*;
36  import org.apache.log4j.Logger;
37  
38  import java.net.InetAddress;
39  import java.util.ArrayList;
40  import java.util.List;
41  
42  /***
43   * HTTP transport that uses HttpClient to send/receive SOAP messages
44   * 
45   * @author Ole.Matzura
46   */
47  
48  public class HttpClientRequestTransport implements BaseHttpRequestTransport
49  {
50  	private List<RequestFilter> filters = new ArrayList<RequestFilter>();
51  	private final static Logger log = Logger.getLogger(HttpClientRequestTransport.class);
52  	
53  	public HttpClientRequestTransport()
54  	{
55  	}
56  	
57  	public void addRequestFilter(RequestFilter filter)
58  	{
59  		filters.add( filter );
60  	}
61  
62  	public void removeRequestFilter(RequestFilter filter)
63  	{
64  		filters.remove( filter );
65  	}
66  
67  	public void abortRequest( SubmitContext submitContext )
68  	{
69  		HttpMethodBase postMethod = (HttpMethodBase) submitContext.getProperty( HTTP_METHOD );
70  		if( postMethod != null )
71  			postMethod.abort();
72  	}
73  
74  	public Response sendRequest( SubmitContext submitContext, AbstractHttpRequest<?> httpRequest ) throws Exception
75  	{
76  		HttpClient httpClient = HttpClientSupport.getHttpClient();
77  		ExtendedHttpMethod httpMethod = createHttpMethod( httpRequest );
78  		boolean createdState = false;
79  		
80  		HttpState httpState = (HttpState) submitContext.getProperty(SubmitContext.HTTP_STATE_PROPERTY);
81  		if( httpState == null )
82  		{
83  		   httpState = new HttpState();
84  		   submitContext.setProperty( SubmitContext.HTTP_STATE_PROPERTY, httpState );
85  		   createdState = true;
86  		}
87  		
88  		HostConfiguration hostConfiguration = new HostConfiguration();
89  
90  		String localAddress = System.getProperty( "soapui.bind.address", httpRequest.getBindAddress() );
91  		if( localAddress == null || localAddress.trim().length() == 0 )
92  			localAddress = SoapUI.getSettings().getString( HttpSettings.BIND_ADDRESS, null );
93  		
94  		if( localAddress != null && localAddress.trim().length() > 0 )
95  		{
96  			try
97  			{
98  				hostConfiguration.setLocalAddress( InetAddress.getByName( localAddress ));
99  			}
100 			catch( Exception e )
101 			{
102 				SoapUI.logError( e );
103 			}
104 		}
105 
106       submitContext.removeProperty( RESPONSE );
107       submitContext.setProperty( HTTP_METHOD, httpMethod );
108 		submitContext.setProperty( POST_METHOD, httpMethod );
109 		submitContext.setProperty( HTTP_CLIENT, httpClient );
110 		submitContext.setProperty( REQUEST_CONTENT, httpRequest.getRequestContent() );
111 		submitContext.setProperty( HOST_CONFIGURATION, hostConfiguration );
112 		submitContext.setProperty( WSDL_REQUEST, httpRequest );
113 		
114 		for( RequestFilter filter : filters )
115 		{
116 			filter.filterRequest( submitContext, httpRequest );
117 		}
118 		
119 		try
120 		{			
121          Settings settings = httpRequest.getSettings();
122 
123 			//	custom http headers last so they can be overridden
124 			StringToStringMap headers = httpRequest.getRequestHeaders();
125 			for( String header : headers.keySet() )
126 			{
127 				String headerValue = headers.get( header );
128 				headerValue = PropertyExpansionUtils.expandProperties( submitContext, headerValue );
129 				httpMethod.setRequestHeader( header, headerValue );
130 			}
131 			
132 			//	do request
133 			WsdlProject project = (WsdlProject) ModelSupport.getModelItemProject( httpRequest );
134 			WssCrypto crypto = project.getWssContainer().getCryptoByName(
135                   PropertyExpansionUtils.expandProperties( submitContext, httpRequest.getSslKeystore()) );
136          
137 			if( crypto != null && WssCrypto.STATUS_OK.equals( crypto.getStatus() ) )
138 			{
139 				hostConfiguration.getParams().setParameter( SoapUIHostConfiguration.SOAPUI_SSL_CONFIG, 
140 							 crypto.getSource() + " " + crypto.getPassword() );
141 			}	
142 				
143 			// dump file?
144 			httpMethod.setDumpFile( 
145 					PropertyExpansionUtils.expandProperties( submitContext, httpRequest.getDumpFile() ));
146 
147 			//	include request time?
148 			if (settings.getBoolean(HttpSettings.INCLUDE_REQUEST_IN_TIME_TAKEN))
149 				httpMethod.initStartTime();
150 			
151 			// submit!
152 			httpClient.executeMethod(hostConfiguration, httpMethod, httpState);
153 			httpMethod.getTimeTaken();
154 			
155 			for( RequestFilter filter : filters )
156 			{
157 				filter.afterRequest( submitContext, httpRequest );
158 			}
159 			
160 			if( !submitContext.hasProperty(RESPONSE))
161 			{
162 				createDefaultResponse(submitContext, httpRequest, httpMethod);
163 			}
164 		}
165 		catch( Throwable t )
166 		{
167 			throw new Exception( t );
168 		}
169 		finally
170 		{
171 			if (httpMethod != null)
172 			{
173 				httpMethod.releaseConnection();
174 			}
175 			else log.error( "PostMethod is null");
176 			
177 			if( createdState )
178 				submitContext.setProperty( SubmitContext.HTTP_STATE_PROPERTY, null );
179 		}		
180 		
181 		return (Response) submitContext.getProperty(BaseHttpRequestTransport.RESPONSE);
182 	}
183 
184 	private void createDefaultResponse(SubmitContext submitContext, AbstractHttpRequest<?> httpRequest,
185 			ExtendedHttpMethod httpMethod)
186 	{
187 		String requestContent = (String) submitContext.getProperty(BaseHttpRequestTransport.REQUEST_CONTENT);
188 
189 		// check content-type for multiplart
190 		Header responseContentTypeHeader = httpMethod.getResponseHeader("Content-Type");
191 		Response response = null;
192 
193 		if ( responseContentTypeHeader != null	&& responseContentTypeHeader.getValue().toUpperCase().startsWith("MULTIPART"))
194 		{
195 			response = new MimeMessageResponse(httpRequest, httpMethod, requestContent, submitContext);
196 		}
197 		else
198 		{
199 			response = new SinglePartHttpResponse(httpRequest, httpMethod, requestContent, submitContext);
200 		}
201 
202 		submitContext.setProperty(BaseHttpRequestTransport.RESPONSE, response);
203 	}
204 
205 	private ExtendedHttpMethod createHttpMethod(AbstractHttpRequest<?> httpRequest)
206 	{
207 		if( httpRequest instanceof RestRequest )
208 		{
209 			RestRequest restRequest = (RestRequest) httpRequest;
210 			switch( restRequest.getMethod())
211 			{
212 				case GET : return new ExtendedGetMethod();
213 				case DELETE : return new ExtendedDeleteMethod();
214 				case PUT : return new ExtendedPutMethod();
215 			}
216 		}
217 		
218 		return new ExtendedPostMethod();
219 	}
220 
221 }