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