~ubuntu-branches/ubuntu/wily/libjboss-remoting-java/wily

« back to all changes in this revision

Viewing changes to src/main/org/jboss/remoting/transport/http/HTTPClientInvoker.java

  • Committer: Package Import Robot
  • Author(s): Torsten Werner
  • Date: 2011-09-09 14:01:03 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: package-import@ubuntu.com-20110909140103-hqokx61534tas9rg
Tags: 2.5.3.SP1-1
* Newer but not newest upstream release. Do not build samples.
* Change debian/watch to upstream's svn repo.
* Add patch to fix compile error caused by tomcat update.
  (Closes: #628303)
* Switch to source format 3.0.
* Switch to debhelper level 7.
* Remove useless Depends.
* Update Standards-Version: 3.9.2.
* Update README.source.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
* JBoss, Home of Professional Open Source
 
3
* Copyright 2005, JBoss Inc., and individual contributors as indicated
 
4
* by the @authors tag. See the copyright.txt in the distribution for a
 
5
* full listing of individual contributors.
 
6
*
 
7
* This is free software; you can redistribute it and/or modify it
 
8
* under the terms of the GNU Lesser General Public License as
 
9
* published by the Free Software Foundation; either version 2.1 of
 
10
* the License, or (at your option) any later version.
 
11
*
 
12
* This software is distributed in the hope that it will be useful,
 
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 
15
* Lesser General Public License for more details.
 
16
*
 
17
* You should have received a copy of the GNU Lesser General Public
 
18
* License along with this software; if not, write to the Free
 
19
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 
20
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 
21
*/
 
22
 
 
23
package org.jboss.remoting.transport.http;
 
24
 
 
25
import org.jboss.logging.Logger;
 
26
import org.jboss.remoting.CannotConnectException;
 
27
import org.jboss.remoting.ConnectionFailedException;
 
28
import org.jboss.remoting.Home;
 
29
import org.jboss.remoting.InvocationRequest;
 
30
import org.jboss.remoting.InvocationResponse;
 
31
import org.jboss.remoting.InvokerLocator;
 
32
import org.jboss.remoting.RemoteClientInvoker;
 
33
import org.jboss.remoting.ServerInvoker;
 
34
import org.jboss.remoting.Version;
 
35
import org.jboss.remoting.marshal.MarshalFactory;
 
36
import org.jboss.remoting.marshal.Marshaller;
 
37
import org.jboss.remoting.marshal.UnMarshaller;
 
38
import org.jboss.remoting.marshal.VersionedMarshaller;
 
39
import org.jboss.remoting.marshal.VersionedUnMarshaller;
 
40
import org.jboss.remoting.marshal.compress.CompressingUnMarshaller;
 
41
import org.jboss.remoting.marshal.http.HTTPMarshaller;
 
42
import org.jboss.remoting.marshal.http.HTTPUnMarshaller;
 
43
import org.jboss.remoting.marshal.serializable.SerializableUnMarshaller;
 
44
import org.jboss.remoting.serialization.ClassLoaderUtility;
 
45
import org.jboss.remoting.transport.web.WebUtil;
 
46
import org.jboss.remoting.util.SecurityUtility;
 
47
import org.jboss.util.Base64;
 
48
import org.jboss.util.threadpool.BasicThreadPool;
 
49
import org.jboss.util.threadpool.BlockingMode;
 
50
import org.jboss.util.threadpool.RunnableTaskWrapper;
 
51
import org.jboss.util.threadpool.Task;
 
52
import org.jboss.util.threadpool.ThreadPool;
 
53
 
 
54
import java.io.EOFException;
 
55
import java.io.IOException;
 
56
import java.io.InputStream;
 
57
import java.io.OutputStream;
 
58
import java.lang.reflect.Constructor;
 
59
import java.lang.reflect.Field;
 
60
import java.lang.reflect.InvocationTargetException;
 
61
import java.lang.reflect.Method;
 
62
import java.net.HttpURLConnection;
 
63
import java.net.InetSocketAddress;
 
64
import java.net.SocketAddress;
 
65
import java.net.SocketTimeoutException;
 
66
import java.net.URL;
 
67
import java.security.AccessController;
 
68
import java.security.PrivilegedActionException;
 
69
import java.security.PrivilegedExceptionAction;
 
70
import java.util.HashMap;
 
71
import java.util.Iterator;
 
72
import java.util.List;
 
73
import java.util.Map;
 
74
import java.util.Set;
 
75
 
 
76
/**
 
77
 * HTTP client invoker.  Used for making http requests on http/servlet invoker.
 
78
 *
 
79
 * @author <a href="mailto:tom@jboss.org">Tom Elrod</a>
 
80
 */
 
81
public class HTTPClientInvoker extends RemoteClientInvoker
 
82
{
 
83
   /**
 
84
    * Key for the configuration map that determines the threadpool size for 
 
85
    * simulated timeouts when using jdk 1.4.
 
86
    */
 
87
   public static final String MAX_NUM_TIMEOUT_THREADS = "maxNumTimeoutThreads";
 
88
 
 
89
   /**
 
90
    * Key for the configuration map that determines the queue size for simulated
 
91
    * timeout threadpool when using jdk 1.4.
 
92
    */
 
93
   public static final String MAX_TIMEOUT_QUEUE_SIZE = "maxTimeoutQueueSize";
 
94
   
 
95
   /**
 
96
    * Specifies the default number of work threads in the thread pool for 
 
97
    * simulating timeouts when using jdk 1.4.
 
98
    */
 
99
   public static final int MAX_NUM_TIMEOUT_THREADS_DEFAULT = 10;
 
100
   
 
101
   /**
 
102
    * Specifies the number of attempts to get a functioning connection
 
103
    * to the http server.  Defaults to 1.
 
104
    */
 
105
   public static final String NUMBER_OF_CALL_ATTEMPTS = "numberOfCallAttempts";
 
106
   
 
107
   /*
 
108
    * Specifies whether useHttpURLConnection(), upon receiving a null InputStream or ErrorStream,
 
109
    * should call the UnMarshaller.
 
110
    */
 
111
   public static final String UNMARSHAL_NULL_STREAM = "unmarshalNullStream";
 
112
   
 
113
   protected static final Logger log = Logger.getLogger(HTTPClientInvoker.class);
 
114
   
 
115
   protected boolean noThrowOnError;
 
116
   protected int numberOfCallAttempts = 1;
 
117
   protected boolean unmarshalNullStream = true;
 
118
   protected boolean useRemotingContentType = false;
 
119
   
 
120
   private Object timeoutThreadPoolLock = new Object();
 
121
   private ThreadPool timeoutThreadPool;
 
122
 
 
123
   public HTTPClientInvoker(InvokerLocator locator)
 
124
   {
 
125
      super(locator);
 
126
      configureParameters();
 
127
   }
 
128
 
 
129
   public HTTPClientInvoker(InvokerLocator locator, Map configuration)
 
130
   {
 
131
      super(locator, configuration);
 
132
      configureParameters();
 
133
   }
 
134
 
 
135
   /**
 
136
    * @param sessionId
 
137
    * @param invocation
 
138
    * @param marshaller
 
139
    * @return
 
140
    * @throws java.io.IOException
 
141
    * @throws org.jboss.remoting.ConnectionFailedException
 
142
    *
 
143
    */
 
144
   protected Object transport(String sessionId, final Object invocation, Map metadata,
 
145
                              final Marshaller marshaller, final UnMarshaller unmarshaller)
 
146
         throws IOException, ConnectionFailedException
 
147
   {
 
148
      // need to check the url and make sure it compatible protocol
 
149
      final String validatedUrl = validateURL(getLocator().getLocatorURI());
 
150
 
 
151
      if (metadata == null)
 
152
      {
 
153
         metadata = new HashMap();
 
154
      }
 
155
 
 
156
      final HttpURLConnection conn = createURLConnection(validatedUrl, metadata);
 
157
      
 
158
      int simulatedTimeout = getSimulatedTimeout(configuration, metadata, conn);
 
159
      
 
160
      if (simulatedTimeout <= 0)
 
161
      {
 
162
         return makeInvocation(conn, validatedUrl, invocation, metadata, marshaller, unmarshaller, true);
 
163
      }
 
164
      else
 
165
      {
 
166
         if (log.isTraceEnabled()) log.trace("using simulated timeout: " + simulatedTimeout);
 
167
         class Holder {public Object value;}
 
168
         final Holder resultHolder = new Holder();
 
169
         final Map finalMetadata = metadata;
 
170
         
 
171
         Runnable r = new Runnable()
 
172
         {
 
173
            public void run()
 
174
            {
 
175
               try
 
176
               {
 
177
                  resultHolder.value = useHttpURLConnection(conn, invocation, finalMetadata, marshaller, unmarshaller);
 
178
                  if (log.isTraceEnabled()) log.trace("result: " + resultHolder.value);
 
179
               }
 
180
               catch (Exception e)
 
181
               {
 
182
                  resultHolder.value = e;
 
183
                  if (log.isTraceEnabled()) log.trace("exception: " + e); 
 
184
               }
 
185
            }
 
186
         };
 
187
         
 
188
         // BasicThreadPool timeout mechanism depends on the interrupted status of
 
189
         // the running thread.
 
190
         Thread.interrupted();
 
191
         
 
192
         ThreadPool pool = getTimeoutThreadPool();
 
193
         WaitingTaskWrapper wrapper = new WaitingTaskWrapper(r, simulatedTimeout);
 
194
         if (log.isTraceEnabled()) log.trace("starting task in thread pool");
 
195
         pool.runTaskWrapper(wrapper);
 
196
         if (log.isTraceEnabled()) log.trace("task finished in thread pool");
 
197
         
 
198
         Object result = resultHolder.value;
 
199
         if (result == null)
 
200
         {
 
201
            if (log.isDebugEnabled()) log.debug("invocation timed out");
 
202
            Exception cause = new SocketTimeoutException("timed out");
 
203
            throw new CannotConnectException("Can not connect http client invoker.", cause);
 
204
         }
 
205
         else if (result instanceof IOException)
 
206
         {
 
207
            throw (IOException) result;
 
208
         }
 
209
         else if (result instanceof RuntimeException)
 
210
         {
 
211
            throw (RuntimeException) result;
 
212
         }
 
213
         else
 
214
         {
 
215
            if (log.isTraceEnabled()) log.trace("returning result: " + result);
 
216
            return result;
 
217
         }
 
218
      }
 
219
   }
 
220
 
 
221
   protected Object makeInvocation(HttpURLConnection conn, String url, Object invocation,
 
222
                                   Map metadata, Marshaller marshaller, UnMarshaller unmarshaller,
 
223
                                   boolean setTimeout)
 
224
   throws IOException
 
225
   {
 
226
      Throwable savedException = null;
 
227
      
 
228
      for (int i = 0; i < numberOfCallAttempts; i++)
 
229
      {
 
230
         try
 
231
         {
 
232
            Object o = useHttpURLConnection(conn, invocation, metadata, marshaller, unmarshaller);
 
233
            if (log.isTraceEnabled()) log.trace("result: " + o);
 
234
            return o;
 
235
         }
 
236
         catch (CannotConnectException e)
 
237
         {
 
238
            savedException = e.getCause();
 
239
            String suffix = (i < (numberOfCallAttempts - 1) ? ": will retry" : "");
 
240
            log.debug("Cannot connect on attempt " + (i + 1) + suffix);
 
241
            conn = createURLConnection(url, metadata);
 
242
            if (setTimeout)
 
243
            {
 
244
               getSimulatedTimeout(configuration, metadata, conn);
 
245
            }
 
246
         }
 
247
      }
 
248
      
 
249
      String msg = "Can not connect http client invoker after " + numberOfCallAttempts + " attempt(s)";
 
250
      throw new CannotConnectException(msg, savedException);
 
251
   }
 
252
   
 
253
   
 
254
   private Object useHttpURLConnection(HttpURLConnection conn, Object invocation, Map metadata,
 
255
                                       Marshaller marshaller, UnMarshaller unmarshaller) throws WebServerError
 
256
   {
 
257
      Object result = null;
 
258
      int responseCode = -1;
 
259
 
 
260
      try
 
261
      {
 
262
         setChunked(configuration, conn);
 
263
 
 
264
         // check to see if basic auth required
 
265
         String basicAuth = getBasicAuth(metadata);
 
266
         if (basicAuth != null)
 
267
         {
 
268
            conn.setRequestProperty("Authorization", basicAuth);
 
269
         }
 
270
 
 
271
         // check for ping request and process it now and return
 
272
         result = checkForLeasePing(conn,  invocation, metadata);
 
273
         if(result != null)
 
274
         {
 
275
            return result;
 
276
         }
 
277
 
 
278
 
 
279
         // Get the request method type
 
280
         boolean sendingData = true;
 
281
         String type = "POST";
 
282
         if (metadata != null)
 
283
         {
 
284
            type = (String) metadata.get("TYPE");
 
285
            if (type != null)
 
286
            {
 
287
               if ((!type.equals("POST") && !type.equals("PUT")))
 
288
               {
 
289
                  sendingData = false;
 
290
               }
 
291
            }
 
292
            else
 
293
            {
 
294
               type = "POST";
 
295
            }
 
296
         }
 
297
         else // need to check for content type and set metadata
 
298
         {
 
299
            metadata = new HashMap();
 
300
            Map header = new HashMap();
 
301
            header.put(HTTPMetadataConstants.CONTENTTYPE, WebUtil.getContentType(invocation));
 
302
            metadata.put("HEADER", header);
 
303
         }
 
304
         // Set request headers
 
305
         Map header = (Map) metadata.get("HEADER");
 
306
         if (header != null)
 
307
         {
 
308
            Set keys = header.keySet();
 
309
            Iterator itr = keys.iterator();
 
310
            while (itr.hasNext())
 
311
            {
 
312
               String key = (String) itr.next();
 
313
               String value = (String) header.get(key);
 
314
               log.debug("Setting request header with " + key + " : " + value);
 
315
               conn.setRequestProperty(key, value);
 
316
            }
 
317
         }
 
318
         else
 
319
         {
 
320
            conn.setRequestProperty(HTTPMetadataConstants.CONTENTTYPE, WebUtil.getContentType(invocation));
 
321
         }
 
322
         
 
323
         metadata.put(HTTPMetadataConstants.USE_REMOTING_CONTENT_TYPE, Boolean.toString(useRemotingContentType));
 
324
 
 
325
         // set the remoting version
 
326
         conn.setRequestProperty(HTTPMetadataConstants.REMOTING_VERSION_HEADER, new Integer(getVersion()).toString());
 
327
         // set the user agent
 
328
         conn.setRequestProperty(HTTPMetadataConstants.REMOTING_USER_AGENT, "JBossRemoting - " + Version.VERSION);
 
329
 
 
330
         if (sendingData)
 
331
         {
 
332
            //POST or PUT
 
333
            conn.setDoOutput(true);
 
334
            conn.setDoInput(true);
 
335
            conn.setRequestMethod(type);
 
336
 
 
337
            if (invocation instanceof String)
 
338
            {
 
339
               conn.setRequestProperty(HTTPMetadataConstants.REMOTING_CONTENT_TYPE, HTTPMetadataConstants.REMOTING_CONTENT_TYPE_STRING);
 
340
            }
 
341
            else
 
342
            {
 
343
               conn.setRequestProperty(HTTPMetadataConstants.REMOTING_CONTENT_TYPE, HTTPMetadataConstants.REMOTING_CONTENT_TYPE_NON_STRING);       
 
344
            }
 
345
            
 
346
            OutputStream stream = getOutputStream(conn);        
 
347
            if (marshaller instanceof VersionedMarshaller)
 
348
               ((VersionedMarshaller) marshaller).write(invocation, stream, getVersion());
 
349
            else
 
350
               marshaller.write(invocation, stream);
 
351
            responseCode = getResponseCode(conn);
 
352
 
 
353
            Map headers = conn.getHeaderFields();
 
354
            if (metadata == null)
 
355
            {
 
356
               metadata = new HashMap();
 
357
            }
 
358
 
 
359
            // sometimes I get headers with "null" keys (I don't know who's fault is it), so I need
 
360
            // to clean the header map, unless I want to get an NPE thrown by metadata.putAll()
 
361
            if (headers != null)
 
362
            {
 
363
               for(Iterator i = headers.entrySet().iterator(); i.hasNext(); )
 
364
               {
 
365
                  Map.Entry e = (Map.Entry)i.next();
 
366
                  if (e.getKey() != null)
 
367
                  {
 
368
                     metadata.put(e.getKey(), e.getValue());
 
369
                  }
 
370
               }
 
371
            }
 
372
 
 
373
            String responseMessage = getResponseMessage(conn);
 
374
            metadata.put(HTTPMetadataConstants.RESPONSE_CODE_MESSAGE, responseMessage);
 
375
            metadata.put(HTTPMetadataConstants.RESPONSE_CODE, new Integer(responseCode));
 
376
            metadata.put(HTTPMetadataConstants.RESPONSE_HEADERS, headers);
 
377
 
 
378
            InputStream is = (responseCode < 400) ? conn.getInputStream() : conn.getErrorStream();
 
379
            if (is != null || unmarshalNullStream)
 
380
            {
 
381
               result = readResponse(metadata, headers, unmarshaller, is);
 
382
            }
 
383
         }
 
384
         else
 
385
         {
 
386
            conn.setDoOutput(false);
 
387
            conn.setDoInput(true);
 
388
            conn.setRequestMethod(type);
 
389
 
 
390
            connect(conn);
 
391
 
 
392
            InputStream is = (getResponseCode(conn) < 400) ? conn.getInputStream() : conn.getErrorStream();
 
393
            Map headers = conn.getHeaderFields();
 
394
 
 
395
            if (is != null || unmarshalNullStream)
 
396
            {
 
397
               result = readResponse(null, headers, unmarshaller, is);
 
398
            }
 
399
            
 
400
            if (metadata == null)
 
401
            {
 
402
               metadata = new HashMap();
 
403
            }
 
404
            metadata.putAll(headers);
 
405
            String responseMessage = getResponseMessage(conn);
 
406
            metadata.put(HTTPMetadataConstants.RESPONSE_CODE_MESSAGE, responseMessage);
 
407
            responseCode = getResponseCode(conn);
 
408
            metadata.put(HTTPMetadataConstants.RESPONSE_CODE, new Integer(responseCode));
 
409
            metadata.put(HTTPMetadataConstants.RESPONSE_HEADERS, conn.getHeaderFields());
 
410
         }
 
411
      }
 
412
      catch (Exception e)
 
413
      {
 
414
         String message = "Can not connect http client invoker.";
 
415
         if (e.getMessage() != null)
 
416
            message += " " + e.getMessage() + ".";
 
417
 
 
418
         try
 
419
         {
 
420
            String responseMessage = getResponseMessage(conn);
 
421
            int code = getResponseCode(conn);
 
422
            message += " Response: " + responseMessage + "/" + code + ".";
 
423
         }
 
424
         catch (IOException e1)
 
425
         {
 
426
            log.debug("Unable to retrieve response message", e1);
 
427
         }
 
428
         throw new CannotConnectException(message, e);
 
429
      }
 
430
 
 
431
      // now check for error response and throw exception unless configured to not do so
 
432
      if(responseCode >= 400)
 
433
      {
 
434
         boolean doNotThrow = noThrowOnError;
 
435
         if(metadata != null)
 
436
         {
 
437
            Object configObj = metadata.get(HTTPMetadataConstants.NO_THROW_ON_ERROR);
 
438
            if(configObj != null && configObj instanceof String)
 
439
            {
 
440
               doNotThrow = Boolean.valueOf((String)configObj).booleanValue();
 
441
            }
 
442
         }
 
443
 
 
444
         if(doNotThrow)
 
445
         {
 
446
            if(result instanceof String)
 
447
            {
 
448
               // this is a html error page displayed by web server, need to conver to exception
 
449
               WebServerError ex = new WebServerError((String)result);
 
450
               return ex;
 
451
            }
 
452
            else if (result instanceof InvocationResponse)
 
453
            {
 
454
               return ((InvocationResponse) result).getResult();
 
455
            }
 
456
            else
 
457
            {
 
458
               return result;
 
459
            }
 
460
         }
 
461
 
 
462
 
 
463
         // if got here, wasn't configured to not throw exception, so will throw it.
 
464
 
 
465
         // In this case, MicroRemoteClientInvoker will throw the exception carried by
 
466
         // the InvocationResponse.
 
467
         if (result instanceof InvocationResponse)
 
468
            return result;
 
469
 
 
470
         // Otherwise, create a new WebServerError.
 
471
         if(result instanceof String)
 
472
         {
 
473
            WebServerError ex = new WebServerError((String)result);
 
474
            throw ex;
 
475
         }
 
476
         else
 
477
         {
 
478
            WebServerError ex = new WebServerError("Error received when calling on web server.  Error returned was " + responseCode);
 
479
            throw ex;
 
480
         }
 
481
 
 
482
      }
 
483
 
 
484
      return result;
 
485
   }
 
486
 
 
487
   private Object checkForLeasePing(HttpURLConnection conn, Object invocation, Map metadata) throws IOException
 
488
   {
 
489
      InvocationResponse response = null;
 
490
      boolean shouldLease = false;
 
491
      long leasePeriod = -1;
 
492
 
 
493
      if(invocation != null && invocation instanceof InvocationRequest)
 
494
      {
 
495
         InvocationRequest request = (InvocationRequest)invocation;
 
496
 
 
497
         Object payload = request.getParameter();
 
498
         // although a bit of a hack, this will determin if first time ping called by client.
 
499
         if(payload != null && payload instanceof String && "$PING$".equalsIgnoreCase((String)payload) && request.getReturnPayload() != null)
 
500
         {
 
501
            try
 
502
            {
 
503
               // now know is a ping request, so convert to be a HEAD method call
 
504
               conn.setDoOutput(false);
 
505
               conn.setDoInput(true);
 
506
               conn.setRequestMethod("HEAD");
 
507
               // set the remoting version
 
508
               conn.setRequestProperty(HTTPMetadataConstants.REMOTING_VERSION_HEADER, new Integer(getVersion()).toString());
 
509
               // set the user agent
 
510
               conn.setRequestProperty(HTTPMetadataConstants.REMOTING_USER_AGENT, "JBossRemoting - " + Version.VERSION);
 
511
               conn.setRequestProperty(HTTPMetadataConstants.REMOTING_LEASE_QUERY, "true");
 
512
               conn.setRequestProperty("sessionId", request.getSessionId());
 
513
               connect(conn);
 
514
 
 
515
               //InputStream is = (conn.getResponseCode() < 400) ? conn.getInputStream() : conn.getErrorStream();
 
516
               Map headers = conn.getHeaderFields();
 
517
 
 
518
               if(headers != null)
 
519
               {
 
520
                  Object leasingEnabled = headers.get("LEASING_ENABLED");
 
521
                  if(leasingEnabled != null && leasingEnabled instanceof List)
 
522
                  {
 
523
                     shouldLease = new Boolean((String)((List)leasingEnabled).get(0)).booleanValue();
 
524
                  }
 
525
                  Object leasingPeriod = headers.get("LEASE_PERIOD");
 
526
                  if(leasingPeriod != null && leasingPeriod instanceof List)
 
527
                  {
 
528
                     leasePeriod = new Long((String)((List)leasingPeriod).get(0)).longValue();
 
529
                  }
 
530
               }
 
531
            }
 
532
            catch (IOException e)
 
533
            {
 
534
               log.error("Error checking server for lease information.", e);
 
535
            }
 
536
 
 
537
            Map p = new HashMap();
 
538
            p.put("clientLeasePeriod", new Long(leasePeriod));
 
539
            InvocationResponse innterResponse = new InvocationResponse(null, new Boolean(shouldLease), false, p);
 
540
            response = new InvocationResponse(null, innterResponse, false, null);
 
541
 
 
542
         }
 
543
      }
 
544
 
 
545
      return response;
 
546
   }
 
547
 
 
548
   private Object readResponse(Map metadata, Map headers, UnMarshaller unmarshaller, InputStream is)
 
549
         throws  ClassNotFoundException, IOException
 
550
   {
 
551
      Object result = null;
 
552
      String encoding = null;
 
553
      Object ceObj = headers.get("Content-Encoding");
 
554
      if (ceObj != null)
 
555
      {
 
556
         if (ceObj instanceof List)
 
557
         {
 
558
            encoding = (String) ((List) ceObj).get(0);
 
559
         }
 
560
      }
 
561
      if (encoding != null && encoding.indexOf("gzip") >= 0)
 
562
      {
 
563
         unmarshaller = new CompressingUnMarshaller(MarshalFactory.getUnMarshaller(SerializableUnMarshaller.DATATYPE));
 
564
      }
 
565
 
 
566
      Map map = metadata == null ? new HashMap(headers) : metadata;
 
567
      
 
568
      // UnMarshaller may not be an HTTPUnMarshaller, in which case it
 
569
      // can ignore this parameter.
 
570
      if (map.get(HTTPUnMarshaller.PRESERVE_LINES) == null)
 
571
      {
 
572
         Object o = configuration.get(HTTPUnMarshaller.PRESERVE_LINES);
 
573
         if (o != null)
 
574
            map.put(HTTPUnMarshaller.PRESERVE_LINES, o);
 
575
      }
 
576
      
 
577
      map.put(HTTPMetadataConstants.USE_REMOTING_CONTENT_TYPE, Boolean.toString(useRemotingContentType));
 
578
      
 
579
      try
 
580
      {
 
581
         if (unmarshaller instanceof VersionedUnMarshaller)
 
582
            result = ((VersionedUnMarshaller)unmarshaller).read(is, map, getVersion());
 
583
         else
 
584
            result = unmarshaller.read(is, map);
 
585
      }
 
586
      catch (ClassNotFoundException e)
 
587
      {
 
588
         throw e;
 
589
      }
 
590
      catch (IOException e)
 
591
      {
 
592
         log.trace(this + " unable to read response", e);
 
593
         if (-1 == is.read())
 
594
         {
 
595
            throw new EOFException();
 
596
         }
 
597
         throw e;
 
598
      }
 
599
 
 
600
      return result;
 
601
   }
 
602
 
 
603
   private void setChunked(Map metadata, final HttpURLConnection conn)
 
604
   {
 
605
      String chunkedValue = (String) metadata.get("chunkedLength");
 
606
      if (chunkedValue != null && chunkedValue.length() > 0)
 
607
      {
 
608
         try
 
609
         {
 
610
            int chunkedLength = Integer.parseInt(chunkedValue);
 
611
 
 
612
            /**
 
613
             * Since HTTPURLConnection in jdk 1.4 does NOT have a setChunkedStreamingMode() method and
 
614
             * the one in jdk 1.5 does, will have to use reflection to see if it exists before trying to set it.
 
615
             */
 
616
            try
 
617
            {
 
618
               Class cl = conn.getClass();
 
619
               Class[] paramTypes = new Class[] {int.class};
 
620
               Method setChunkedLengthMethod = getMethod(cl, "setChunkedStreamingMode", paramTypes);
 
621
               setChunkedLengthMethod.invoke(conn, new Object[]{new Integer(chunkedLength)});
 
622
            }
 
623
            catch (NoSuchMethodException e)
 
624
            {
 
625
               log.warn("Could not set chunked length (" + chunkedLength + ") on http client transport as method not available with JDK 1.4 (only JDK 1.5 or higher)");
 
626
            }
 
627
            catch (IllegalAccessException e)
 
628
            {
 
629
               log.error("Error setting http client connection chunked length.");
 
630
               log.debug(e);
 
631
            }
 
632
            catch (InvocationTargetException e)
 
633
            {
 
634
               log.error("Error setting http client connection chunked length.");
 
635
               log.debug(e);
 
636
            }
 
637
            catch (Exception e)
 
638
            {
 
639
               // Unexpected.
 
640
               log.error("Unexpected error setting http client connection chunked length.");
 
641
               log.debug(e);
 
642
            }
 
643
         }
 
644
         catch (NumberFormatException e)
 
645
         {
 
646
            log.error("Could not set chunked length for http client connection because value (" + chunkedValue + ") is not a number.");
 
647
         }
 
648
 
 
649
 
 
650
      }
 
651
   }
 
652
 
 
653
 
 
654
   private int getSimulatedTimeout(Map configuration, Map metadata, final HttpURLConnection conn)
 
655
   {
 
656
      int timeout = -1;
 
657
      String connectionTimeout = (String) configuration.get("timeout");
 
658
      String invocationTimeout = (String) metadata.get("timeout");
 
659
      
 
660
      if (invocationTimeout != null && invocationTimeout.length() > 0)
 
661
      {
 
662
         try
 
663
         {
 
664
            timeout = Integer.parseInt(invocationTimeout);
 
665
         }
 
666
         catch (NumberFormatException e)
 
667
         {
 
668
            log.error("Could not set timeout for current invocation because value (" + invocationTimeout + ") is not a number.");
 
669
         }
 
670
      }
 
671
      
 
672
      if (timeout < 0 && connectionTimeout != null && connectionTimeout.length() > 0)
 
673
      {
 
674
         try
 
675
         {
 
676
            timeout = Integer.parseInt(connectionTimeout);
 
677
         }
 
678
         catch (NumberFormatException e)
 
679
         {
 
680
            log.error("Could not set timeout for http client connection because value (" + connectionTimeout + ") is not a number.");
 
681
         }
 
682
      }
 
683
      
 
684
      if (timeout < 0)
 
685
         timeout = 0;
 
686
 
 
687
      /**
 
688
       * Since URLConnection in jdk 1.4 does NOT have a setConnectTimeout() method and
 
689
       * the one in jdk 1.5 does, will have to use reflection to see if it exists before
 
690
       * trying to set it.
 
691
       */
 
692
      try
 
693
      {
 
694
         Class cl = conn.getClass();
 
695
         Class[] paramTypes = new Class[] {int.class};
 
696
         Method setTimeoutMethod = getMethod(cl, "setConnectTimeout", paramTypes);
 
697
         setTimeoutMethod.invoke(conn, new Object[]{new Integer(timeout)});
 
698
         setTimeoutMethod = getMethod(cl, "setReadTimeout", paramTypes);
 
699
         setTimeoutMethod.invoke(conn, new Object[]{new Integer(timeout)});
 
700
         return -1;
 
701
      }
 
702
      catch (NoSuchMethodException e)
 
703
      {
 
704
         log.debug("Using older JDK (prior to 1.5): will simulate timeout");
 
705
      }
 
706
      catch (IllegalAccessException e)
 
707
      {
 
708
         log.error("Error setting http client connection timeout.");
 
709
         log.debug(e);
 
710
      }
 
711
      catch (InvocationTargetException e)
 
712
      {
 
713
         log.error("Error setting http client connection timeout.");
 
714
         log.debug(e);
 
715
      }
 
716
      catch (Exception e)
 
717
      {
 
718
         // Unexpected.
 
719
         log.error("Unexpected error setting http client connection timeout.");
 
720
         log.debug(e);
 
721
      }
 
722
 
 
723
      return timeout;
 
724
   }
 
725
 
 
726
   protected String validateURL(String url)
 
727
   {
 
728
      String validatedUrl = url;
 
729
 
 
730
      if (validatedUrl.startsWith("servlet"))
 
731
      {
 
732
         // servlet:// is a valid protocol, but only in the remoting world, so need to convert to http
 
733
         validatedUrl = "http" + validatedUrl.substring("servlet".length());
 
734
      }
 
735
      return validatedUrl;
 
736
   }
 
737
   
 
738
   protected Home getUsableAddress()
 
739
   {
 
740
      InvokerLocator savedLocator = locator;
 
741
      String protocol = savedLocator.getProtocol();
 
742
      String path = savedLocator.getPath();
 
743
      Map params = savedLocator.getParameters();
 
744
      List homes = getConnectHomes();
 
745
      
 
746
      Iterator it = homes.iterator();
 
747
      while (it.hasNext())
 
748
      {
 
749
         Home home = null;
 
750
         try
 
751
         {
 
752
            home = (Home) it.next();
 
753
            locator = new InvokerLocator(protocol, home.host, home.port, path, params);
 
754
            invoke(new InvocationRequest(null, null, ServerInvoker.ECHO, null, null, null));
 
755
            if (log.isTraceEnabled()) log.trace(this + " able to contact server at: " + home);
 
756
            return home;
 
757
         }
 
758
         catch (Throwable e)
 
759
         {
 
760
            log.debug(this + " unable to contact server at: " + home);
 
761
         }
 
762
         finally
 
763
         {
 
764
            locator = savedLocator;
 
765
         }
 
766
      }
 
767
   
 
768
      return null;
 
769
   }
 
770
 
 
771
   protected HttpURLConnection createURLConnection(String url, Map metadata) throws IOException
 
772
   {
 
773
      URL externalURL = null;
 
774
      HttpURLConnection httpURLConn = null;
 
775
 
 
776
      // need to find out if need to use a proxy or not
 
777
      String proxyHost = null;
 
778
      String proxyportString = null;
 
779
      int proxyPort = 80;
 
780
 
 
781
      if (metadata != null)
 
782
      {
 
783
         // first check the metadata as will have precedence
 
784
         proxyHost = (String) metadata.get("http.proxyHost");
 
785
         proxyportString = (String) metadata.get("http.proxyPort");
 
786
         if (proxyportString != null && proxyportString.length() > 0)
 
787
         {
 
788
            try
 
789
            {
 
790
               proxyPort = Integer.parseInt(proxyportString);
 
791
            }
 
792
            catch (NumberFormatException e)
 
793
            {
 
794
               log.warn("Error converting proxy port specified (" + proxyportString + ") to a number.");
 
795
            }
 
796
         }
 
797
      }
 
798
 
 
799
      // now determin if going to use proxy or not
 
800
      if (proxyHost != null)
 
801
      {
 
802
         externalURL = new URL(url);
 
803
 
 
804
         /**
 
805
          * Since URL in jdk 1.4 does NOT have a openConnection(Proxy) method and
 
806
          * the one in jdk 1.5 does, will have to use reflection to see if it exists before trying to set it.
 
807
          */
 
808
         try
 
809
         {
 
810
            final Class proxyClass = ClassLoaderUtility.loadClass("java.net.Proxy", HTTPClientInvoker.class);
 
811
            InetSocketAddress proxyAddress = new InetSocketAddress(proxyHost, proxyPort);
 
812
            Class[] decalredClasses = proxyClass.getDeclaredClasses();
 
813
            Class proxyTypeClass = null;
 
814
            for(int x = 0; x < decalredClasses.length; x++)
 
815
            {
 
816
               Class declaredClass = decalredClasses[x];
 
817
               String className = declaredClass.getName();
 
818
               if(className.endsWith("Type"))
 
819
               {
 
820
                  proxyTypeClass = declaredClass;
 
821
                  break;
 
822
               }
 
823
            }
 
824
            Object proxyType = null;
 
825
            Field[] fields = proxyTypeClass.getDeclaredFields();
 
826
            for(int i = 0; i < fields.length; i++)
 
827
            {
 
828
               Field field = fields[i];
 
829
               String fieldName = field.getName();
 
830
               if(fieldName.endsWith("HTTP"))
 
831
               {
 
832
                  proxyType = field.get(proxyTypeClass);
 
833
                  break;
 
834
               }
 
835
            }
 
836
            Constructor proxyConstructor = proxyClass.getConstructor(new Class[] {proxyTypeClass, SocketAddress.class});
 
837
            Object proxy = proxyConstructor.newInstance(new Object[] {proxyType, proxyAddress});
 
838
            Method openConnection = getMethod(URL.class, "openConnection", new Class[] {proxyClass});
 
839
            httpURLConn = (HttpURLConnection)openConnection.invoke(externalURL, new Object[] {proxy});
 
840
         }
 
841
         catch (Exception e)
 
842
         {
 
843
            log.error("Can not set proxy for http invocation (proxy host: " + proxyHost + ", proxy port: " + proxyPort + ") " +
 
844
                      "as this configuration requires JDK 1.5 or later.  If running JDK 1.4, can use proxy by setting system properties.");
 
845
            log.debug(e);
 
846
         }
 
847
 
 
848
         // since know it is a proxy being used, see if have proxy auth
 
849
         String proxyAuth = getProxyAuth(metadata);
 
850
         if (proxyAuth != null)
 
851
         {
 
852
            httpURLConn.setRequestProperty("Proxy-Authorization", proxyAuth);
 
853
         }
 
854
      }
 
855
      else
 
856
      {
 
857
         externalURL = new URL(url);
 
858
         httpURLConn = (HttpURLConnection) externalURL.openConnection();
 
859
         
 
860
         // Check if proxy is being configured by system properties.
 
861
         if (getSystemProperty("http.proxyHost") != null)
 
862
         {
 
863
            String proxyAuth = getProxyAuth(metadata);
 
864
            if (proxyAuth != null)
 
865
            {
 
866
               httpURLConn.setRequestProperty("Proxy-Authorization", proxyAuth);
 
867
            }
 
868
         }
 
869
      }
 
870
 
 
871
      return httpURLConn;
 
872
   }
 
873
 
 
874
   private String getProxyAuth(Map metadata)
 
875
   {
 
876
      String authString = null;
 
877
      String username = null;
 
878
      String password = null;
 
879
 
 
880
      if (metadata != null)
 
881
      {
 
882
         username = (String) metadata.get("http.proxy.username");
 
883
      }
 
884
      if (username == null || username.length() == 0)
 
885
      {
 
886
         username = getSystemProperty("http.proxy.username");
 
887
      }
 
888
      if (metadata != null)
 
889
      {
 
890
         password = (String) metadata.get("http.proxy.password");
 
891
      }
 
892
      if (password == null)
 
893
      {
 
894
         password = getSystemProperty("http.proxy.password");
 
895
      }
 
896
 
 
897
      if (username != null && password != null)
 
898
      {
 
899
         StringBuffer buffer = new StringBuffer();
 
900
         buffer.append(username);
 
901
         buffer.append(":");
 
902
         buffer.append(password);
 
903
 
 
904
         String encoded = Base64.encodeBytes(buffer.toString().getBytes());
 
905
 
 
906
         authString = "Basic " + encoded;
 
907
 
 
908
      }
 
909
 
 
910
      return authString;
 
911
   }
 
912
 
 
913
   private String getBasicAuth(Map metadata)
 
914
   {
 
915
      String authString = null;
 
916
      String username = null;
 
917
      String password = null;
 
918
 
 
919
      if (metadata != null)
 
920
      {
 
921
         username = (String) metadata.get("http.basic.username");
 
922
      }
 
923
      if (username == null || username.length() == 0)
 
924
      {
 
925
         username = getSystemProperty("http.basic.username");
 
926
      }
 
927
      if (metadata != null)
 
928
      {
 
929
         password = (String) metadata.get("http.basic.password");
 
930
      }
 
931
      if (password == null)
 
932
      {
 
933
         password = getSystemProperty("http.basic.password");
 
934
      }
 
935
 
 
936
      if (username != null && password != null)
 
937
      {
 
938
         StringBuffer buffer = new StringBuffer();
 
939
         buffer.append(username);
 
940
         buffer.append(":");
 
941
         buffer.append(password);
 
942
 
 
943
         String encoded = Base64.encodeBytes(buffer.toString().getBytes(), Base64.DONT_BREAK_LINES);
 
944
 
 
945
         authString = "Basic " + encoded;
 
946
 
 
947
      }
 
948
 
 
949
      return authString;
 
950
   }
 
951
 
 
952
 
 
953
   /**
 
954
    * subclasses must implement this method to provide a hook to connect to the remote server, if this applies
 
955
    * to the specific transport. However, in some transport implementations, this may not make must difference since
 
956
    * the connection is not persistent among invocations, such as SOAP.  In these cases, the method should
 
957
    * silently return without any processing.
 
958
    *
 
959
    * @throws org.jboss.remoting.ConnectionFailedException
 
960
    *
 
961
    */
 
962
   protected void handleConnect() throws ConnectionFailedException
 
963
   {
 
964
      if (InvokerLocator.MULTIHOME.equals(locator.getHost()))
 
965
      {
 
966
         Home home = getUsableAddress();
 
967
         if (home == null)
 
968
         {
 
969
            throw new ConnectionFailedException(this + " unable to find a usable address for: " + home);
 
970
         }
 
971
         
 
972
         String protocol = locator.getProtocol();
 
973
         String path = locator.getPath();
 
974
         Map params = locator.getParameters();
 
975
         locator = new InvokerLocator(protocol, home.host, home.port, path, params);
 
976
         if (log.isDebugEnabled()) log.debug(this + " will use InvokerLocator " + locator);
 
977
      }
 
978
   }
 
979
 
 
980
   /**
 
981
    * subclasses must implement this method to provide a hook to disconnect from the remote server, if this applies
 
982
    * to the specific transport. However, in some transport implementations, this may not make must difference since
 
983
    * the connection is not persistent among invocations, such as SOAP.  In these cases, the method should
 
984
    * silently return without any processing.
 
985
    */
 
986
   protected void handleDisconnect()
 
987
   {
 
988
      // NO OP as not statefull connection
 
989
   }
 
990
 
 
991
   /**
 
992
    * Each implementation of the remote client invoker should have
 
993
    * a default data type that is uses in the case it is not specified
 
994
    * in the invoker locator uri.
 
995
    *
 
996
    * @return
 
997
    */
 
998
   protected String getDefaultDataType()
 
999
   {
 
1000
      return HTTPMarshaller.DATATYPE;
 
1001
   }
 
1002
 
 
1003
 
 
1004
   /**
 
1005
    * Sets the thread pool to be used for simulating timeouts with jdk 1.4.
 
1006
    */
 
1007
   public void setTimeoutThreadPool(ThreadPool pool)
 
1008
   {
 
1009
      this.timeoutThreadPool = pool;
 
1010
   }
 
1011
   
 
1012
   protected void configureParameters()
 
1013
   {
 
1014
      Object val = configuration.get(HTTPMetadataConstants.NO_THROW_ON_ERROR);
 
1015
      if (val != null)
 
1016
      {
 
1017
         try
 
1018
         {
 
1019
            noThrowOnError = Boolean.valueOf((String)val).booleanValue();
 
1020
            log.debug(this + " setting noThrowOnError to " + noThrowOnError);
 
1021
         }
 
1022
         catch (Exception e)
 
1023
         {
 
1024
            log.warn(this + " could not convert " + 
 
1025
                     HTTPMetadataConstants.NO_THROW_ON_ERROR + " value of " +
 
1026
                     val + " to a boolean value.");
 
1027
         }
 
1028
      }
 
1029
      
 
1030
      val = configuration.get(NUMBER_OF_CALL_ATTEMPTS);
 
1031
      if (val != null)
 
1032
      {
 
1033
         try
 
1034
         {
 
1035
            numberOfCallAttempts = Integer.valueOf((String)val).intValue();
 
1036
            log.debug(this + " setting numberOfCallRetries to " + numberOfCallAttempts);
 
1037
         }
 
1038
         catch (Exception e)
 
1039
         {
 
1040
            log.warn(this + " could not convert " + 
 
1041
                     NUMBER_OF_CALL_ATTEMPTS + " value of " +
 
1042
                     val + " to an int value.");
 
1043
         }
 
1044
      }
 
1045
      
 
1046
      val = configuration.get(UNMARSHAL_NULL_STREAM);
 
1047
      if (val != null)
 
1048
      {
 
1049
         try
 
1050
         {
 
1051
            unmarshalNullStream = Boolean.valueOf((String)val).booleanValue();
 
1052
            log.debug(this + " setting unmarshalNullStream to " + unmarshalNullStream);
 
1053
         }
 
1054
         catch (Exception e)
 
1055
         {
 
1056
            log.warn(this + " could not convert " + 
 
1057
                     UNMARSHAL_NULL_STREAM + " value of " +
 
1058
                     val + " to a boolean value.");
 
1059
         }
 
1060
      }
 
1061
 
 
1062
      val = configuration.get(HTTPMetadataConstants.USE_REMOTING_CONTENT_TYPE);
 
1063
      if (val != null)
 
1064
      {
 
1065
         try
 
1066
         {
 
1067
            useRemotingContentType = Boolean.valueOf((String)val).booleanValue();
 
1068
            log.debug(this + " setting useRemotingContent to " + useRemotingContentType);
 
1069
         }
 
1070
         catch (Exception e)
 
1071
         {
 
1072
            log.warn(this + " could not convert " + 
 
1073
                     HTTPMetadataConstants.USE_REMOTING_CONTENT_TYPE + " value of " +
 
1074
                     val + " to a boolean value.");
 
1075
         }
 
1076
      }
 
1077
   }
 
1078
   
 
1079
   /**
 
1080
    * Gets the thread pool being used for simulating timeouts with jdk 1.4. If one has
 
1081
    * not be specifically set via configuration or call to set it, will always return
 
1082
    * instance of org.jboss.util.threadpool.BasicThreadPool.
 
1083
    */
 
1084
   public ThreadPool getTimeoutThreadPool()
 
1085
   {
 
1086
      synchronized (timeoutThreadPoolLock)
 
1087
      {
 
1088
         if (timeoutThreadPool == null)
 
1089
         {
 
1090
            int maxNumberThreads = MAX_NUM_TIMEOUT_THREADS_DEFAULT;
 
1091
            int maxTimeoutQueueSize = -1;
 
1092
            
 
1093
            BasicThreadPool pool = new BasicThreadPool("HTTP timeout");
 
1094
            log.debug("created new thread pool: " + pool);
 
1095
            Object param = configuration.get(MAX_NUM_TIMEOUT_THREADS);
 
1096
            if (param instanceof String)
 
1097
            {
 
1098
               try
 
1099
               {
 
1100
                  maxNumberThreads = Integer.parseInt((String) param);
 
1101
               }
 
1102
               catch (NumberFormatException  e)
 
1103
               {
 
1104
                  log.error("maxNumberThreads parameter has invalid format: " + param);
 
1105
               }
 
1106
            }
 
1107
            else if (param != null)
 
1108
            {
 
1109
               log.error("maxNumberThreads parameter must be a string in integer format: " + param);
 
1110
            }
 
1111
 
 
1112
            param = configuration.get(MAX_TIMEOUT_QUEUE_SIZE);
 
1113
 
 
1114
            if (param instanceof String)
 
1115
            {
 
1116
               try
 
1117
               {
 
1118
                  maxTimeoutQueueSize = Integer.parseInt((String) param);
 
1119
               }
 
1120
               catch (NumberFormatException  e)
 
1121
               {
 
1122
                  log.error("maxTimeoutQueueSize parameter has invalid format: " + param);
 
1123
               }
 
1124
            }
 
1125
            else if (param != null)
 
1126
            {
 
1127
               log.error("maxTimeoutQueueSize parameter must be a string in integer format: " + param);
 
1128
            }
 
1129
 
 
1130
            pool.setMaximumPoolSize(maxNumberThreads);
 
1131
 
 
1132
            if (maxTimeoutQueueSize > 0)
 
1133
            {
 
1134
               pool.setMaximumQueueSize(maxTimeoutQueueSize);
 
1135
            }
 
1136
            pool.setBlockingMode(BlockingMode.RUN);
 
1137
            timeoutThreadPool = pool;
 
1138
         }
 
1139
      }
 
1140
      return timeoutThreadPool;
 
1141
   }
 
1142
   
 
1143
   
 
1144
   /**
 
1145
    * When a WaitingTaskWrapper is run in a BasicThreadPool, the calling thread
 
1146
    * will block for the designated timeout period.
 
1147
    */
 
1148
   static class WaitingTaskWrapper extends RunnableTaskWrapper
 
1149
   {
 
1150
      long completeTimeout;
 
1151
      
 
1152
      public WaitingTaskWrapper(Runnable runnable, long completeTimeout)
 
1153
      {
 
1154
         super(runnable, 0, completeTimeout);
 
1155
         this.completeTimeout = completeTimeout;
 
1156
      }
 
1157
      public int getTaskWaitType()
 
1158
      {
 
1159
         return Task.WAIT_FOR_COMPLETE;
 
1160
      }
 
1161
      public String toString()
 
1162
      {
 
1163
         return "WaitingTaskWrapper[" + completeTimeout + "]";
 
1164
      }
 
1165
   }
 
1166
   
 
1167
   static private String getSystemProperty(final String name)
 
1168
   {
 
1169
      if (SecurityUtility.skipAccessControl())
 
1170
         return System.getProperty(name);
 
1171
      
 
1172
      String value = null;
 
1173
      try
 
1174
      {
 
1175
         value = (String)AccessController.doPrivileged( new PrivilegedExceptionAction()
 
1176
         {
 
1177
            public Object run() throws Exception
 
1178
            {
 
1179
               return System.getProperty(name);
 
1180
            }
 
1181
         });
 
1182
      }
 
1183
      catch (PrivilegedActionException e)
 
1184
      {
 
1185
         throw (RuntimeException) e.getCause();
 
1186
      }
 
1187
      
 
1188
      return value;
 
1189
   }
 
1190
   
 
1191
   static private Method getMethod(final Class c, final String name, final Class[] parameterTypes)
 
1192
   throws NoSuchMethodException
 
1193
   {
 
1194
      if (SecurityUtility.skipAccessControl())
 
1195
      {
 
1196
         return c.getMethod(name, parameterTypes);
 
1197
      }
 
1198
 
 
1199
      try
 
1200
      {
 
1201
         return (Method) AccessController.doPrivileged( new PrivilegedExceptionAction()
 
1202
         {
 
1203
            public Object run() throws NoSuchMethodException
 
1204
            {
 
1205
               return c.getMethod(name, parameterTypes);
 
1206
            }
 
1207
         });
 
1208
      }
 
1209
      catch (PrivilegedActionException e)
 
1210
      {
 
1211
         throw (NoSuchMethodException) e.getCause();
 
1212
      }
 
1213
   }
 
1214
   
 
1215
   static private void connect(final HttpURLConnection conn) throws IOException
 
1216
   {
 
1217
      if (SecurityUtility.skipAccessControl())
 
1218
      {
 
1219
         conn.connect();
 
1220
         return;
 
1221
      }
 
1222
 
 
1223
      try
 
1224
      {
 
1225
         AccessController.doPrivileged( new PrivilegedExceptionAction()
 
1226
         {
 
1227
            public Object run() throws IOException
 
1228
            {
 
1229
               conn.connect();
 
1230
               return null;
 
1231
            }
 
1232
         });
 
1233
      }
 
1234
      catch (PrivilegedActionException e)
 
1235
      {
 
1236
         throw (IOException) e.getCause();
 
1237
      }
 
1238
   }
 
1239
   
 
1240
   static private OutputStream getOutputStream(final HttpURLConnection conn)
 
1241
   throws IOException
 
1242
   {
 
1243
      if (SecurityUtility.skipAccessControl())
 
1244
      {
 
1245
         return conn.getOutputStream();
 
1246
      }
 
1247
      
 
1248
      try
 
1249
      {
 
1250
         return (OutputStream)AccessController.doPrivileged( new PrivilegedExceptionAction()
 
1251
         {
 
1252
            public Object run() throws IOException
 
1253
            {
 
1254
               return conn.getOutputStream();
 
1255
            }
 
1256
         });
 
1257
      }
 
1258
      catch (PrivilegedActionException e)
 
1259
      {
 
1260
         throw (IOException) e.getCause();
 
1261
      }
 
1262
   }
 
1263
   
 
1264
   static private int getResponseCode(final HttpURLConnection conn)
 
1265
   throws IOException
 
1266
   {
 
1267
      if (SecurityUtility.skipAccessControl())
 
1268
      {
 
1269
         return conn.getResponseCode();
 
1270
      }
 
1271
      
 
1272
      try
 
1273
      {
 
1274
         return ((Integer) AccessController.doPrivileged( new PrivilegedExceptionAction()
 
1275
         {
 
1276
            public Object run() throws IOException
 
1277
            {
 
1278
               return new Integer(conn.getResponseCode());
 
1279
            }
 
1280
         })).intValue();
 
1281
      }
 
1282
      catch (PrivilegedActionException e)
 
1283
      {
 
1284
         throw (IOException) e.getCause();
 
1285
      }
 
1286
   }
 
1287
   
 
1288
   static private String getResponseMessage(final HttpURLConnection conn)
 
1289
   throws IOException
 
1290
   {
 
1291
      if (SecurityUtility.skipAccessControl())
 
1292
      {
 
1293
         return conn.getResponseMessage();
 
1294
      }
 
1295
      
 
1296
      try
 
1297
      {
 
1298
         return (String) AccessController.doPrivileged( new PrivilegedExceptionAction()
 
1299
         {
 
1300
            public Object run() throws IOException
 
1301
            {
 
1302
               return conn.getResponseMessage();
 
1303
            }
 
1304
         });
 
1305
      }
 
1306
      catch (PrivilegedActionException e)
 
1307
      {
 
1308
         throw (IOException) e.getCause();
 
1309
      }
 
1310
   }
 
1311
}
 
 
b'\\ No newline at end of file'