Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   /*
   * JBoss, Home of Professional Open Source
   * Copyright 2005, JBoss Inc., and individual contributors as indicated
   * by the @authors tag. See the copyright.txt in the distribution for a
   * full listing of individual contributors.
   *
   * This is free software; you can redistribute it and/or modify it
   * under the terms of the GNU Lesser General Public License as
   * published by the Free Software Foundation; either version 2.1 of
  * the License, or (at your option) any later version.
  *
  * This software is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this software; if not, write to the Free
  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  */
  
  package org.jboss.remoting.transport.http;
  
  import  org.jboss.logging.Logger;
  import  org.jboss.util.Base64;
  import  org.jboss.util.threadpool.BasicThreadPool;
  import  org.jboss.util.threadpool.BlockingMode;
  import  org.jboss.util.threadpool.RunnableTaskWrapper;
  import  org.jboss.util.threadpool.Task;
  import  org.jboss.util.threadpool.ThreadPool;
  
  import java.net.URL;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  import java.util.Set;

HTTP client invoker. Used for making http requests on http/servlet invoker.

Author(s):
Tom Elrod
  
  public class HTTPClientInvoker extends RemoteClientInvoker
  {
   
Key for the configuration map that determines the threadpool size for simulated timeouts when using jdk 1.4.
  
     public static final String MAX_NUM_TIMEOUT_THREADS = "maxNumTimeoutThreads";

   
Key for the configuration map that determines the queue size for simulated timeout threadpool when using jdk 1.4.
  
     public static final String MAX_TIMEOUT_QUEUE_SIZE = "maxTimeoutQueueSize";
   
   
Specifies the default number of work threads in the thread pool for simulating timeouts when using jdk 1.4.
  
     public static final int MAX_NUM_TIMEOUT_THREADS_DEFAULT = 10;
   
   
Specifies the number of attempts to get a functioning connection to the http server. Defaults to 1.
 
    public static final String NUMBER_OF_CALL_ATTEMPTS = "numberOfCallAttempts";
    
    /*
     * Specifies whether useHttpURLConnection(), upon receiving a null InputStream or ErrorStream,
     * should call the UnMarshaller.
     */
    public static final String UNMARSHAL_NULL_STREAM = "unmarshalNullStream";
    
    protected static final Logger log = Logger.getLogger(HTTPClientInvoker.class);
    
    protected boolean noThrowOnError;
    protected int numberOfCallAttempts = 1;
    protected boolean unmarshalNullStream = true;
    
    private Object timeoutThreadPoolLock = new Object();
    private ThreadPool timeoutThreadPool;
 
    public HTTPClientInvoker(InvokerLocator locator)
    {
       super(locator);
       configureParameters();
    }
 
    public HTTPClientInvoker(InvokerLocator locatorMap configuration)
    {
       super(locatorconfiguration);
       configureParameters();
    }

   

Parameters:
sessionId
invocation
marshaller
Returns:
Throws:
java.io.IOException
org.jboss.remoting.ConnectionFailedException
 
    protected Object transport(String sessionIdfinal Object invocationMap metadata,
                               final Marshaller marshallerfinal UnMarshaller unmarshaller)
          throws IOExceptionConnectionFailedException
    {
       // need to check the url and make sure it compatible protocol
       final String validatedUrl = validateURL(getLocator().getLocatorURI());
 
       if (metadata == null)
       {
          metadata = new HashMap();
       }
 
       final HttpURLConnection conn = createURLConnection(validatedUrlmetadata);
       
       int simulatedTimeout = getSimulatedTimeout(metadataconn);
       
       if (simulatedTimeout <= 0)
       {
          return makeInvocation(connvalidatedUrlinvocationmetadatamarshallerunmarshallertrue);
       }
       else
       {
          if (.isTraceEnabled()) .trace("using simulated timeout: " + simulatedTimeout);
          class Holder {public Object value;}
          final Holder resultHolder = new Holder();
          final Map finalMetadata = metadata;
          
          Runnable r = new Runnable()
          {
             public void run()
             {
                try
                {
                   resultHolder.value = useHttpURLConnection(conninvocationfinalMetadatamarshallerunmarshaller);
                   if (.isTraceEnabled()) .trace("result: " + resultHolder.value);
                }
                catch (Exception e)
                {
                   resultHolder.value = e;
                   if (.isTraceEnabled()) .trace("exception: " + e); 
                }
             }
          };
          
          // BasicThreadPool timeout mechanism depends on the interrupted status of
          // the running thread.
          Thread.interrupted();
          
          ThreadPool pool = getTimeoutThreadPool();
          WaitingTaskWrapper wrapper = new WaitingTaskWrapper(rsimulatedTimeout);
          if (.isTraceEnabled()) .trace("starting task in thread pool");
          pool.runTaskWrapper(wrapper);
          if (.isTraceEnabled()) .trace("task finished in thread pool");
          
          Object result = resultHolder.value;
          if (result == null)
          {
             if (.isDebugEnabled()) .debug("invocation timed out");
             Exception cause = new SocketTimeoutException("timed out");
             throw new CannotConnectException("Can not connect http client invoker."cause);
          }
          else if (result instanceof IOException)
          {
             throw (IOExceptionresult;
          }
          else if (result instanceof RuntimeException)
          {
             throw (RuntimeExceptionresult;
          }
          else
          {
             if (.isTraceEnabled()) .trace("returning result: " + result);
             return result;
          }
       }
    }
 
    protected Object makeInvocation(HttpURLConnection connString urlObject invocation,
                                    Map metadataMarshaller marshallerUnMarshaller unmarshaller,
                                    boolean setTimeout)
    throws IOException
    {
       Throwable savedException = null;
       
       for (int i = 0; i < i++)
       {
          try
          {
             Object o = useHttpURLConnection(conninvocationmetadatamarshallerunmarshaller);
             if (.isTraceEnabled()) .trace("result: " + o);
             return o;
          }
          catch (CannotConnectException e)
          {
             savedException = e.getCause();
             String suffix = (i < ( - 1) ? ": will retry" : "");
             .debug("Cannot connect on attempt " + (i + 1) + suffix);
             conn = createURLConnection(urlmetadata);
             if (setTimeout)
             {
                getSimulatedTimeout(metadataconn);
             }
          }
       }
       
       String msg = "Can not connect http client invoker after " +  + " attempt(s)";
       throw new CannotConnectException(msgsavedException);
    }
    
    
    private Object useHttpURLConnection(HttpURLConnection connObject invocationMap metadata,
                                        Marshaller marshallerUnMarshaller unmarshallerthrows WebServerError
    {
       Object result = null;
       int responseCode = -1;
 
       try
       {
          setChunked(conn);
 
          // check to see if basic auth required
          String basicAuth = getBasicAuth(metadata);
          if (basicAuth != null)
          {
             conn.setRequestProperty("Authorization"basicAuth);
          }
 
          // check for ping request and process it now and return
          result = checkForLeasePing(conn,  invocationmetadata);
          if(result != null)
          {
             return result;
          }
 
 
          // Get the request method type
          boolean sendingData = true;
          String type = "POST";
          if (metadata != null)
          {
             type = (Stringmetadata.get("TYPE");
             if (type != null)
             {
                if ((!type.equals("POST") && !type.equals("PUT")))
                {
                   sendingData = false;
                }
             }
             else
             {
                type = "POST";
             }
          }
          else // need to check for content type and set metadata
          {
             metadata = new HashMap();
             Map header = new HashMap();
             header.put(., WebUtil.getContentType(invocation));
             metadata.put("HEADER"header);
          }
          // Set request headers
          Map header = (Mapmetadata.get("HEADER");
          if (header != null)
          {
             Set keys = header.keySet();
             Iterator itr = keys.iterator();
             while (itr.hasNext())
             {
                String key = (Stringitr.next();
                String value = (Stringheader.get(key);
                .debug("Setting request header with " + key + " : " + value);
                conn.setRequestProperty(keyvalue);
             }
          }
          else
          {
             conn.setRequestProperty(., WebUtil.getContentType(invocation));
          }
 
          // set the remoting version
          // set the user agent
          conn.setRequestProperty(."JBossRemoting - " + .);
 
          if (sendingData)
          {
             //POST or PUT
             conn.setDoOutput(true);
             conn.setDoInput(true);
             conn.setRequestMethod(type);
 
             OutputStream stream = SecurityUtility.getOutputStream(conn);        
             if (marshaller instanceof VersionedMarshaller)
                ((VersionedMarshallermarshaller).write(invocationstreamgetVersion());
             else
                marshaller.write(invocationstream);
             responseCode = SecurityUtility.getResponseCode(conn);
 
             Map headers = conn.getHeaderFields();
             if (metadata == null)
             {
                metadata = new HashMap();
             }
 
             // sometimes I get headers with "null" keys (I don't know who's fault is it), so I need
             // to clean the header map, unless I want to get an NPE thrown by metadata.putAll()
             if (headers != null)
             {
                for(Iterator i = headers.entrySet().iterator(); i.hasNext(); )
                {
                   Map.Entry e = (Map.Entry)i.next();
                   if (e.getKey() != null)
                   {
                      metadata.put(e.getKey(), e.getValue());
                   }
                }
             }
 
             String responseMessage = SecurityUtility.getResponseMessage(conn);
             metadata.put(.responseMessage);
             metadata.put(.new Integer(responseCode));
             metadata.put(.headers);
 
             InputStream is = (responseCode < 400) ? conn.getInputStream() : conn.getErrorStream();
             if (is != null || )
             {
                result = readResponse(metadataheadersunmarshalleris);
             }
          }
          else
          {
             conn.setDoOutput(false);
             conn.setDoInput(true);
             conn.setRequestMethod(type);
 
             SecurityUtility.connect(conn);
 
             InputStream is = (SecurityUtility.getResponseCode(conn) < 400) ? conn.getInputStream() : conn.getErrorStream();
             Map headers = conn.getHeaderFields();
 
             if (is != null || )
             {
                result = readResponse(nullheadersunmarshalleris);
             }
             
             if (metadata == null)
             {
                metadata = new HashMap();
             }
             metadata.putAll(headers);
             String responseMessage = SecurityUtility.getResponseMessage(conn);
             metadata.put(.responseMessage);
             responseCode = SecurityUtility.getResponseCode(conn);
             metadata.put(.new Integer(responseCode));
             metadata.put(.conn.getHeaderFields());
          }
       }
       catch (Exception e)
       {
          String message = "Can not connect http client invoker.";
          if (e.getMessage() != null)
             message += " " + e.getMessage() + ".";
  
          try
          {
             String responseMessage = SecurityUtility.getResponseMessage(conn);
             int code = SecurityUtility.getResponseCode(conn);
             message += " Response: " + responseMessage + "/" + code + ".";
          }
          catch (IOException e1)
          {
             .debug("Unable to retrieve response message"e1);
          }
          throw new CannotConnectException(messagee);
       }
 
       // now check for error response and throw exception unless configured to not do so
       if(responseCode >= 400)
       {
          boolean doNotThrow = ;
          if(metadata != null)
          {
             Object configObj = metadata.get(.);
             if(configObj != null && configObj instanceof String)
             {
                doNotThrow = Boolean.valueOf((String)configObj).booleanValue();
             }
          }
 
          if(doNotThrow)
          {
             if(result instanceof String)
             {
                // this is a html error page displayed by web server, need to conver to exception
                WebServerError ex = new WebServerError((String)result);
                return ex;
             }
             else if (result instanceof InvocationResponse)
             {
                return ((InvocationResponseresult).getResult();
             }
             else
             {
                return result;
             }
          }
 
 
          // if got here, wasn't configured to not throw exception, so will throw it.
 
          // In this case, MicroRemoteClientInvoker will throw the exception carried by
          // the InvocationResponse.
          if (result instanceof InvocationResponse)
             return result;
 
          // Otherwise, create a new WebServerError.
          if(result instanceof String)
          {
             WebServerError ex = new WebServerError((String)result);
             throw ex;
          }
          else
          {
             WebServerError ex = new WebServerError("Error received when calling on web server.  Error returned was " + responseCode);
             throw ex;
          }
 
       }
 
       return result;
    }
 
    private Object checkForLeasePing(HttpURLConnection connObject invocationMap metadatathrows IOException
    {
       InvocationResponse response = null;
       boolean shouldLease = false;
       long leasePeriod = -1;
 
       if(invocation != null && invocation instanceof InvocationRequest)
       {
          InvocationRequest request = (InvocationRequest)invocation;
 
          Object payload = request.getParameter();
          // although a bit of a hack, this will determin if first time ping called by client.
          if(payload != null && payload instanceof String && "$PING$".equalsIgnoreCase((String)payload) && request.getReturnPayload() != null)
          {
             try
             {
                // now know is a ping request, so convert to be a HEAD method call
                conn.setDoOutput(false);
                conn.setDoInput(true);
                conn.setRequestMethod("HEAD");
                // set the remoting version
                // set the user agent
                conn.setRequestProperty(."JBossRemoting - " + .);
                conn.setRequestProperty(."true");
                conn.setRequestProperty("sessionId"request.getSessionId());
                SecurityUtility.connect(conn);
 
                //InputStream is = (conn.getResponseCode() < 400) ? conn.getInputStream() : conn.getErrorStream();
                Map headers = conn.getHeaderFields();
 
                if(headers != null)
                {
                   Object leasingEnabled = headers.get("LEASING_ENABLED");
                   if(leasingEnabled != null && leasingEnabled instanceof List)
                   {
                      shouldLease = new Boolean((String)((List)leasingEnabled).get(0)).booleanValue();
                   }
                   Object leasingPeriod = headers.get("LEASE_PERIOD");
                   if(leasingPeriod != null && leasingPeriod instanceof List)
                   {
                      leasePeriod = new Long((String)((List)leasingPeriod).get(0)).longValue();
                   }
                }
             }
             catch (IOException e)
             {
                .error("Error checking server for lease information."e);
             }
 
             Map p = new HashMap();
             p.put("clientLeasePeriod"new Long(leasePeriod));
             InvocationResponse innterResponse = new InvocationResponse(nullnew Boolean(shouldLease), falsep);
             response = new InvocationResponse(nullinnterResponsefalsenull);
 
          }
       }
 
       return response;
    }
 
    private Object readResponse(Map metadataMap headersUnMarshaller unmarshallerInputStream is)
          throws  ClassNotFoundExceptionIOException
    {
       Object result = null;
       String encoding = null;
       Object ceObj = headers.get("Content-Encoding");
       if (ceObj != null)
       {
          if (ceObj instanceof List)
          {
             encoding = (String) ((ListceObj).get(0);
          }
       }
       if (encoding != null && encoding.indexOf("gzip") >= 0)
       {
          unmarshaller = new CompressingUnMarshaller(MarshalFactory.getUnMarshaller(.));
       }
 
       Map map = metadata == null ? headers : metadata;
       
       // UnMarshaller may not be an HTTPUnMarshaller, in which case it
       // can ignore this parameter.
       if (map.get(.) == null)
       {
          if (o != null)
             map.put(.o);
       }
       
       try
       {
          if (unmarshaller instanceof VersionedUnMarshaller)
             result = ((VersionedUnMarshaller)unmarshaller).read(ismapgetVersion());
          else
             result = unmarshaller.read(ismap);
       }
       catch (ClassNotFoundException e)
       {
          throw e;
       }
       catch (IOException e)
       {
          if (-1 == is.read())
          {
             throw new EOFException();
          }
          throw e;
       }
 
       return result;
    }
 
    private void setChunked(Map metadatafinal HttpURLConnection conn)
    {
       String chunkedValue = (Stringmetadata.get("chunkedLength");
       if (chunkedValue != null && chunkedValue.length() > 0)
       {
          try
          {
             int chunkedLength = Integer.parseInt(chunkedValue);

            
Since HTTPURLConnection in jdk 1.4 does NOT have a setChunkedStreamingMode() method and the one in jdk 1.5 does, will have to use reflection to see if it exists before trying to set it.
 
             try
             {
                Class cl = conn.getClass();
                Class[] paramTypes = new Class[] {int.class};
                Method setChunkedLengthMethod = SecurityUtility.getMethod(cl"setChunkedStreamingMode"paramTypes);
                setChunkedLengthMethod.invoke(connnew Object[]{new Integer(chunkedLength)});
             }
             catch (NoSuchMethodException e)
             {
                .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)");
             }
             catch (IllegalAccessException e)
             {
                .error("Error setting http client connection chunked length.");
                .debug(e);
             }
             catch (InvocationTargetException e)
             {
                .error("Error setting http client connection chunked length.");
                .debug(e);
             }
             catch (Exception e)
             {
                // Unexpected.
                .error("Unexpected error setting http client connection chunked length.");
                .debug(e);
             }
          }
          catch (NumberFormatException e)
          {
             .error("Could not set chunked length for http client connection because value (" + chunkedValue + ") is not a number.");
          }
 
 
       }
    }
 
 
    private int getSimulatedTimeout(Map configurationMap metadatafinal HttpURLConnection conn)
    {
       int timeout = -1;
       String connectionTimeout = (Stringconfiguration.get("timeout");
       String invocationTimeout = (Stringmetadata.get("timeout");
       
       if (invocationTimeout != null && invocationTimeout.length() > 0)
       {
          try
          {
             timeout = Integer.parseInt(invocationTimeout);
          }
          catch (NumberFormatException e)
          {
             .error("Could not set timeout for current invocation because value (" + invocationTimeout + ") is not a number.");
          }
       }
       
       if (timeout < 0 && connectionTimeout != null && connectionTimeout.length() > 0)
       {
          try
          {
             timeout = Integer.parseInt(connectionTimeout);
          }
          catch (NumberFormatException e)
          {
             .error("Could not set timeout for http client connection because value (" + connectionTimeout + ") is not a number.");
          }
       }
       
       if (timeout < 0)
          timeout = 0;

      
Since URLConnection in jdk 1.4 does NOT have a setConnectTimeout() method and the one in jdk 1.5 does, will have to use reflection to see if it exists before trying to set it.
 
       try
       {
          Class cl = conn.getClass();
          Class[] paramTypes = new Class[] {int.class};
          Method setTimeoutMethod = SecurityUtility.getMethod(cl"setConnectTimeout"paramTypes);
          setTimeoutMethod.invoke(connnew Object[]{new Integer(timeout)});
          setTimeoutMethod = SecurityUtility.getMethod(cl"setReadTimeout"paramTypes);
          setTimeoutMethod.invoke(connnew Object[]{new Integer(timeout)});
          return -1;
       }
       catch (NoSuchMethodException e)
       {
          .debug("Using older JDK (prior to 1.5): will simulate timeout");
       }
       catch (IllegalAccessException e)
       {
          .error("Error setting http client connection timeout.");
          .debug(e);
       }
       catch (InvocationTargetException e)
       {
          .error("Error setting http client connection timeout.");
          .debug(e);
       }
       catch (Exception e)
       {
          // Unexpected.
          .error("Unexpected error setting http client connection timeout.");
          .debug(e);
       }
 
       return timeout;
    }
 
    protected String validateURL(String url)
    {
       String validatedUrl = url;
 
       if (validatedUrl.startsWith("servlet"))
       {
          // servlet:// is a valid protocol, but only in the remoting world, so need to convert to http
          validatedUrl = "http" + validatedUrl.substring("servlet".length());
       }
       return validatedUrl;
    }
    
    protected Home getUsableAddress()
    {
       InvokerLocator savedLocator = ;
       String protocol = savedLocator.getProtocol();
       String path = savedLocator.getPath();
       Map params = savedLocator.getParameters();
       List homes = getConnectHomes();
       
       Iterator it = homes.iterator();
       while (it.hasNext())
       {
          Home home = null;
          try
          {
             home = (Homeit.next();
              = new InvokerLocator(protocolhome.hosthome.portpathparams);
             invoke(new InvocationRequest(nullnull.nullnullnull));
             if (.isTraceEnabled()) .trace(this + " able to contact server at: " + home);
             return home;
          }
          catch (Throwable e)
          {
             .debug(this + " unable to contact server at: " + home);
          }
          finally
          {
              = savedLocator;
          }
       }
    
       return null;
    }
 
    protected HttpURLConnection createURLConnection(String urlMap metadatathrows IOException
    {
       URL externalURL = null;
       HttpURLConnection httpURLConn = null;
 
       // need to find out if need to use a proxy or not
       String proxyHost = null;
       String proxyportString = null;
       int proxyPort = 80;
 
       if (metadata != null)
       {
          // first check the metadata as will have precedence
          proxyHost = (Stringmetadata.get("http.proxyHost");
          proxyportString = (Stringmetadata.get("http.proxyPort");
          if (proxyportString != null && proxyportString.length() > 0)
          {
             try
             {
                proxyPort = Integer.parseInt(proxyportString);
             }
             catch (NumberFormatException e)
             {
                .warn("Error converting proxy port specified (" + proxyportString + ") to a number.");
             }
          }
       }
 
       // now determin if going to use proxy or not
       if (proxyHost != null)
       {
          externalURL = new URL(url);

         
Since URL in jdk 1.4 does NOT have a openConnection(Proxy) method and the one in jdk 1.5 does, will have to use reflection to see if it exists before trying to set it.
 
          try
          {
             final Class proxyClass = ClassLoaderUtility.loadClass("java.net.Proxy"HTTPClientInvoker.class);
             InetSocketAddress proxyAddress = new InetSocketAddress(proxyHostproxyPort);
             Class[] decalredClasses = proxyClass.getDeclaredClasses();
             Class proxyTypeClass = null;
             for(int x = 0; x < decalredClasses.lengthx++)
             {
                Class declaredClass = decalredClasses[x];
                String className = declaredClass.getName();
                if(className.endsWith("Type"))
                {
                   proxyTypeClass = declaredClass;
                   break;
                }
             }
             Object proxyType = null;
             Field[] fields = proxyTypeClass.getDeclaredFields();
             for(int i = 0; i < fields.lengthi++)
             {
                Field field = fields[i];
                String fieldName = field.getName();
                if(fieldName.endsWith("HTTP"))
                {
                   proxyType = field.get(proxyTypeClass);
                   break;
                }
             }
             Constructor proxyConstructor = proxyClass.getConstructor(new Class[] {proxyTypeClassSocketAddress.class});
             Object proxy = proxyConstructor.newInstance(new Object[] {proxyTypeproxyAddress});
             Method openConnection = SecurityUtility.getMethod(URL.class"openConnection"new Class[] {proxyClass});
             httpURLConn = (HttpURLConnection)openConnection.invoke(externalURLnew Object[] {proxy});
          }
          catch (Exception e)
          {
             .error("Can not set proxy for http invocation (proxy host: " + proxyHost + ", proxy port: " + proxyPort + ") " +
                       "as this configuration requires JDK 1.5 or later.  If running JDK 1.4, can use proxy by setting system properties.");
             .debug(e);
          }
 
          // since know it is a proxy being used, see if have proxy auth
          String proxyAuth = getProxyAuth(metadata);
          if (proxyAuth != null)
          {
             httpURLConn.setRequestProperty("Proxy-Authorization"proxyAuth);
          }
       }
       else
       {
          externalURL = new URL(url);
          httpURLConn = (HttpURLConnectionexternalURL.openConnection();
          
          // Check if proxy is being configured by system properties.
          if (SecurityUtility.getSystemProperty("http.proxyHost") != null)
          {
             String proxyAuth = getProxyAuth(metadata);
             if (proxyAuth != null)
             {
                httpURLConn.setRequestProperty("Proxy-Authorization"proxyAuth);
             }
          }
       }
 
       return httpURLConn;
    }
 
    private String getProxyAuth(Map metadata)
    {
       String authString = null;
       String username = null;
       String password = null;
 
       if (metadata != null)
       {
          username = (Stringmetadata.get("http.proxy.username");
       }
       if (username == null || username.length() == 0)
       {
          username = SecurityUtility.getSystemProperty("http.proxy.username");
       }
       if (metadata != null)
       {
          password = (Stringmetadata.get("http.proxy.password");
       }
       if (password == null)
       {
          password = SecurityUtility.getSystemProperty("http.proxy.password");
       }
 
       if (username != null && password != null)
       {
          StringBuffer buffer = new StringBuffer();
          buffer.append(username);
          buffer.append(":");
          buffer.append(password);
 
          String encoded = Base64.encodeBytes(buffer.toString().getBytes());
 
          authString = "Basic " + encoded;
 
       }
 
       return authString;
    }
 
    private String getBasicAuth(Map metadata)
    {
       String authString = null;
       String username = null;
       String password = null;
 
       if (metadata != null)
       {
          username = (Stringmetadata.get("http.basic.username");
       }
       if (username == null || username.length() == 0)
       {
          username = SecurityUtility.getSystemProperty("http.basic.username");
       }
       if (metadata != null)
       {
          password = (Stringmetadata.get("http.basic.password");
       }
       if (password == null)
       {
          password = SecurityUtility.getSystemProperty("http.basic.password");
       }
 
       if (username != null && password != null)
       {
          StringBuffer buffer = new StringBuffer();
          buffer.append(username);
          buffer.append(":");
          buffer.append(password);
 
          String encoded = Base64.encodeBytes(buffer.toString().getBytes(), Base64.DONT_BREAK_LINES);
 
          authString = "Basic " + encoded;
 
       }
 
       return authString;
    }


   
subclasses must implement this method to provide a hook to connect to the remote server, if this applies to the specific transport. However, in some transport implementations, this may not make must difference since the connection is not persistent among invocations, such as SOAP. In these cases, the method should silently return without any processing.

Throws:
org.jboss.remoting.ConnectionFailedException
 
    protected void handleConnect() throws ConnectionFailedException
    {
       {
          Home home = getUsableAddress();
          if (home == null)
          {
             throw new ConnectionFailedException(this + " unable to find a usable address for: " + home);
          }
          
          String protocol = .getProtocol();
          String path = .getPath();
          Map params = .getParameters();
           = new InvokerLocator(protocolhome.hosthome.portpathparams);
          if (.isDebugEnabled()) .debug(this + " will use InvokerLocator " + );
       }
    }

   
subclasses must implement this method to provide a hook to disconnect from the remote server, if this applies to the specific transport. However, in some transport implementations, this may not make must difference since the connection is not persistent among invocations, such as SOAP. In these cases, the method should silently return without any processing.
 
    protected void handleDisconnect()
    {
       // NO OP as not statefull connection
    }

   
Each implementation of the remote client invoker should have a default data type that is uses in the case it is not specified in the invoker locator uri.

Returns:
 
    protected String getDefaultDataType()
    {
       return .;
    }


   
Sets the thread pool to be used for simulating timeouts with jdk 1.4.
 
    public void setTimeoutThreadPool(ThreadPool pool)
    {
       this. = pool;
    }
    
    protected void configureParameters()
    {
       if (val != null)
       {
          try
         {
             = Boolean.valueOf((String)val).booleanValue();
            .debug(this + " setting noThrowOnError to " + );
         }
         catch (Exception e)
         {
            .warn(this + " could not convert " + 
                     . + " value of " +
                     val + " to a boolean value.");
         }
      }
      
      if (val != null)
      {
         try
         {
             = Integer.valueOf((String)val).intValue();
            .debug(this + " setting numberOfCallRetries to " + );
         }
         catch (Exception e)
         {
            .warn(this + " could not convert " + 
                      + " value of " +
                     val + " to an int value.");
         }
      }
      
      if (val != null)
      {
         try
         {
             = Boolean.valueOf((String)val).booleanValue();
            .debug(this + " setting unmarshalNullStream to " + );
         }
         catch (Exception e)
         {
            .warn(this + " could not convert " + 
                      + " value of " +
                     val + " to a boolean value.");
         }
      }
   }
   
   
Gets the thread pool being used for simulating timeouts with jdk 1.4. If one has not be specifically set via configuration or call to set it, will always return instance of org.jboss.util.threadpool.BasicThreadPool.
   public ThreadPool getTimeoutThreadPool()
   {
      synchronized ()
      {
         if ( == null)
         {
            int maxNumberThreads = ;
            int maxTimeoutQueueSize = -1;
            
            BasicThreadPool pool = new BasicThreadPool("HTTP timeout");
            .debug("created new thread pool: " + pool);
            Object param = .get();
            if (param instanceof String)
            {
               try
               {
                  maxNumberThreads = Integer.parseInt((Stringparam);
               }
               catch (NumberFormatException  e)
               {
                  .error("maxNumberThreads parameter has invalid format: " + param);
               }
            }
            else if (param != null)
            {
               .error("maxNumberThreads parameter must be a string in integer format: " + param);
            }
            param = .get();
            if (param instanceof String)
            {
               try
               {
                  maxTimeoutQueueSize = Integer.parseInt((Stringparam);
               }
               catch (NumberFormatException  e)
               {
                  .error("maxTimeoutQueueSize parameter has invalid format: " + param);
               }
            }
            else if (param != null)
            {
               .error("maxTimeoutQueueSize parameter must be a string in integer format: " + param);
            }
            pool.setMaximumPoolSize(maxNumberThreads);
            if (maxTimeoutQueueSize > 0)
            {
               pool.setMaximumQueueSize(maxTimeoutQueueSize);
            }
            pool.setBlockingMode(BlockingMode.RUN);
             = pool;
         }
      }
      return ;
   }
   
   
   
When a WaitingTaskWrapper is run in a BasicThreadPool, the calling thread will block for the designated timeout period.
   static class WaitingTaskWrapper extends RunnableTaskWrapper
   {
      long completeTimeout;
      
      public WaitingTaskWrapper(Runnable runnablelong completeTimeout)
      {
         super(runnable, 0, completeTimeout);
         this. = completeTimeout;
      }
      public int getTaskWaitType()
      {
         return Task.WAIT_FOR_COMPLETE;
      }
      public String toString()
      {
         return "WaitingTaskWrapper[" +  + "]";
      }
   }