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 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
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 && headers[0].getElements().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 }