You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by "Davanum Srinivas (JIRA)" <ax...@ws.apache.org> on 2005/06/10 16:45:53 UTC

[jira] Assigned: (AXIS-1994) CommonsHTTPSender failing to set host name

     [ http://issues.apache.org/jira/browse/AXIS-1994?page=all ]

Davanum Srinivas reassigned AXIS-1994:
--------------------------------------

    Assign To: Jayachandra Sekhara Rao Sunkara

> CommonsHTTPSender failing to set host name
> ------------------------------------------
>
>          Key: AXIS-1994
>          URL: http://issues.apache.org/jira/browse/AXIS-1994
>      Project: Axis
>         Type: Bug
>   Components: Basic Architecture
>     Versions: 1.2
>     Reporter: Javier Cámara
>     Assignee: Jayachandra Sekhara Rao Sunkara
>     Priority: Minor

>
> I tried to use Axis 1.2 to trespass a firewall with NTLM authentication (I think it is NTLM; at least it asks for an Active Directory Domain). 
> I configured client-config.wsdd to use CommonsHTTPSender, and installed commons-codec-1.3.jar in the classpath. But I got the following exception:
>  
> java.lang.IllegalArgumentException: host parameter is null
>         at org.apache.commons.httpclient.HttpConnection.&lt;init&gt;(HttpConnection.java:206)
>         at org.apache.commons.httpclient.HttpConnection.&lt;init&gt;(HttpConnection.java:155)
>         at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$HttpConnectionWithReference.&lt;init&gt;(MultiThreadedHttpConnectionManager.java:1123)
>         at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$ConnectionPool.createConnection(MultiThreadedHttpConnectionManager.java:748)
>         at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager.doGetConnection(MultiThreadedHttpConnectionManager.java:469)
>         at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager.getConnectionWithTimeout(MultiThreadedHttpConnectionManager.java:394)
>         at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:152)
>         at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:393)
>         at org.apache.axis.transport.http.CommonsHTTPSender.invoke(CommonsHTTPSender.java:186)
>         at org.apache.axis.strategies.InvocationStrategy.visit(InvocationStrategy.java:32)
>         at org.apache.axis.SimpleChain.doVisiting(SimpleChain.java:118)
>         at org.apache.axis.SimpleChain.invoke(SimpleChain.java:83)
>         at org.apache.axis.client.AxisClient.invoke(AxisClient.java:165)
>         at org.apache.axis.client.Call.invokeEngine(Call.java:2765)
>         at org.apache.axis.client.Call.invoke(Call.java:2748)
>         at org.apache.axis.client.Call.invoke(Call.java:1784)
>  (...)
>  
> Then I had a look into CommonsHTTPSender and saw that the getHostConfiguration(HttpClient, MessageContext, URL) method seemed to fail to call config.setHost() when there is a proxy host. I patched it. After that I still got an error, but related to the Commons HTTP Library and not CommonsHTTPSender.
> Since it seems to be no attachement feature in JIRA I guess I have to copy & paste my patch here. I will post the entire file; I just added line 390 (marked as "JCM"):
> /*
>  * Copyright 2001-2004 The Apache Software Foundation.
>  * 
>  * Licensed under the Apache License, Version 2.0 (the "License");
>  * you may not use this file except in compliance with the License.
>  * You may obtain a copy of the License at
>  * 
>  *      http://www.apache.org/licenses/LICENSE-2.0
>  * 
>  * Unless required by applicable law or agreed to in writing, software
>  * distributed under the License is distributed on an "AS IS" BASIS,
>  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
>  * See the License for the specific language governing permissions and
>  * limitations under the License.
>  */
> package org.apache.axis.transport.http;
> import org.apache.axis.AxisFault;
> import org.apache.axis.Constants;
> import org.apache.axis.Message;
> import org.apache.axis.MessageContext;
> import org.apache.axis.components.logger.LogFactory;
> import org.apache.axis.components.net.CommonsHTTPClientProperties;
> import org.apache.axis.components.net.CommonsHTTPClientPropertiesFactory;
> import org.apache.axis.components.net.TransportClientProperties;
> import org.apache.axis.components.net.TransportClientPropertiesFactory;
> import org.apache.axis.handlers.BasicHandler;
> import org.apache.axis.soap.SOAP12Constants;
> import org.apache.axis.soap.SOAPConstants;
> import org.apache.axis.utils.Messages;
> import org.apache.axis.utils.NetworkUtils;
> import org.apache.commons.httpclient.Cookie;
> import org.apache.commons.httpclient.Credentials;
> import org.apache.commons.httpclient.Header;
> import org.apache.commons.httpclient.HostConfiguration;
> import org.apache.commons.httpclient.HttpClient;
> import org.apache.commons.httpclient.HttpConnectionManager;
> import org.apache.commons.httpclient.HttpMethodBase;
> import org.apache.commons.httpclient.HttpState;
> import org.apache.commons.httpclient.HttpVersion;
> import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
> import org.apache.commons.httpclient.NTCredentials;
> import org.apache.commons.httpclient.UsernamePasswordCredentials;
> import org.apache.commons.httpclient.auth.AuthScope;
> import org.apache.commons.httpclient.cookie.CookiePolicy;
> import org.apache.commons.httpclient.methods.GetMethod;
> import org.apache.commons.httpclient.methods.PostMethod;
> import org.apache.commons.httpclient.methods.RequestEntity;
> import org.apache.commons.httpclient.params.HttpMethodParams;
> import org.apache.commons.logging.Log;
> import javax.xml.soap.MimeHeader;
> import javax.xml.soap.MimeHeaders;
> import javax.xml.soap.SOAPException;
> import java.io.FilterInputStream;
> import java.io.IOException;
> import java.io.InputStream;
> import java.io.OutputStream;
> import java.net.URL;
> import java.util.Hashtable;
> import java.util.Iterator;
> import java.util.Map;
> import java.util.StringTokenizer;
> import java.util.ArrayList;
> /**
>  * This class uses Jakarta Commons's HttpClient to call a SOAP server.
>  *
>  * @author Davanum Srinivas (dims@yahoo.com)
>  * History: By Chandra Talluri
>  * Modifications done for maintaining sessions. Cookies needed to be set on
>  * HttpState not on MessageContext, since ttpMethodBase overwrites the cookies 
>  * from HttpState. Also we need to setCookiePolicy on HttpState to 
>  * CookiePolicy.COMPATIBILITY else it is defaulting to RFC2109Spec and adding 
>  * Version information to it and tomcat server not recognizing it
>  */
> public class CommonsHTTPSender extends BasicHandler {
>     
>     /** Field log           */
>     protected static Log log =
>         LogFactory.getLog(CommonsHTTPSender.class.getName());
>     
>     protected HttpConnectionManager connectionManager;
>     protected CommonsHTTPClientProperties clientProperties;
>     
>     public CommonsHTTPSender() {
>         initialize();
>     }
>     protected void initialize() {
>         MultiThreadedHttpConnectionManager cm = new MultiThreadedHttpConnectionManager();
>         this.clientProperties = CommonsHTTPClientPropertiesFactory.create();
>         cm.getParams().setDefaultMaxConnectionsPerHost(clientProperties.getMaximumConnectionsPerHost());
>         cm.getParams().setMaxTotalConnections(clientProperties.getMaximumTotalConnections());
>         // If defined, set the default timeouts
>         // Can be overridden by the MessageContext
>         if(this.clientProperties.getDefaultConnectionTimeout()>0) {
>            cm.getParams().setConnectionTimeout(this.clientProperties.getDefaultConnectionTimeout());
>         }
>         if(this.clientProperties.getDefaultSoTimeout()>0) {
>            cm.getParams().setSoTimeout(this.clientProperties.getDefaultSoTimeout());
>         }
>         this.connectionManager = cm;
>     }
>     
>     /**
>      * invoke creates a socket connection, sends the request SOAP message and then
>      * reads the response SOAP message back from the SOAP server
>      *
>      * @param msgContext the messsage context
>      *
>      * @throws AxisFault
>      */
>     public void invoke(MessageContext msgContext) throws AxisFault {
>         HttpMethodBase method = null;
>         if (log.isDebugEnabled()) {
>             log.debug(Messages.getMessage("enter00",
>                                           "CommonsHTTPSender::invoke"));
>         }
>         try {
>             URL targetURL =
>                 new URL(msgContext.getStrProp(MessageContext.TRANS_URL));
>             
>             // no need to retain these, as the cookies/credentials are
>             // stored in the message context across multiple requests.
>             // the underlying connection manager, however, is retained
>             // so sockets get recycled when possible.
>             HttpClient httpClient = new HttpClient(this.connectionManager);
>             // the timeout value for allocation of connections from the pool
>             httpClient.getParams().setConnectionManagerTimeout(this.clientProperties.getConnectionPoolTimeout());
>             HostConfiguration hostConfiguration = 
>                 getHostConfiguration(httpClient, msgContext, targetURL);
>             
>             boolean posting = true;
>             
>             // If we're SOAP 1.2, allow the web method to be set from the
>             // MessageContext.
>             if (msgContext.getSOAPConstants() == SOAPConstants.SOAP12_CONSTANTS) {
>                 String webMethod = msgContext.getStrProp(SOAP12Constants.PROP_WEBMETHOD);
>                 if (webMethod != null) {
>                     posting = webMethod.equals(HTTPConstants.HEADER_POST);
>                 }
>             }
>             if (posting) {
>                 Message reqMessage = msgContext.getRequestMessage();
>                 method = new PostMethod(targetURL.toString());
>                 // set false as default, addContetInfo can overwrite
>                 method.getParams().setBooleanParameter(HttpMethodParams.USE_EXPECT_CONTINUE,
>                                                        false);
>                 
>                 addContextInfo(method, httpClient, msgContext, targetURL);
>                 ((PostMethod)method).setRequestEntity(
>                                                new MessageRequestEntity(method, reqMessage));
>             } else {
>                 method = new GetMethod(targetURL.toString());
>                 addContextInfo(method, httpClient, msgContext, targetURL);
>             }
>             String httpVersion = 
>                 msgContext.getStrProp(MessageContext.HTTP_TRANSPORT_VERSION);
>             if (httpVersion != null) {
>                 if (httpVersion.equals(HTTPConstants.HEADER_PROTOCOL_V10)) {
>                     method.getParams().setVersion(HttpVersion.HTTP_1_0);
>                 }
>                 // assume 1.1
>             }
>             
>             // don't forget the cookies!
>             // Cookies need to be set on HttpState, since HttpMethodBase 
>             // overwrites the cookies from HttpState
>             if (msgContext.getMaintainSession()) {
>                 HttpState state = httpClient.getState();
>                 method.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
>                 String host = hostConfiguration.getHost();
>                 String path = targetURL.getPath();
>                 boolean secure = hostConfiguration.getProtocol().isSecure();
>                 fillHeaders(msgContext, state, HTTPConstants.HEADER_COOKIE, host, path, secure);
>                 fillHeaders(msgContext, state, HTTPConstants.HEADER_COOKIE2, host, path, secure);
>                 httpClient.setState(state);
>             }
>             int returnCode = httpClient.executeMethod(hostConfiguration, method, null);
>             String contentType = 
>                 getHeader(method, HTTPConstants.HEADER_CONTENT_TYPE);
>             String contentLocation = 
>                 getHeader(method, HTTPConstants.HEADER_CONTENT_LOCATION);
>             String contentLength = 
>                 getHeader(method, HTTPConstants.HEADER_CONTENT_LENGTH);
>             if ((returnCode > 199) && (returnCode < 300)) {
>                 
>                 // SOAP return is OK - so fall through
>             } else if (msgContext.getSOAPConstants() ==
>                        SOAPConstants.SOAP12_CONSTANTS) {
>                 // For now, if we're SOAP 1.2, fall through, since the range of
>                 // valid result codes is much greater
>             } else if ((contentType != null) && !contentType.equals("text/html")
>                        && ((returnCode > 499) && (returnCode < 600))) {
>                 
>                 // SOAP Fault should be in here - so fall through
>             } else {
>                 String statusMessage = method.getStatusText();
>                 AxisFault fault = new AxisFault("HTTP",
>                                                 "(" + returnCode + ")"
>                                                 + statusMessage, null,
>                                                 null);
>                 
>                 try {
>                     fault.setFaultDetailString(
>                          Messages.getMessage("return01",
>                                              "" + returnCode,
>                                              method.getResponseBodyAsString()));
>                     fault.addFaultDetail(Constants.QNAME_FAULTDETAIL_HTTPERRORCODE,
>                                          Integer.toString(returnCode));
>                     throw fault;
>                 } finally {
>                     method.releaseConnection(); // release connection back to pool.
>                 }
>             }
>             
>             // wrap the response body stream so that close() also releases 
>             // the connection back to the pool.
>             InputStream releaseConnectionOnCloseStream = 
>                 createConnectionReleasingInputStream(method);
>             Message outMsg = new Message(releaseConnectionOnCloseStream,
>                                          false, contentType, contentLocation);
>             // Transfer HTTP headers of HTTP message to MIME headers of SOAP message
>             Header[] responseHeaders = method.getResponseHeaders();
>             MimeHeaders responseMimeHeaders = outMsg.getMimeHeaders();
>             for (int i = 0; i < responseHeaders.length; i++) {
>                 Header responseHeader = responseHeaders[i];
>                 responseMimeHeaders.addHeader(responseHeader.getName(), 
>                                               responseHeader.getValue());
>             }
>             outMsg.setMessageType(Message.RESPONSE);
>             msgContext.setResponseMessage(outMsg);
>             if (log.isDebugEnabled()) {
>                 if (null == contentLength) {
>                     log.debug("\n"
>                     + Messages.getMessage("no00", "Content-Length"));
>                 }
>                 log.debug("\n" + Messages.getMessage("xmlRecd00"));
>                 log.debug("-----------------------------------------------");
>                 log.debug(outMsg.getSOAPPartAsString());
>             }
>             
>             // if we are maintaining session state,
>             // handle cookies (if any)
>             if (msgContext.getMaintainSession()) {
>                 Header[] headers = method.getResponseHeaders();
>                 ArrayList cookies = new ArrayList();
>                 ArrayList cookies2 = new ArrayList();
>                 for (int i = 0; i < headers.length; i++) {
>                     if (headers[i].getName().equalsIgnoreCase(HTTPConstants.HEADER_SET_COOKIE)) {
>                         cookies.add(cleanupCookie(headers[i].getValue()));
>                     } else if (headers[i].getName().equalsIgnoreCase(HTTPConstants.HEADER_SET_COOKIE2)) {
>                         cookies2.add(cleanupCookie(headers[i].getValue()));
>                     }
>                 }
>                 if(cookies.size()==1) {
>                     msgContext.setProperty(HTTPConstants.HEADER_COOKIE, cookies.get(0));
>                 } else if (cookies.size() > 1) {
>                     msgContext.setProperty(HTTPConstants.HEADER_COOKIE, cookies.toArray(new String[cookies.size()]));
>                 }
>                 if(cookies2.size()==1) {
>                     msgContext.setProperty(HTTPConstants.HEADER_COOKIE2, cookies2.get(0));
>                 } else if (cookies2.size() > 1) {
>                     msgContext.setProperty(HTTPConstants.HEADER_COOKIE2, cookies2.toArray(new String[cookies2.size()]));
>                 }
>             }
>             // always release the connection back to the pool if 
>             // it was one way invocation
>             if (msgContext.isPropertyTrue("axis.one.way")) {
>                 method.releaseConnection();
>             }
>             
>         } catch (Exception e) {
>             log.debug(e);
>             throw AxisFault.makeFault(e);
>         }
>         
>         if (log.isDebugEnabled()) {
>             log.debug(Messages.getMessage("exit00",
>                                           "CommonsHTTPSender::invoke"));
>         }
>     }
>     /**
>      * Add cookies from message context
>      *
>      * @param msgContext
>      * @param state
>      * @param header
>      * @param host
>      * @param path
>      * @param secure
>      */
>     private void fillHeaders(MessageContext msgContext, HttpState state, String header, String host, String path, boolean secure) {
>         Object ck1 = msgContext.getProperty(header);
>         if (ck1 != null) {
>             if (ck1 instanceof String[]) {
>                 String [] cookies = (String[]) ck1;
>                 for (int i = 0; i < cookies.length; i++) {
>                     addCookie(state, cookies[i], host, path, secure);
>                 }
>             } else {
>                 addCookie(state, (String) ck1, host, path, secure);
>             }
>         }
>     }
>     /**
>      * add cookie to state
>      * @param state
>      * @param cookie
>      */
>     private void addCookie(HttpState state, String cookie,String host, String path, boolean secure) {
>         int index = cookie.indexOf('=');
>         state.addCookie(new Cookie(host, cookie.substring(0, index),
>                 cookie.substring(index + 1), path,
>                 null, secure));
>     }
>     /**
>      * cleanup the cookie value.
>      *
>      * @param cookie initial cookie value
>      *
>      * @return a cleaned up cookie value.
>      */
>     private String cleanupCookie(String cookie) {
>         cookie = cookie.trim();
>         // chop after first ; a la Apache SOAP (see HTTPUtils.java there)
>         int index = cookie.indexOf(';');
>         if (index != -1) {
>             cookie = cookie.substring(0, index);
>         }
>         return cookie;
>     }
>     
>     protected HostConfiguration getHostConfiguration(HttpClient client, 
>                                                      MessageContext context,
>                                                      URL targetURL) {
>         TransportClientProperties tcp = 
>             TransportClientPropertiesFactory.create(targetURL.getProtocol()); // http or https
>         int port = targetURL.getPort();
>         boolean hostInNonProxyList =
>             isHostInNonProxyList(targetURL.getHost(), tcp.getNonProxyHosts());
>         
>         HostConfiguration config = new HostConfiguration();
>         
>         if (port == -1) {
>             port = 80;          // even for https
>         }
>         
>         if(hostInNonProxyList){
>             config.setHost(targetURL.getHost(), port, targetURL.getProtocol());
>         } else {
>             if (tcp.getProxyHost().length() == 0 ||
>                 tcp.getProxyPort().length() == 0) {
>                 config.setHost(targetURL.getHost(), port, targetURL.getProtocol());
>             } else {
>                 if (tcp.getProxyUser().length() != 0) {
>                     Credentials proxyCred = 
>                         new UsernamePasswordCredentials(tcp.getProxyUser(),
>                                                         tcp.getProxyPassword());
>                     // if the username is in the form "user\domain" 
>                     // then use NTCredentials instead.
>                     int domainIndex = tcp.getProxyUser().indexOf("\\");
>                     if (domainIndex > 0) {
>                         String domain = tcp.getProxyUser().substring(0, domainIndex);
>                         if (tcp.getProxyUser().length() > domainIndex + 1) {
>                             String user = tcp.getProxyUser().substring(domainIndex + 1);
>                             proxyCred = new NTCredentials(user,
>                                             tcp.getProxyPassword(),
>                                             tcp.getProxyHost(), domain);
>                         }
>                     }
>                     client.getState().setProxyCredentials(AuthScope.ANY, proxyCred);
>                 }
>                 int proxyPort = new Integer(tcp.getProxyPort()).intValue();
>                 config.setProxy(tcp.getProxyHost(), proxyPort);
>                 config.setHost(targetURL.getHost(), port, targetURL.getProtocol()); // JCM May 2005
>             }
>         }
>         return config;
>     }
>     
>     /**
>      * Extracts info from message context.
>      *
>      * @param method Post method
>      * @param httpClient The client used for posting
>      * @param msgContext the message context
>      * @param tmpURL the url to post to.
>      *
>      * @throws Exception
>      */
>     private void addContextInfo(HttpMethodBase method, 
>                                 HttpClient httpClient, 
>                                 MessageContext msgContext, 
>                                 URL tmpURL)
>         throws Exception {
>         
>         // optionally set a timeout for the request
>         if (msgContext.getTimeout() != 0) {
>             /* ISSUE: these are not the same, but MessageContext has only one
>                       definition of timeout */
>             // SO_TIMEOUT -- timeout for blocking reads
>             httpClient.getHttpConnectionManager().getParams().setSoTimeout(msgContext.getTimeout());
>             // timeout for initial connection
>             httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(msgContext.getTimeout());
>         }
>         
>         // Get SOAPAction, default to ""
>         String action = msgContext.useSOAPAction()
>             ? msgContext.getSOAPActionURI()
>             : "";
>         
>         if (action == null) {
>             action = "";
>         }
>         Message msg = msgContext.getRequestMessage();
>         if (msg != null){
>             method.setRequestHeader(new Header(HTTPConstants.HEADER_CONTENT_TYPE,
>                                                msg.getContentType(msgContext.getSOAPConstants())));
>         }
>         method.setRequestHeader(new Header(HTTPConstants.HEADER_SOAP_ACTION, 
>                                            "\"" + action + "\""));
>         String userID = msgContext.getUsername();
>         String passwd = msgContext.getPassword();
>         
>         // if UserID is not part of the context, but is in the URL, use
>         // the one in the URL.
>         if ((userID == null) && (tmpURL.getUserInfo() != null)) {
>             String info = tmpURL.getUserInfo();
>             int sep = info.indexOf(':');
>             
>             if ((sep >= 0) && (sep + 1 < info.length())) {
>                 userID = info.substring(0, sep);
>                 passwd = info.substring(sep + 1);
>             } else {
>                 userID = info;
>             }
>         }
>         if (userID != null) {
>             Credentials proxyCred =
>                 new UsernamePasswordCredentials(userID,
>                                                 passwd);
>             // if the username is in the form "user\domain"
>             // then use NTCredentials instead.
>             int domainIndex = userID.indexOf("\\");
>             if (domainIndex > 0) {
>                 String domain = userID.substring(0, domainIndex);
>                 if (userID.length() > domainIndex + 1) {
>                     String user = userID.substring(domainIndex + 1);
>                     proxyCred = new NTCredentials(user,
>                                     passwd,
>                                     NetworkUtils.getLocalHostname(), domain);
>                 }
>             }
>             httpClient.getState().setCredentials(AuthScope.ANY, proxyCred);
>         }
>         
>         // Transfer MIME headers of SOAPMessage to HTTP headers. 
>         MimeHeaders mimeHeaders = msg.getMimeHeaders();
>         if (mimeHeaders != null) {
>             for (Iterator i = mimeHeaders.getAllHeaders(); i.hasNext(); ) {
>                 MimeHeader mimeHeader = (MimeHeader) i.next();
>                 method.addRequestHeader(mimeHeader.getName(), 
>                                         mimeHeader.getValue());
>             }
>         }
>         // process user defined headers for information.
>         Hashtable userHeaderTable =
>             (Hashtable) msgContext.getProperty(HTTPConstants.REQUEST_HEADERS);
>         
>         if (userHeaderTable != null) {
>             for (Iterator e = userHeaderTable.entrySet().iterator();
>                  e.hasNext();) {
>                 Map.Entry me = (Map.Entry) e.next();
>                 Object keyObj = me.getKey();
>                 
>                 if (null == keyObj) {
>                     continue;
>                 }
>                 String key = keyObj.toString().trim();
>                 String value = me.getValue().toString().trim();
>                 
>                 if (key.equalsIgnoreCase(HTTPConstants.HEADER_EXPECT) &&
>                     value.equalsIgnoreCase(HTTPConstants.HEADER_EXPECT_100_Continue)) {
>                     method.getParams().setBooleanParameter(HttpMethodParams.USE_EXPECT_CONTINUE,
>                                                            true);
>                 } else {
>                     method.addRequestHeader(key, value);
>                 }
>             }
>         }
>     }
>     
>     /**
>      * Check if the specified host is in the list of non proxy hosts.
>      *
>      * @param host host name
>      * @param nonProxyHosts string containing the list of non proxy hosts
>      *
>      * @return true/false
>      */
>     protected boolean isHostInNonProxyList(String host, String nonProxyHosts) {
>         
>         if ((nonProxyHosts == null) || (host == null)) {
>             return false;
>         }
>         
>         /*
>          * The http.nonProxyHosts system property is a list enclosed in
>          * double quotes with items separated by a vertical bar.
>          */
>         StringTokenizer tokenizer = new StringTokenizer(nonProxyHosts, "|\"");
>         
>         while (tokenizer.hasMoreTokens()) {
>             String pattern = tokenizer.nextToken();
>             
>             if (log.isDebugEnabled()) {
>                 log.debug(Messages.getMessage("match00",
>                 new String[]{"HTTPSender",
>                 host,
>                 pattern}));
>             }
>             if (match(pattern, host, false)) {
>                 return true;
>             }
>         }
>         return false;
>     }
>     
>     /**
>      * Matches a string against a pattern. The pattern contains two special
>      * characters:
>      * '*' which means zero or more characters,
>      *
>      * @param pattern the (non-null) pattern to match against
>      * @param str     the (non-null) string that must be matched against the
>      *                pattern
>      * @param isCaseSensitive
>      *
>      * @return <code>true</code> when the string matches against the pattern,
>      *         <code>false</code> otherwise.
>      */
>     protected static boolean match(String pattern, String str,
>                                    boolean isCaseSensitive) {
>         
>         char[] patArr = pattern.toCharArray();
>         char[] strArr = str.toCharArray();
>         int patIdxStart = 0;
>         int patIdxEnd = patArr.length - 1;
>         int strIdxStart = 0;
>         int strIdxEnd = strArr.length - 1;
>         char ch;
>         boolean containsStar = false;
>         
>         for (int i = 0; i < patArr.length; i++) {
>             if (patArr[i] == '*') {
>                 containsStar = true;
>                 break;
>             }
>         }
>         if (!containsStar) {
>             
>             // No '*'s, so we make a shortcut
>             if (patIdxEnd != strIdxEnd) {
>                 return false;        // Pattern and string do not have the same size
>             }
>             for (int i = 0; i <= patIdxEnd; i++) {
>                 ch = patArr[i];
>                 if (isCaseSensitive && (ch != strArr[i])) {
>                     return false;    // Character mismatch
>                 }
>                 if (!isCaseSensitive
>                 && (Character.toUpperCase(ch)
>                 != Character.toUpperCase(strArr[i]))) {
>                     return false;    // Character mismatch
>                 }
>             }
>             return true;             // String matches against pattern
>         }
>         if (patIdxEnd == 0) {
>             return true;    // Pattern contains only '*', which matches anything
>         }
>         
>         // Process characters before first star
>         while ((ch = patArr[patIdxStart]) != '*'
>         && (strIdxStart <= strIdxEnd)) {
>             if (isCaseSensitive && (ch != strArr[strIdxStart])) {
>                 return false;    // Character mismatch
>             }
>             if (!isCaseSensitive
>             && (Character.toUpperCase(ch)
>             != Character.toUpperCase(strArr[strIdxStart]))) {
>                 return false;    // Character mismatch
>             }
>             patIdxStart++;
>             strIdxStart++;
>         }
>         if (strIdxStart > strIdxEnd) {
>             
>             // All characters in the string are used. Check if only '*'s are
>             // left in the pattern. If so, we succeeded. Otherwise failure.
>             for (int i = patIdxStart; i <= patIdxEnd; i++) {
>                 if (patArr[i] != '*') {
>                     return false;
>                 }
>             }
>             return true;
>         }
>         
>         // Process characters after last star
>         while ((ch = patArr[patIdxEnd]) != '*' && (strIdxStart <= strIdxEnd)) {
>             if (isCaseSensitive && (ch != strArr[strIdxEnd])) {
>                 return false;    // Character mismatch
>             }
>             if (!isCaseSensitive
>             && (Character.toUpperCase(ch)
>             != Character.toUpperCase(strArr[strIdxEnd]))) {
>                 return false;    // Character mismatch
>             }
>             patIdxEnd--;
>             strIdxEnd--;
>         }
>         if (strIdxStart > strIdxEnd) {
>             
>             // All characters in the string are used. Check if only '*'s are
>             // left in the pattern. If so, we succeeded. Otherwise failure.
>             for (int i = patIdxStart; i <= patIdxEnd; i++) {
>                 if (patArr[i] != '*') {
>                     return false;
>                 }
>             }
>             return true;
>         }
>         
>         // process pattern between stars. padIdxStart and patIdxEnd point
>         // always to a '*'.
>         while ((patIdxStart != patIdxEnd) && (strIdxStart <= strIdxEnd)) {
>             int patIdxTmp = -1;
>             
>             for (int i = patIdxStart + 1; i <= patIdxEnd; i++) {
>                 if (patArr[i] == '*') {
>                     patIdxTmp = i;
>                     break;
>                 }
>             }
>             if (patIdxTmp == patIdxStart + 1) {
>                 
>                 // Two stars next to each other, skip the first one.
>                 patIdxStart++;
>                 continue;
>             }
>             
>             // Find the pattern between padIdxStart & padIdxTmp in str between
>             // strIdxStart & strIdxEnd
>             int patLength = (patIdxTmp - patIdxStart - 1);
>             int strLength = (strIdxEnd - strIdxStart + 1);
>             int foundIdx = -1;
>             
>             strLoop:
>                 for (int i = 0; i <= strLength - patLength; i++) {
>                     for (int j = 0; j < patLength; j++) {
>                         ch = patArr[patIdxStart + j + 1];
>                         if (isCaseSensitive
>                         && (ch != strArr[strIdxStart + i + j])) {
>                             continue strLoop;
>                         }
>                         if (!isCaseSensitive && (Character
>                         .toUpperCase(ch) != Character
>                         .toUpperCase(strArr[strIdxStart + i + j]))) {
>                             continue strLoop;
>                         }
>                     }
>                     foundIdx = strIdxStart + i;
>                     break;
>                 }
>                 if (foundIdx == -1) {
>                     return false;
>                 }
>                 patIdxStart = patIdxTmp;
>                 strIdxStart = foundIdx + patLength;
>         }
>         
>         // All characters in the string are used. Check if only '*'s are left
>         // in the pattern. If so, we succeeded. Otherwise failure.
>         for (int i = patIdxStart; i <= patIdxEnd; i++) {
>             if (patArr[i] != '*') {
>                 return false;
>             }
>         }
>         return true;
>     }
>     private static String getHeader(HttpMethodBase method, String headerName) {
>         Header header = method.getResponseHeader(headerName);
>         return (header == null) ? null : header.getValue().trim();
>     }
>     private InputStream createConnectionReleasingInputStream(final HttpMethodBase method) throws IOException {
>         return new FilterInputStream(method.getResponseBodyAsStream()) {
>                 public void close() throws IOException {
>                     try {
>                         super.close();
>                     } finally {
>                         method.releaseConnection();
>                     }
>                 }
>             };
>     }
>     private static class MessageRequestEntity implements RequestEntity {
>         
>         private HttpMethodBase method;
>         private Message message;
>         public MessageRequestEntity(HttpMethodBase method, Message message) {
>             this.message = message;
>             this.method = method;
>         }
>         public boolean isRepeatable() {
>             return true;
>         }
>         public void writeRequest(OutputStream out) throws IOException {
>             try {
>                 this.message.writeTo(out);
>             } catch (SOAPException e) {
>                 throw new IOException(e.getMessage());
>             }
>         }
>         public long getContentLength() {
>             if (this.method.getParams().getVersion() == HttpVersion.HTTP_1_0) {
>                 try {
>                     return message.getContentLength();
>                 } catch (Exception e) {
>                     return -1; /* -1 for chunked */
>                 }
>             } else {
>                 return -1; /* -1 for chunked */
>             }
>         }
>         public String getContentType() {
>             return null; // a separate header is added
>         }
>         
>     }
> }

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira