1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.eviware.soapui.impl.wsdl.monitor;
18
19 import java.io.InputStream;
20 import java.io.OutputStream;
21 import java.io.PrintWriter;
22 import java.io.StringWriter;
23 import java.net.Socket;
24 import java.net.URL;
25
26 import com.eviware.soapui.SoapUI;
27
28 /***
29 * a connection listens to a single current connection
30 */
31 class Connection extends Thread
32 {
33
34 private SoapMonitor monitor;
35 private boolean active;
36
37 private Socket inSocket = null;
38 private Socket outSocket = null;
39
40 private SocketRR rr1 = null;
41 private SocketRR rr2 = null;
42
43 private InputStream inputStream = null;
44
45 private String httpProxyHost = null;
46 private int httpProxyPort = 80;
47 private SlowLinkSimulator slowLink;
48
49 /***
50 * Constructor Connection
51 *
52 * @param l
53 */
54 public Connection( String name, SoapMonitor l, SlowLinkSimulator slowLink )
55 {
56 super( name );
57 monitor = l;
58 httpProxyHost = l.getHttpProxyHost();
59 httpProxyPort = l.getHttpProxyPort();
60 this.slowLink = slowLink;
61 }
62
63 /***
64 * Constructor Connection
65 *
66 * @param l
67 * @param s
68 */
69 public Connection( String name, SoapMonitor l, Socket s, SlowLinkSimulator slowLink )
70 {
71 this( name, l, slowLink );
72 inSocket = s;
73 start();
74 }
75
76 /***
77 * Constructor Connection
78 *
79 * @param l
80 * @param in
81 */
82 public Connection( String name, SoapMonitor l, InputStream in, SlowLinkSimulator slowLink )
83 {
84 this( name, l, slowLink );
85 inputStream = in;
86 start();
87 }
88
89 /***
90 * Method run
91 */
92 public void run()
93 {
94 setContextClassLoader( SoapUI.getSoapUICore().getExtensionClassLoader() );
95
96 try
97 {
98 active = true;
99 httpProxyHost = System.getProperty( "http.proxyHost" );
100 if( ( httpProxyHost != null ) && httpProxyHost.equals( "" ) )
101 {
102 httpProxyHost = null;
103 }
104 if( httpProxyHost != null )
105 {
106 String tmp = System.getProperty( "http.proxyPort" );
107 if( ( tmp != null ) && tmp.equals( "" ) )
108 {
109 tmp = null;
110 }
111 if( tmp == null )
112 {
113 httpProxyPort = 80;
114 }
115 else
116 {
117 httpProxyPort = Integer.parseInt( tmp );
118 }
119 }
120
121 String fromHost = "";
122 if( inSocket != null )
123 {
124 fromHost = ( inSocket.getInetAddress() ).getHostName();
125 }
126
127 String targetHost = monitor.getTargetHost();
128 int targetPort = monitor.getTargetPort();
129 int listenPort = monitor.getLocalPort();
130 InputStream tmpIn1 = inputStream;
131 OutputStream tmpOut1 = null;
132 InputStream tmpIn2 = null;
133 OutputStream tmpOut2 = null;
134 if( tmpIn1 == null )
135 {
136 tmpIn1 = inSocket.getInputStream();
137 }
138 if( inSocket != null )
139 {
140 tmpOut1 = inSocket.getOutputStream();
141 }
142
143 CaptureInputStream requestCapture = new CaptureInputStream( tmpIn1 );
144 tmpIn1 = requestCapture;
145
146 String bufferedData = null;
147 StringBuffer buf = null;
148
149 TcpMonWsdlMonitorMessageExchange exchange = new TcpMonWsdlMonitorMessageExchange( monitor.getProject() );
150 exchange.setRequestHost( fromHost );
151
152
153
154 boolean isProxy = true;
155 URL targetUrl = isProxy ? null : new URL( monitor.getTargetEndpoint() );
156
157 if( isProxy || ( httpProxyHost != null ) )
158 {
159
160 byte[] b = new byte[1];
161 buf = new StringBuffer();
162 String s;
163 for( ;; )
164 {
165 int len;
166 len = tmpIn1.read( b, 0, 1 );
167 if( len == -1 )
168 {
169 break;
170 }
171 s = new String( b );
172 buf.append( s );
173 if( b[0] != '\n' )
174 {
175 continue;
176 }
177 break;
178 }
179 bufferedData = buf.toString();
180 if( bufferedData.startsWith( "GET " ) || bufferedData.startsWith( "POST " )
181 || bufferedData.startsWith( "PUT " ) || bufferedData.startsWith( "DELETE " ) )
182 {
183 int start, end;
184
185 start = bufferedData.indexOf( ' ' ) + 1;
186 while( bufferedData.charAt( start ) == ' ' )
187 {
188 start++ ;
189 }
190 end = bufferedData.indexOf( ' ', start );
191 String urlString = bufferedData.substring( start, end );
192 if( urlString.charAt( 0 ) == '/' )
193 {
194 urlString = urlString.substring( 1 );
195 }
196 if( isProxy )
197 {
198 targetUrl = new URL( urlString );
199 targetHost = targetUrl.getHost();
200 targetPort = targetUrl.getPort();
201 if( targetPort == -1 )
202 {
203 targetPort = 80;
204 }
205
206 bufferedData = bufferedData.substring( 0, start ) + targetUrl.getFile()
207 + bufferedData.substring( end );
208 bufferedData += "Connection: close\r\n";
209 }
210 else
211 {
212 targetUrl = new URL( "http://" + targetHost + ":" + targetPort + "/" + urlString );
213 bufferedData = bufferedData.substring( 0, start ) + targetUrl.toExternalForm()
214 + bufferedData.substring( end );
215 targetHost = httpProxyHost;
216 targetPort = httpProxyPort;
217 }
218 }
219 }
220 else
221 {
222
223
224
225 byte[] b1 = new byte[1];
226 buf = new StringBuffer();
227 String s1;
228 String lastLine = null;
229 for( ;; )
230 {
231 int len;
232 len = tmpIn1.read( b1, 0, 1 );
233 if( len == -1 )
234 {
235 break;
236 }
237 s1 = new String( b1 );
238 buf.append( s1 );
239 if( b1[0] != '\n' )
240 {
241 continue;
242 }
243
244
245 String line = buf.toString();
246 buf.setLength( 0 );
247
248
249 if( line.startsWith( "Host: " ) )
250 {
251
252 String newHost = "Host: " + targetHost + ":" + listenPort + "\r\n";
253 bufferedData = bufferedData.concat( newHost );
254 bufferedData += "Connection: close\r\n";
255 break;
256 }
257
258
259 if( line.equals( "\r\n" ) || ( "\n".equals( lastLine ) && line.equals( "\n" ) ) )
260 {
261 bufferedData += "Connection: close" + line;
262 break;
263 }
264
265
266 if( bufferedData == null )
267 {
268 bufferedData = line;
269 }
270 else
271 {
272 bufferedData = bufferedData.concat( line );
273 }
274
275 lastLine = line;
276 }
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292 }
293 if( targetPort == -1 )
294 {
295 targetPort = 80;
296 }
297
298 exchange.setTargetUrl( targetUrl );
299
300 outSocket = new Socket( targetHost, targetPort );
301 tmpIn2 = outSocket.getInputStream();
302
303 CaptureInputStream responseCapture = new CaptureInputStream( tmpIn2 );
304 tmpIn2 = responseCapture;
305
306 tmpOut2 = outSocket.getOutputStream();
307 if( bufferedData != null )
308 {
309 byte[] b = bufferedData.getBytes();
310 tmpOut2.write( b );
311 slowLink.pump( b.length );
312 }
313
314
315 rr1 = new SocketRR( getName() + " to endpoint", this, inSocket, tmpIn1, outSocket, tmpOut2, slowLink );
316
317
318 SlowLinkSimulator responseLink = new SlowLinkSimulator( slowLink );
319
320
321 rr2 = new SocketRR( getName() + " from endpoint", this, outSocket, tmpIn2, inSocket, tmpOut1, responseLink );
322
323 while( ( rr1 != null ) || ( rr2 != null ) )
324 {
325 if( rr2 != null )
326 {
327 exchange.setTimeTaken( rr2.getElapsed() );
328 }
329
330
331
332
333
334
335 if( ( null != rr1 ) && rr1.isDone() )
336 {
337 rr1 = null;
338 }
339
340 if( ( null != rr2 ) && rr2.isDone() )
341 {
342 rr2 = null;
343 }
344
345 synchronized( this )
346 {
347 this.wait( 10 );
348
349 }
350 }
351
352 active = false;
353 exchange.finish( requestCapture.getCapturedData(), responseCapture.getCapturedData() );
354 monitor.addMessageExchange( exchange );
355 }
356 catch( Exception e )
357 {
358 StringWriter st = new StringWriter();
359 PrintWriter wr = new PrintWriter( st );
360 e.printStackTrace( wr );
361 wr.close();
362 halt();
363 }
364 }
365
366 protected boolean isActive()
367 {
368 return active;
369 }
370
371 /***
372 * Method wakeUp
373 */
374 synchronized void wakeUp()
375 {
376 this.notifyAll();
377 }
378
379 /***
380 * Method halt
381 */
382 public void halt()
383 {
384 try
385 {
386 if( rr1 != null )
387 {
388 rr1.halt();
389 }
390 if( rr2 != null )
391 {
392 rr2.halt();
393 }
394 if( inSocket != null )
395 {
396 inSocket.close();
397 }
398 inSocket = null;
399 if( outSocket != null )
400 {
401 outSocket.close();
402 }
403 outSocket = null;
404 }
405 catch( Exception e )
406 {
407 SoapUI.log.info( "Error halting connection: " + e.toString() );
408 }
409 }
410
411 /***
412 * Method remove
413 */
414 public void remove()
415 {
416 try
417 {
418 halt();
419 }
420 catch( Exception e )
421 {
422 e.printStackTrace();
423 }
424 }
425 }