View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2009 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.wsdl.support.CompressionSupport;
17  import com.eviware.soapui.impl.wsdl.support.http.ConnectionWithSocket;
18  import com.eviware.soapui.impl.wsdl.support.http.HttpClientSupport;
19  import com.eviware.soapui.settings.HttpSettings;
20  import com.eviware.soapui.support.StringUtils;
21  import com.eviware.soapui.support.Tools;
22  import org.apache.commons.httpclient.*;
23  
24  import javax.net.ssl.SSLSocket;
25  import java.io.*;
26  import java.net.Socket;
27  
28  /***
29   * Extended PostMethod that supports limiting of response size and detailed
30   * timestamps
31   * 
32   * @author Ole.Matzura
33   */
34  
35  public final class HttpMethodSupport
36  {
37  	private long timeTaken;
38  	private long startTime;
39  	private long maxSize;
40  	private long responseReadTime;
41  
42  	private byte[] responseBody;
43  
44  	private SSLInfo sslInfo;
45  	private String dumpFile;
46  	private final HttpMethodBase httpMethod;
47  	private Throwable failureCause;
48  
49  	public HttpMethodSupport( HttpMethodBase httpMethod )
50  	{
51  		this.httpMethod = httpMethod;
52  	}
53  
54  	public String getDumpFile()
55  	{
56  		return dumpFile;
57  	}
58  
59  	public void setDumpFile( String dumpFile )
60  	{
61  		this.dumpFile = dumpFile;
62  	}
63  
64  	public void afterReadResponse( HttpState arg0, HttpConnection arg1 )
65  	{
66  		if( arg1 instanceof ConnectionWithSocket )
67  		{
68  			Socket socket = ( ( ConnectionWithSocket )arg1 ).getConnectionSocket();
69  			if( socket instanceof SSLSocket )
70  			{
71  				sslInfo = new SSLInfo( ( SSLSocket )socket );
72  			}
73  		}
74  	}
75  
76  	public long getMaxSize()
77  	{
78  		return maxSize;
79  	}
80  
81  	public void setMaxSize( long maxSize )
82  	{
83  		this.maxSize = maxSize;
84  	}
85  
86  	public void afterWriteRequest( HttpState arg0, HttpConnection arg1 )
87  	{
88  		if( startTime == 0 )
89  			startTime = System.nanoTime();
90  	}
91  
92  	public void initStartTime()
93  	{
94  		startTime = System.nanoTime();
95  	}
96  
97  	public long getTimeTaken()
98  	{
99  		if( timeTaken == 0 )
100 			timeTaken = ( System.nanoTime() - startTime ) / 1000000;
101 
102 		return timeTaken;
103 	}
104 
105 	public long getStartTime()
106 	{
107 		return startTime;
108 	}
109 
110 	public byte[] getResponseBody() throws IOException
111 	{
112 		if( responseBody != null )
113 			return responseBody;
114 
115 		long contentLength = httpMethod.getResponseContentLength();
116 		long now = System.nanoTime();
117 
118 		InputStream instream = httpMethod.getResponseBodyAsStream();
119 
120 		if( maxSize == 0 || ( contentLength >= 0 && contentLength <= maxSize ) )
121 		{
122 			ByteArrayOutputStream out = new ByteArrayOutputStream();
123 			if( instream != null )
124 				Tools.writeAll( out, instream );
125 
126 			responseReadTime = System.nanoTime() - now;
127 			responseBody = out.toByteArray();
128 
129 			try
130 			{
131 				if( StringUtils.hasContent( dumpFile ) )
132 				{
133 					Tools.writeAll( new FileOutputStream( dumpFile ), new ByteArrayInputStream( responseBody ) );
134 				}
135 			}
136 			catch( IOException e )
137 			{
138 				e.printStackTrace();
139 			}
140 
141 			if( !SoapUI.getSettings().getBoolean( HttpSettings.DISABLE_RESPONSE_DECOMPRESSION ) )
142 			{
143 				String compressionAlg = HttpClientSupport.getResponseCompressionType( httpMethod );
144 				if( compressionAlg != null )
145 				{
146 					try
147 					{
148 						responseBody = CompressionSupport.decompress( compressionAlg, responseBody );
149 					}
150 					catch( Exception e )
151 					{
152 						IOException ioe = new IOException( "Decompression of response failed" );
153 						ioe.initCause( e );
154 						throw ioe;
155 					}
156 				}
157 			}
158 		}
159 		else
160 		{
161 			try
162 			{
163 				if( StringUtils.hasContent( dumpFile ) && instream != null )
164 				{
165 					FileOutputStream fileOutputStream = new FileOutputStream( dumpFile );
166 					Tools.writeAll( fileOutputStream, instream );
167 					responseReadTime = System.nanoTime() - now;
168 					fileOutputStream.close();
169 					instream = new FileInputStream( dumpFile );
170 				}
171 			}
172 			catch( IOException e )
173 			{
174 				e.printStackTrace();
175 			}
176 
177 			ByteArrayOutputStream outstream = instream == null ? new ByteArrayOutputStream() : Tools.readAll( instream,
178 					maxSize );
179 
180 			if( responseReadTime == 0 )
181 				responseReadTime = System.nanoTime() - now;
182 
183 			responseBody = outstream.toByteArray();
184 		}
185 
186 		// convert to ms
187 		responseReadTime /= 1000000;
188 
189 		return responseBody;
190 	}
191 
192 	public SSLInfo getSSLInfo()
193 	{
194 		return sslInfo;
195 	}
196 
197 	public String getResponseContentType()
198 	{
199 		Header[] headers = httpMethod.getResponseHeaders( "Content-Type" );
200 		if( headers != null && headers.length > 0 )
201 		{
202 			return headers[0].getElements()[0].getName();
203 		}
204 
205 		return null;
206 	}
207 
208 	public long getResponseReadTime()
209 	{
210 		return responseReadTime;
211 	}
212 
213 	/***
214 	 * Handles charset specified in Content-Encoding headers
215 	 * 
216 	 * @return
217 	 */
218 
219 	public String getResponseCharset()
220 	{
221 		Header header = httpMethod.getResponseHeader( "Content-Type" );
222 		if( header != null )
223 		{
224 			for( HeaderElement headerElement : header.getElements() )
225 			{
226 				NameValuePair parameter = headerElement.getParameterByName( "charset" );
227 				if( parameter != null )
228 					return parameter.getValue();
229 			}
230 		}
231 
232 		Header contentEncodingHeader = httpMethod.getResponseHeader( "Content-Encoding" );
233 		if( contentEncodingHeader != null )
234 		{
235 			try
236 			{
237 				String value = contentEncodingHeader.getValue();
238 				if( CompressionSupport.getAvailableAlgorithm( value ) == null )
239 				{
240 					new String( "" ).getBytes( value );
241 					return value;
242 				}
243 			}
244 			catch( Exception e )
245 			{
246 			}
247 		}
248 
249 		return null;
250 	}
251 
252 	public Throwable getFailureCause()
253 	{
254 		return failureCause;
255 	}
256 
257 	public boolean isFailed()
258 	{
259 		return failureCause != null;
260 	}
261 
262 	public void setFailed( Throwable t )
263 	{
264 		this.failureCause = t;
265 	}
266 
267 	public boolean hasResponse()
268 	{
269 		return responseBody != null;
270 	}
271 }