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

« back to all changes in this revision

Viewing changes to src/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'