You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cactus-dev@jakarta.apache.org by vm...@apache.org on 2003/02/22 21:24:17 UTC
cvs commit: jakarta-cactus/framework/src/java/j2ee13/org/apache/cactus/util FilterConfiguration.java
vmassol 2003/02/22 12:24:17
Modified: framework/src/java/share/org/apache/cactus/client/authentication
FormAuthentication.java
framework/src/java/share/org/apache/cactus/configuration
Configuration.java BaseConfiguration.java
framework/src/java/share/org/apache/cactus
AbstractWebServerTestCase.java WebRequest.java
framework/src/java/j2ee13/org/apache/cactus/util
FilterConfiguration.java
Added: framework/src/java/share/org/apache/cactus/client/connector
ConnectionHelperFactory.java
JdkConnectionHelper.java DefaultHttpClient.java
AbstractConnectionHelper.java
AutoReadHttpURLConnection.java
ConnectionHelper.java
HttpClientConnectionHelper.java
Removed: framework/src/java/share/org/apache/cactus/client
AutoReadHttpURLConnection.java
DefaultHttpClient.java ConnectionHelper.java
ConnectionHelperFactory.java
HttpClientConnectionHelper.java
AbstractConnectionHelper.java
JdkConnectionHelper.java
Log:
Package refactoring (should not affect any cactus user)
Revision Changes Path
1.1 jakarta-cactus/framework/src/java/share/org/apache/cactus/client/connector/ConnectionHelperFactory.java
Index: ConnectionHelperFactory.java
===================================================================
/*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Cactus" and "Apache Software
* Foundation" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.cactus.client.connector;
import java.lang.reflect.Constructor;
import org.apache.cactus.configuration.Configuration;
import org.apache.cactus.util.ChainedRuntimeException;
/**
* Factory that returns the <code>ConnectionHelper</code> specified in Cactus
* configuration or the default one if none has been specified.
*
* @see Configuration
*
* @author <a href="mailto:vmassol@apache.org">Vincent Massol</a>
*
* @version $Id: ConnectionHelperFactory.java,v 1.1 2003/02/22 20:24:15 vmassol Exp $
*/
public class ConnectionHelperFactory
{
/**
* @return a <code>ConnectionHelper</code> instance of the type specified
* in Cactus configuration or the default one
* (<code>JdkConnectionHelper</code>)
* @param theUrl the URL to connect to as a String
* @param theConfiguration the Cactus configuration
*/
public static ConnectionHelper getConnectionHelper(String theUrl,
Configuration theConfiguration)
{
// Load the corresponding class
ConnectionHelper connectionHelper;
try
{
Class connectionHelperClass =
Class.forName(theConfiguration.getConnectionHelper());
Constructor constructor = connectionHelperClass.getConstructor(
new Class[] {String.class});
connectionHelper = (ConnectionHelper) constructor.newInstance(
new Object[] {theUrl});
}
catch (Exception e)
{
throw new ChainedRuntimeException("Failed to load the ["
+ theConfiguration.getConnectionHelper()
+ "] ConnectionHelper " + "class", e);
}
return connectionHelper;
}
}
1.1 jakarta-cactus/framework/src/java/share/org/apache/cactus/client/connector/JdkConnectionHelper.java
Index: JdkConnectionHelper.java
===================================================================
/*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Cactus" and "Apache Software
* Foundation" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.cactus.client.connector;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.Enumeration;
import org.apache.cactus.WebRequest;
import org.apache.cactus.client.authentication.AbstractAuthentication;
import org.apache.cactus.util.ChainedRuntimeException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Implementation of <code>ConnectionHelper</code> using the JDK
* <code>HttpURLConnection</code> class.
*
* @author <a href="mailto:vmassol@apache.org">Vincent Massol</a>
* @author <a href="mailto:Jason.Robertson@acs-inc.com">Jason Robertson</a>
*
* @version $Id: JdkConnectionHelper.java,v 1.1 2003/02/22 20:24:15 vmassol Exp $
*/
public class JdkConnectionHelper extends AbstractConnectionHelper
{
/**
* The logger
*/
private static final Log LOGGER =
LogFactory.getLog(JdkConnectionHelper.class);
// Static initialisations
static
{
// Do not follow redirects (because we are doing unit tests and
// we need to be able to assert the returned headers, cookies, ...)
HttpURLConnection.setFollowRedirects(false);
}
/**
* The URL that will be used for the HTTP connection.
*/
private String url;
/**
* @param theURL the URL that will be used for the HTTP connection.
*/
public JdkConnectionHelper(String theURL)
{
this.url = theURL;
}
/**
* @see ConnectionHelper#connect(WebRequest)
*/
public HttpURLConnection connect(WebRequest theRequest) throws Throwable
{
URL url = new URL(this.url);
// Add Authentication headers, if necessary. This is the first
// step to allow authentication to add extra headers, HTTP parameters,
// etc.
AbstractAuthentication authentication = theRequest.getAuthentication();
if (authentication != null)
{
authentication.configure(theRequest);
}
// Add the parameters that need to be passed as part of the URL
url = addParametersGet(theRequest, url);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
// Choose the method that we will use to post data :
// - If at least one parameter is to be sent in the request body, then
// we are doing a POST.
// - If user data has been specified, then we are doing a POST
if (theRequest.getParameterNamesPost().hasMoreElements()
|| (theRequest.getUserData() != null))
{
connection.setDoOutput(true);
}
else
{
connection.setDoOutput(false);
}
connection.setUseCaches(false);
// Sets the content type
connection.setRequestProperty("Content-type",
theRequest.getContentType());
// Add the other header fields
addHeaders(theRequest, connection);
// Add the cookies
String cookieString = getCookieString(theRequest, url);
if (cookieString != null)
{
connection.setRequestProperty("Cookie", cookieString);
}
// Add the POST parameters if no user data has been specified (user data
// overried post parameters)
if (theRequest.getUserData() != null)
{
addUserData(theRequest, connection);
}
else
{
addParametersPost(theRequest, connection);
}
// Log content length
LOGGER.debug("ContentLength = [" + connection.getContentLength() + "]");
// Open the connection and get the result
connection.connect();
return connection;
}
/**
* Add user data in the request body.
*
* @param theRequest the request containing all data to pass to the server
* redirector.
* @param theConnection the HTTP connection
* @exception IOException if we fail to read the user data
*/
private void addUserData(WebRequest theRequest, URLConnection theConnection)
throws IOException
{
// If no user data, then exit
if (theRequest.getUserData() == null)
{
return;
}
OutputStream out = getConnectionStream(theConnection);
InputStream stream = theRequest.getUserData();
byte[] buffer = new byte[2048];
int length;
while ((length = stream.read(buffer)) != -1)
{
out.write(buffer, 0, length);
}
out.close();
}
/**
* Add the HTTP parameters that need to be passed in the request body.
*
* @param theRequest the request containing all data to pass to the server
* redirector.
* @param theConnection the HTTP connection
*/
private void addParametersPost(WebRequest theRequest,
URLConnection theConnection)
{
// If no parameters, then exit
if (!theRequest.getParameterNamesPost().hasMoreElements())
{
return;
}
PrintWriter out = new PrintWriter(getConnectionStream(theConnection));
StringBuffer queryString = new StringBuffer();
Enumeration keys = theRequest.getParameterNamesPost();
if (keys.hasMoreElements())
{
String key = (String) keys.nextElement();
String[] values = theRequest.getParameterValuesPost(key);
queryString.append(key);
queryString.append('=');
queryString.append(URLEncoder.encode(values[0]));
for (int i = 1; i < values.length; i++)
{
queryString.append('&');
queryString.append(key);
queryString.append('=');
queryString.append(URLEncoder.encode(values[i]));
}
}
while (keys.hasMoreElements())
{
String key = (String) keys.nextElement();
String[] values = theRequest.getParameterValuesPost(key);
for (int i = 0; i < values.length; i++)
{
queryString.append('&');
queryString.append(key);
queryString.append('=');
queryString.append(URLEncoder.encode(values[i]));
}
}
out.print(queryString.toString());
out.close();
}
/**
* @param theConnection the HTTP connection
* @return an output stream to write in the request body
*/
private OutputStream getConnectionStream(URLConnection theConnection)
{
OutputStream out;
try
{
out = theConnection.getOutputStream();
}
catch (IOException e)
{
// Cannot connect to server, try to explain why ...
String reason = "Cannot connect to URL [" + theConnection.getURL()
+ "]. Reason : [" + e.getMessage() + "]\r\n";
reason += "Possible reasons :\r\n";
reason += "\t- The server is not running,\r\n";
reason += ("\t- The server redirector is not correctly mapped in "
+ "web.xml,\r\n");
reason += "\t- Something else ... !";
throw new ChainedRuntimeException(reason);
}
return out;
}
/**
* Add the Headers to the request.
*
* @param theRequest the request containing all data to pass to the server
* redirector.
* @param theConnection the HTTP connection
*/
private void addHeaders(WebRequest theRequest, URLConnection theConnection)
{
Enumeration keys = theRequest.getHeaderNames();
while (keys.hasMoreElements())
{
String key = (String) keys.nextElement();
String[] values = theRequest.getHeaderValues(key);
// As the URLConnection.setRequestProperty will overwrite any
// property already set we have to regroup the multi valued
// headers into a single header name entry.
// Question: Is this an implementation bug ? It seems because
// on the server side, I cannot use the request.getHeaders() (it
// only returns a single header).
StringBuffer fullHeaderValue = new StringBuffer(values[0]);
for (int i = 1; i < values.length; i++)
{
fullHeaderValue.append("," + values[i]);
}
theConnection.setRequestProperty(key, fullHeaderValue.toString());
}
}
}
1.1 jakarta-cactus/framework/src/java/share/org/apache/cactus/client/connector/DefaultHttpClient.java
Index: DefaultHttpClient.java
===================================================================
/*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Cactus" and "Apache Software
* Foundation" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.cactus.client.connector;
import java.net.HttpURLConnection;
import org.apache.cactus.HttpServiceDefinition;
import org.apache.cactus.ServiceEnumeration;
import org.apache.cactus.WebRequest;
import org.apache.cactus.WebResponse;
import org.apache.cactus.WebTestResult;
import org.apache.cactus.client.AssertionFailedErrorWrapper;
import org.apache.cactus.client.ParsingException;
import org.apache.cactus.client.ServletExceptionWrapper;
import org.apache.cactus.client.WebTestResultParser;
import org.apache.cactus.configuration.WebConfiguration;
import org.apache.cactus.util.ChainedRuntimeException;
import org.apache.cactus.util.IoUtil;
/**
* Performs the steps necessary to run a test. It involves
* opening a first HTTP connection to a server redirector, reading the output
* stream and then opening a second HTTP connection to retrieve the test
* result.
*
* @author <a href="mailto:vmassol@apache.org">Vincent Massol</a>
* @author <a href="mailto:Jason.Robertson@acs-inc.com">Jason Robertson</a>
*
* @version $Id: DefaultHttpClient.java,v 1.1 2003/02/22 20:24:15 vmassol Exp $
*/
public class DefaultHttpClient
{
/**
* Cactus configuration.
*/
protected WebConfiguration configuration;
/**
* Initialize the Http client.
*
* @param theConfiguration the Cactus configuration
*/
public DefaultHttpClient(WebConfiguration theConfiguration)
{
this.configuration = theConfiguration;
}
/**
* Calls the test method indirectly by calling the Redirector servlet and
* then open a second HTTP connection to retrieve the test results.
*
* @param theRequest the request containing all data to pass to the
* redirector servlet.
*
* @return the <code>HttpURLConnection</code> that contains the HTTP
* response when the test was called.
*
* @exception Throwable if an error occured in the test method or in the
* redirector servlet.
*/
public HttpURLConnection doTest(WebRequest theRequest) throws Throwable
{
// Open the first connection to the redirector to execute the test on
// the server side
HttpURLConnection connection = callRunTest(theRequest);
// Open the second connection to get the test results
WebTestResult result = null;
try
{
result = callGetResult(theRequest);
}
catch (ParsingException e)
{
throw new ChainedRuntimeException("Failed to get the test "
+ "results. This is probably due to an error that happened on "
+ "the server side when trying to execute the tests. Here is "
+ "what was returned by the server : ["
+ new WebResponse(theRequest, connection).getText() + "]", e);
}
// Check if the returned result object returned contains an error or
// not. If yes, we need to raise an exception so that the JUnit
// framework can catch it
if (result.hasException())
{
// Wrap the exception message and stack trace into a fake
// exception class with overloaded <code>printStackTrace()</code>
// methods so that when JUnit calls this method it will print the
// stack trace that was set on the server side.
// If the error was an AssertionFailedError then we use an instance
// of AssertionFailedErrorWrapper (so that JUnit recognize it is
// an AssertionFailedError exception and print it differently in
// it's runner console). Otherwise we use an instance of
// ServletExceptionWrapper.
if (result.getExceptionClassName().equals(
"junit.framework.AssertionFailedError"))
{
throw new AssertionFailedErrorWrapper(
result.getExceptionMessage(),
result.getExceptionClassName(),
result.getExceptionStackTrace());
}
else
{
throw new ServletExceptionWrapper(
result.getExceptionMessage(),
result.getExceptionClassName(),
result.getExceptionStackTrace());
}
}
return connection;
}
/**
* Execute the test by calling the redirector.
*
* @param theRequest the request containing all data to pass to the
* redirector servlet.
* @return the <code>HttpURLConnection</code> that contains the HTTP
* response when the test was called.
*
* @exception Throwable if an error occured in the test method or in the
* redirector servlet.
*/
private HttpURLConnection callRunTest(WebRequest theRequest)
throws Throwable
{
// Specify the service to call on the redirector side
theRequest.addParameter(HttpServiceDefinition.SERVICE_NAME_PARAM,
ServiceEnumeration.CALL_TEST_SERVICE.toString(),
WebRequest.GET_METHOD);
// Open the first connection to the redirector to execute the test on
// the server side
ConnectionHelper helper = ConnectionHelperFactory.getConnectionHelper(
this.configuration.getRedirectorURL(theRequest),
this.configuration);
HttpURLConnection connection = helper.connect(theRequest);
// Wrap the connection to ensure that all servlet output is read
// before we ask for results
connection = new AutoReadHttpURLConnection(connection);
// Trigger the transfer of data
connection.getInputStream();
return connection;
}
/**
* Get the test result from the redirector.
*
* @param theOriginalRequest the request that was used to run the test
* @return the result that was returned by the redirector.
*
* @exception Throwable if an error occured in the test method or in the
* redirector servlet.
*/
private WebTestResult callGetResult(WebRequest theOriginalRequest)
throws Throwable
{
WebRequest resultsRequest = new WebRequest(this.configuration);
resultsRequest.addParameter(HttpServiceDefinition.SERVICE_NAME_PARAM,
ServiceEnumeration.GET_RESULTS_SERVICE.toString(),
WebRequest.GET_METHOD);
// Use the same redirector as was used by the original request
resultsRequest.setRedirectorName(
theOriginalRequest.getRedirectorName());
// Add authentication details
if (theOriginalRequest.getAuthentication() != null)
{
resultsRequest.setAuthentication(
theOriginalRequest.getAuthentication());
}
// Open the second connection to get the test results
ConnectionHelper helper = ConnectionHelperFactory.getConnectionHelper(
this.configuration.getRedirectorURL(resultsRequest),
this.configuration);
HttpURLConnection resultConnection = helper.connect(resultsRequest);
// Read the test result
WebTestResultParser parser = new WebTestResultParser();
WebTestResult result = parser.parse(
IoUtil.getText(resultConnection.getInputStream(), "UTF-8"));
return result;
}
}
1.1 jakarta-cactus/framework/src/java/share/org/apache/cactus/client/connector/AbstractConnectionHelper.java
Index: AbstractConnectionHelper.java
===================================================================
/*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Cactus" and "Apache Software
* Foundation" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.cactus.client.connector;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Enumeration;
import java.util.Vector;
import org.apache.cactus.Cookie;
import org.apache.cactus.WebRequest;
import org.apache.cactus.client.ClientException;
import org.apache.commons.httpclient.Header;
/**
* Common helper methods for implementing <code>ConnectionHelper</code>. These
* methods are common to any implementation.
*
* @author <a href="mailto:vmassol@apache.org">Vincent Massol</a>
*
* @version $Id: AbstractConnectionHelper.java,v 1.1 2003/02/22 20:24:15 vmassol Exp $
*/
public abstract class AbstractConnectionHelper
implements ConnectionHelper
{
/**
* Add the HTTP parameters that need to be passed in the query string of
* the URL.
*
* @param theRequest the request containing all data to pass to the server
* redirector.
* @param theURL the URL used to connect to the server redirector.
* @return the new URL
* @exception MalformedURLException if the URL is malformed
*/
protected URL addParametersGet(WebRequest theRequest, URL theURL)
throws MalformedURLException
{
// If no parameters, then exit
if (!theRequest.getParameterNamesGet().hasMoreElements())
{
return theURL;
}
StringBuffer queryString = new StringBuffer();
Enumeration keys = theRequest.getParameterNamesGet();
if (keys.hasMoreElements())
{
String key = (String) keys.nextElement();
String[] values = theRequest.getParameterValuesGet(key);
queryString.append(key);
queryString.append('=');
queryString.append(URLEncoder.encode(values[0]));
for (int i = 1; i < values.length; i++)
{
queryString.append('&');
queryString.append(key);
queryString.append('=');
queryString.append(URLEncoder.encode(values[i]));
}
}
while (keys.hasMoreElements())
{
String key = (String) keys.nextElement();
String[] values = theRequest.getParameterValuesGet(key);
for (int i = 0; i < values.length; i++)
{
queryString.append('&');
queryString.append(key);
queryString.append('=');
queryString.append(URLEncoder.encode(values[i]));
}
}
String file = theURL.getFile();
// Remove the trailing "/" if there is one
if (file.endsWith("/"))
{
file = file.substring(0, file.length() - 1);
}
if (theURL.toString().indexOf("?") > 0)
{
file = file + "&" + queryString.toString();
}
else
{
file = file + "?" + queryString.toString();
}
return new URL(theURL.getProtocol(), theURL.getHost(),
theURL.getPort(), file);
}
/**
* @return the cookie string which will be added as a HTTP "Cookie" header
* or null if no cookie has been set
* @param theRequest the request containing all data to pass to the server
* redirector.
* @param theUrl the URL to connect to
* @throws ClientException if an error occurred when creating the cookie
* string
*/
public String getCookieString(WebRequest theRequest, URL theUrl)
throws ClientException
{
// If no Cookies, then exit
Vector cookies = theRequest.getCookies();
if (!cookies.isEmpty())
{
// transform the Cactus cookies into HttpClient cookies
org.apache.commons.httpclient.Cookie[] httpclientCookies =
new org.apache.commons.httpclient.Cookie[cookies.size()];
for (int i = 0; i < cookies.size(); i++)
{
Cookie cactusCookie = (Cookie) cookies.elementAt(i);
// If no domain has been specified, use a default one
String domain;
if (cactusCookie.getDomain() == null)
{
domain = Cookie.getCookieDomain(theRequest,
theUrl.getHost());
}
else
{
domain = cactusCookie.getDomain();
}
// If not path has been specified , use a default one
String path;
if (cactusCookie.getPath() == null)
{
path = Cookie.getCookiePath(theRequest, theUrl.getFile());
}
else
{
path = cactusCookie.getPath();
}
httpclientCookies[i] = new org.apache.commons.httpclient.Cookie(
domain, cactusCookie.getName(), cactusCookie.getValue());
httpclientCookies[i].setComment(cactusCookie.getComment());
httpclientCookies[i].setExpiryDate(
cactusCookie.getExpiryDate());
httpclientCookies[i].setPath(path);
httpclientCookies[i].setSecure(cactusCookie.isSecure());
}
// and create the cookie header to send
Header cookieHeader = createCookieHeader(
Cookie.getCookieDomain(theRequest, theUrl.getHost()),
Cookie.getCookiePath(theRequest, theUrl.getFile()),
httpclientCookies);
return cookieHeader.getValue();
}
return null;
}
/**
* Create a HttpClient {@link Header} for cookies that matches
* the domain and path.
*
* @param theDomain the cookie domain to match
* @param thePath the cookie path to match
* @param theCookies the list of potential cookies
* @return the HttpClient {@link Header} containing the matching
* cookies
* @throws ClientException if no cookie was matching the domain
* and path
*/
private Header createCookieHeader(String theDomain, String thePath,
org.apache.commons.httpclient.Cookie[] theCookies)
throws ClientException
{
Header cookieHeader =
org.apache.commons.httpclient.Cookie.createCookieHeader(
theDomain, thePath, theCookies);
if (cookieHeader == null)
{
throw new ClientException("Failed to create Cookie header for ["
+ "domain = [" + theDomain + ", path = [" + thePath
+ ", cookies = [" + theCookies + "]]. Turn on HttpClient "
+ "logging for more information about the error");
}
return cookieHeader;
}
}
1.1 jakarta-cactus/framework/src/java/share/org/apache/cactus/client/connector/AutoReadHttpURLConnection.java
Index: AutoReadHttpURLConnection.java
===================================================================
/*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Cactus" and "Apache Software
* Foundation" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.cactus.client.connector;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.ProtocolException;
import java.net.URL;
import java.security.Permission;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Wrapper class for the real <code>HttpURLConnection</code> to the test servlet
* that reads the complete input stream into an internal buffer on
* the first call to getInputStream(). This is to ensure that the test servlet
* is not blocked on i/o when the test caller asks for the results.
* <p>
* The wrapper returns the buffered input stream from getInputStream and
* delegates the rest of the calls.
* <p>
* This class is final so we don't have to provide access to protected instance
* variables and methods of the wrapped connection.
*
* @author <a href="mailto:Bob.Davison@reuters.com">Bob Davison</a>
* @author <a href="mailto:vmassol@apache.org">Vincent Massol</a>
*
* @version $Id: AutoReadHttpURLConnection.java,v 1.1 2003/02/22 20:24:15 vmassol Exp $
*/
final class AutoReadHttpURLConnection extends HttpURLConnection
{
/**
* The logger
*/
private static final Log LOGGER =
LogFactory.getLog(AutoReadHttpURLConnection.class);
/**
* Default size of array for copying data.
*/
private static final int DEFAULT_CHUNK_SIZE = 16384;
/**
* The wrapped connection.
*/
private HttpURLConnection delegate;
/**
* The read input stream.
*/
private InputStream streamBuffer;
/**
* Constructs a an <code>AutoReadHttpURLConnection</code> object from an
* <code>HttpURLConnection</code>.
*
* @param theConnection the original connection to wrap
*/
AutoReadHttpURLConnection(HttpURLConnection theConnection)
{
super(null);
this.delegate = theConnection;
}
/**
* Returns an input stream containing the fully read contents of
* the wrapped connection's input stream
*
* @return the input stream
* @exception IOException if an error occurs when reading the input stream
*/
public synchronized InputStream getInputStream() throws IOException
{
// Catch IOException to log the content of the error stream
try
{
if (this.streamBuffer == null)
{
LOGGER.debug("Original connection = " + this.delegate);
InputStream is = this.delegate.getInputStream();
this.streamBuffer = getBufferedInputStream(is);
}
}
catch (IOException e)
{
logErrorStream(this.delegate.getErrorStream());
throw e;
}
return this.streamBuffer;
}
/**
* Logs the HTTP error stream (used to get more information when we fail
* to read from the HTTP URL connection).
*
* @param theErrorStream the error stream containing the error description
* @exception IOException if an error occurs when reading the input stream
*/
private void logErrorStream(InputStream theErrorStream) throws IOException
{
if (theErrorStream != null)
{
// Log content of error stream
BufferedReader errorStream =
new BufferedReader(new InputStreamReader(theErrorStream));
String buffer;
while ((buffer = errorStream.readLine()) != null)
{
LOGGER.debug("ErrorStream [" + buffer + "]");
}
}
}
/**
* Fully read the HTTP Connection response stream until there is no
* more bytes to read.
*
* @param theInputStream the input stream to fully read
* @return the data read as a buffered input stream
* @exception IOException if an error occurs when reading the input stream
*/
private InputStream getBufferedInputStream(InputStream theInputStream)
throws IOException
{
ByteArrayOutputStream os =
new ByteArrayOutputStream(DEFAULT_CHUNK_SIZE);
copy(theInputStream, os);
ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray());
return bais;
}
/**
* Copies the input stream passed as parameter to the output stream also
* passed as parameter. The full stream is read until there is no more
* bytes to read.
*
* @param theInputStream the input stream to read from
* @param theOutputStream the output stream to write to
* @exception IOException if an error occurs when reading the input stream
*/
private void copy(InputStream theInputStream, OutputStream theOutputStream)
throws IOException
{
// Only copy if there are data to copy ... The problem is that not
// all servers return a content-length header. If there is no header
// getContentLength() returns -1. It seems to work and it seems
// that all servers that return no content-length header also do
// not block on read() operations !
LOGGER.debug("Content-Length : [" + this.delegate.getContentLength()
+ "]");
if (this.delegate.getContentLength() != 0)
{
byte[] buf = new byte[DEFAULT_CHUNK_SIZE];
int count;
while (-1 != (count = theInputStream.read(buf)))
{
// log read data
printReadLogs(count, buf);
theOutputStream.write(buf, 0, count);
}
}
}
/**
* Format log data read from socket for pretty printing (replaces
* asc char 10 by "\r", asc char 13 by "\n").
*
* @param theCount the number of bytes read in the buffer
* @param theBuffer the buffer containing the data to print
*/
private void printReadLogs(int theCount, byte[] theBuffer)
{
// Log portion of read data and replace asc 10 by \r and asc
// 13 by /n
StringBuffer prefix = new StringBuffer();
for (int i = 0; i < theCount; i++)
{
if (theBuffer[i] == 10)
{
prefix.append("\\r");
}
else if (theBuffer[i] == 13)
{
prefix.append("\\n");
}
else
{
prefix.append((char) theBuffer[i]);
}
}
LOGGER.debug("Read [" + theCount + "]: [" + prefix + "]");
}
// Delegated methods
/**
* @see java.net.HttpURLConnection#connect()
*/
public void connect() throws IOException
{
this.delegate.connect();
}
/**
* @see java.net.HttpURLConnection#getAllowUserInteraction()
*/
public boolean getAllowUserInteraction()
{
return this.delegate.getAllowUserInteraction();
}
/**
* @see java.net.HttpURLConnection#getContent()
*/
public Object getContent() throws IOException
{
return this.delegate.getContent();
}
/**
* @see java.net.HttpURLConnection#getContentEncoding()
*/
public String getContentEncoding()
{
return this.delegate.getContentEncoding();
}
/**
* @see java.net.HttpURLConnection#getContentLength()
*/
public int getContentLength()
{
return this.delegate.getContentLength();
}
/**
* @see java.net.HttpURLConnection#getContentType()
*/
public String getContentType()
{
return this.delegate.getContentType();
}
/**
* @see java.net.HttpURLConnection#getDate()
*/
public long getDate()
{
return this.delegate.getDate();
}
/**
* @see java.net.HttpURLConnection#getDefaultUseCaches()
*/
public boolean getDefaultUseCaches()
{
return this.delegate.getDefaultUseCaches();
}
/**
* @see java.net.HttpURLConnection#getDoInput()
*/
public boolean getDoInput()
{
return this.delegate.getDoInput();
}
/**
* @see java.net.HttpURLConnection#getDoOutput()
*/
public boolean getDoOutput()
{
return this.delegate.getDoOutput();
}
/**
* @see java.net.HttpURLConnection#getExpiration()
*/
public long getExpiration()
{
return this.delegate.getExpiration();
}
/**
* @see java.net.HttpURLConnection#getHeaderField(int)
*/
public String getHeaderField(int thePosition)
{
return this.delegate.getHeaderField(thePosition);
}
/**
* @see java.net.HttpURLConnection#getHeaderField(String)
*/
public String getHeaderField(String theName)
{
return this.delegate.getHeaderField(theName);
}
/**
* @see java.net.HttpURLConnection#getHeaderFieldDate(String, long)
*/
public long getHeaderFieldDate(String theName, long theDefaultValue)
{
return this.delegate.getHeaderFieldDate(theName, theDefaultValue);
}
/**
* @see java.net.HttpURLConnection#getHeaderFieldInt(String, int)
*/
public int getHeaderFieldInt(String theName, int theDefaultValue)
{
return this.delegate.getHeaderFieldInt(theName, theDefaultValue);
}
/**
* @see java.net.HttpURLConnection#getHeaderFieldKey(int)
*/
public String getHeaderFieldKey(int thePosition)
{
return this.delegate.getHeaderFieldKey(thePosition);
}
/**
* @see java.net.HttpURLConnection#getIfModifiedSince()
*/
public long getIfModifiedSince()
{
return this.delegate.getIfModifiedSince();
}
/**
* @see java.net.HttpURLConnection#getLastModified()
*/
public long getLastModified()
{
return this.delegate.getLastModified();
}
/**
* @see java.net.HttpURLConnection#getOutputStream()
*/
public OutputStream getOutputStream() throws IOException
{
return this.delegate.getOutputStream();
}
/**
* @see java.net.HttpURLConnection#getPermission()
*/
public Permission getPermission() throws IOException
{
return this.delegate.getPermission();
}
/**
* @see java.net.HttpURLConnection#getRequestProperty(String)
*/
public String getRequestProperty(String theKey)
{
return this.delegate.getRequestProperty(theKey);
}
/**
* @see java.net.HttpURLConnection#getURL()
*/
public URL getURL()
{
return this.delegate.getURL();
}
/**
* @see java.net.HttpURLConnection#getUseCaches()
*/
public boolean getUseCaches()
{
return this.delegate.getUseCaches();
}
/**
* @see java.net.HttpURLConnection#setAllowUserInteraction(boolean)
*/
public void setAllowUserInteraction(boolean hasInteraction)
{
this.delegate.setAllowUserInteraction(hasInteraction);
}
/**
* @see java.net.HttpURLConnection#setDefaultUseCaches(boolean)
*/
public void setDefaultUseCaches(boolean isUsingDefaultCache)
{
this.delegate.setDefaultUseCaches(isUsingDefaultCache);
}
/**
* @see java.net.HttpURLConnection#setDoInput(boolean)
*/
public void setDoInput(boolean isInput)
{
this.delegate.setDoInput(isInput);
}
/**
* @see java.net.HttpURLConnection#setDoOutput(boolean)
*/
public void setDoOutput(boolean isOutput)
{
this.delegate.setDoOutput(isOutput);
}
/**
* @see java.net.HttpURLConnection#setIfModifiedSince(long)
*/
public void setIfModifiedSince(long isModifiedSince)
{
this.delegate.setIfModifiedSince(isModifiedSince);
}
/**
* @see java.net.HttpURLConnection#setRequestProperty(String, String)
*/
public void setRequestProperty(String theKey, String theValue)
{
this.delegate.setRequestProperty(theKey, theValue);
}
/**
* @see java.net.HttpURLConnection#setUseCaches(boolean)
*/
public void setUseCaches(boolean isUsingCaches)
{
this.delegate.setUseCaches(isUsingCaches);
}
/**
* @see java.net.HttpURLConnection#toString()
*/
public String toString()
{
return this.delegate.toString();
}
/**
* @see java.net.HttpURLConnection#disconnect()
*/
public void disconnect()
{
this.delegate.disconnect();
}
/**
* @see java.net.HttpURLConnection#getErrorStream()
*/
public InputStream getErrorStream()
{
return this.delegate.getErrorStream();
}
/**
* @see java.net.HttpURLConnection#getRequestMethod()
*/
public String getRequestMethod()
{
return this.delegate.getRequestMethod();
}
/**
* @see java.net.HttpURLConnection#getResponseCode()
*/
public int getResponseCode() throws IOException
{
return this.delegate.getResponseCode();
}
/**
* @see java.net.HttpURLConnection#getResponseMessage()
*/
public String getResponseMessage() throws IOException
{
return this.delegate.getResponseMessage();
}
/**
* @see java.net.HttpURLConnection#setRequestMethod(String)
*/
public void setRequestMethod(String theMethod) throws ProtocolException
{
this.delegate.setRequestMethod(theMethod);
}
/**
* @see java.net.HttpURLConnection#usingProxy()
*/
public boolean usingProxy()
{
return this.delegate.usingProxy();
}
}
1.1 jakarta-cactus/framework/src/java/share/org/apache/cactus/client/connector/ConnectionHelper.java
Index: ConnectionHelper.java
===================================================================
/*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Cactus" and "Apache Software
* Foundation" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.cactus.client.connector;
import java.net.HttpURLConnection;
import org.apache.cactus.WebRequest;
/**
* Helper class to open an HTTP connection to the server redirector and pass
* to it HTTP parameters, Cookies and HTTP headers. It enables different
* possible implementations of an HTTP connection (ex: using the JDK
* <code>HttpURLConnection</code> or using Jakarta HttpClient).
*
* @author <a href="mailto:vmassol@apache.org">Vincent Massol</a>
*
* @version $Id: ConnectionHelper.java,v 1.1 2003/02/22 20:24:15 vmassol Exp $
*/
public interface ConnectionHelper
{
/**
* Connects to the Cactus Redirector using HTTP.
*
* @param theRequest the request containing all data to pass to the
* server redirector.
* @return the HTTP Connection used to connect to the redirector.
* @exception Throwable if an unexpected error occured
*/
HttpURLConnection connect(WebRequest theRequest) throws Throwable;
}
1.1 jakarta-cactus/framework/src/java/share/org/apache/cactus/client/connector/HttpClientConnectionHelper.java
Index: HttpClientConnectionHelper.java
===================================================================
/*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Cactus" and "Apache Software
* Foundation" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.cactus.client.connector;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Enumeration;
import org.apache.cactus.WebRequest;
import org.apache.cactus.client.authentication.AbstractAuthentication;
import org.apache.cactus.util.UrlUtil;
import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.protocol.Protocol;
/**
* Implementation of <code>ConnectionHelper</code> using Jakarta Commons
* HttpClient.
*
* @author <a href="mailto:vmassol@apache.org">Vincent Massol</a>
*
* @version $Id: HttpClientConnectionHelper.java,v 1.1 2003/02/22 20:24:15 vmassol Exp $
*/
public class HttpClientConnectionHelper extends AbstractConnectionHelper
{
/**
* The <code>HttpMethod</code> used to connect to the HTTP server. It is
* either a <code>GetMethod</code> or a <code>PostMethod</code>.
*/
private GetMethod method;
/**
* The URL that will be used for the HTTP connection.
*/
private String url;
/**
* @param theURL the URL that will be used for the HTTP connection.
*/
public HttpClientConnectionHelper(String theURL)
{
this.url = theURL;
}
/**
* @see ConnectionHelper#connect(WebRequest)
*/
public HttpURLConnection connect(WebRequest theRequest) throws Throwable
{
URL url = new URL(this.url);
// Add Authentication headers, if necessary. This is the first
// step to allow authentication to add extra headers, HTTP parameters,
// etc.
AbstractAuthentication authentication = theRequest.getAuthentication();
if (authentication != null)
{
authentication.configure(theRequest);
}
// Add the parameters that need to be passed as part of the URL
url = addParametersGet(theRequest, url);
// Choose the method that we will use to post data :
// - If at least one parameter is to be sent in the request body, then
// we are doing a POST.
// - If user data has been specified, then we are doing a POST
if (theRequest.getParameterNamesPost().hasMoreElements()
|| (theRequest.getUserData() != null))
{
this.method = new PostMethod();
}
else
{
this.method = new GetMethod();
}
this.method.setUseDisk(false);
this.method.setFollowRedirects(false);
this.method.setPath(UrlUtil.getPath(url));
this.method.setQueryString(UrlUtil.getQuery(url));
// Sets the content type
this.method.setRequestHeader("Content-type",
theRequest.getContentType());
// Add the other header fields
addHeaders(theRequest);
// Add the cookies
String cookieString = getCookieString(theRequest, url);
if (cookieString != null)
{
this.method.addRequestHeader("Cookie", cookieString);
}
// Add the POST parameters if no user data has been specified (user data
// overried post parameters)
if (theRequest.getUserData() != null)
{
addUserData(theRequest);
}
else
{
addParametersPost(theRequest);
}
// Open the connection and get the result
HttpClient client = new HttpClient();
HostConfiguration hostConfiguration = new HostConfiguration();
hostConfiguration.setHost(url.getHost(), url.getPort(),
Protocol.getProtocol(url.getProtocol()));
client.executeMethod(hostConfiguration, this.method);
// Wrap the HttpClient method in a java.net.HttpURLConnection object
return new org.apache.commons.httpclient.util.HttpURLConnection(
this.method, url);
}
/**
* Add the HTTP parameters that need to be passed in the request body.
*
* @param theRequest the request containing all data to pass to the server
* redirector.
*/
private void addParametersPost(WebRequest theRequest)
{
// If no parameters, then exit
if (!theRequest.getParameterNamesPost().hasMoreElements())
{
return;
}
Enumeration keys = theRequest.getParameterNamesPost();
while (keys.hasMoreElements())
{
String key = (String) keys.nextElement();
String[] values = theRequest.getParameterValuesPost(key);
for (int i = 0; i < values.length; i++)
{
((PostMethod) this.method).addParameter(key, values[i]);
}
}
}
/**
* Add the Headers to the request.
*
* @param theRequest the request containing all data to pass to the server
* redirector.
*/
private void addHeaders(WebRequest theRequest)
{
Enumeration keys = theRequest.getHeaderNames();
while (keys.hasMoreElements())
{
String key = (String) keys.nextElement();
String[] values = theRequest.getHeaderValues(key);
StringBuffer fullHeaderValue = new StringBuffer(values[0]);
for (int i = 1; i < values.length; i++)
{
fullHeaderValue.append("," + values[i]);
}
this.method.addRequestHeader(key, fullHeaderValue.toString());
}
}
/**
* Add user data in the request body.
*
* @param theRequest the request containing all data to pass to the server
* redirector.
* @exception IOException if we fail to read the user data
*/
private void addUserData(WebRequest theRequest) throws IOException
{
// If no user data, then exit
if (theRequest.getUserData() == null)
{
return;
}
((PostMethod) this.method).setRequestBody(theRequest.getUserData());
}
}
1.9 +2 -2 jakarta-cactus/framework/src/java/share/org/apache/cactus/client/authentication/FormAuthentication.java
Index: FormAuthentication.java
===================================================================
RCS file: /home/cvs/jakarta-cactus/framework/src/java/share/org/apache/cactus/client/authentication/FormAuthentication.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- FormAuthentication.java 22 Feb 2003 11:31:49 -0000 1.8
+++ FormAuthentication.java 22 Feb 2003 20:24:15 -0000 1.9
@@ -61,8 +61,8 @@
import java.net.URL;
import org.apache.cactus.WebRequest;
-import org.apache.cactus.client.ConnectionHelper;
-import org.apache.cactus.client.ConnectionHelperFactory;
+import org.apache.cactus.client.connector.ConnectionHelper;
+import org.apache.cactus.client.connector.ConnectionHelperFactory;
import org.apache.cactus.configuration.WebConfiguration;
import org.apache.cactus.util.ChainedRuntimeException;
import org.apache.commons.logging.Log;
1.2 +3 -3 jakarta-cactus/framework/src/java/share/org/apache/cactus/configuration/Configuration.java
Index: Configuration.java
===================================================================
RCS file: /home/cvs/jakarta-cactus/framework/src/java/share/org/apache/cactus/configuration/Configuration.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Configuration.java 22 Feb 2003 11:31:49 -0000 1.1
+++ Configuration.java 22 Feb 2003 20:24:15 -0000 1.2
@@ -71,8 +71,8 @@
String getContextURL();
/**
- * @return the {@link org.apache.cactus.client.ConnectionHelper} classname
- * to use for opening the HTTP connection
+ * @return the {@link org.apache.cactus.client.connector.ConnectionHelper}
+ * classname to use for opening the HTTP connection
*/
String getConnectionHelper();
1.2 +6 -5 jakarta-cactus/framework/src/java/share/org/apache/cactus/configuration/BaseConfiguration.java
Index: BaseConfiguration.java
===================================================================
RCS file: /home/cvs/jakarta-cactus/framework/src/java/share/org/apache/cactus/configuration/BaseConfiguration.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- BaseConfiguration.java 22 Feb 2003 11:31:49 -0000 1.1
+++ BaseConfiguration.java 22 Feb 2003 20:24:15 -0000 1.2
@@ -64,7 +64,7 @@
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
-import org.apache.cactus.client.HttpClientConnectionHelper;
+import org.apache.cactus.client.connector.HttpClientConnectionHelper;
import org.apache.cactus.util.ChainedRuntimeException;
import org.apache.cactus.util.ClassLoaderUtils;
@@ -110,7 +110,8 @@
"cactus.connectionHelper.classname";
/**
- * Default {@link org.apache.cactus.client.ConnectionHelper} to use.
+ * Default {@link org.apache.cactus.client.connector.ConnectionHelper} to
+ * use.
*/
public static final String DEFAULT_CACTUS_CONNECTION_HELPER_CLASSNAME =
HttpClientConnectionHelper.class.getName();
@@ -212,8 +213,8 @@
}
/**
- * @return the {@link org.apache.cactus.client.ConnectionHelper} classname
- * to use for opening the HTTP connection
+ * @return the {@link org.apache.cactus.client.connector.ConnectionHelper}
+ * classname to use for opening the HTTP connection
*/
public String getConnectionHelper()
{
1.3 +2 -2 jakarta-cactus/framework/src/java/share/org/apache/cactus/AbstractWebServerTestCase.java
Index: AbstractWebServerTestCase.java
===================================================================
RCS file: /home/cvs/jakarta-cactus/framework/src/java/share/org/apache/cactus/AbstractWebServerTestCase.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- AbstractWebServerTestCase.java 22 Feb 2003 11:31:49 -0000 1.2
+++ AbstractWebServerTestCase.java 22 Feb 2003 20:24:16 -0000 1.3
@@ -61,7 +61,7 @@
import java.lang.reflect.Modifier;
import java.net.HttpURLConnection;
-import org.apache.cactus.client.DefaultHttpClient;
+import org.apache.cactus.client.connector.DefaultHttpClient;
import org.apache.cactus.configuration.WebConfiguration;
import org.apache.commons.logging.LogFactory;
1.15 +3 -3 jakarta-cactus/framework/src/java/share/org/apache/cactus/WebRequest.java
Index: WebRequest.java
===================================================================
RCS file: /home/cvs/jakarta-cactus/framework/src/java/share/org/apache/cactus/WebRequest.java,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- WebRequest.java 22 Feb 2003 11:31:49 -0000 1.14
+++ WebRequest.java 22 Feb 2003 20:24:16 -0000 1.15
@@ -60,9 +60,9 @@
import java.util.StringTokenizer;
import org.apache.cactus.client.ClientException;
-import org.apache.cactus.client.ConnectionHelper;
-import org.apache.cactus.client.ConnectionHelperFactory;
import org.apache.cactus.client.WebResponseObjectFactory;
+import org.apache.cactus.client.connector.ConnectionHelper;
+import org.apache.cactus.client.connector.ConnectionHelperFactory;
import org.apache.cactus.configuration.WebConfiguration;
import org.apache.cactus.util.ChainedRuntimeException;
1.11 +2 -2 jakarta-cactus/framework/src/java/j2ee13/org/apache/cactus/util/FilterConfiguration.java
Index: FilterConfiguration.java
===================================================================
RCS file: /home/cvs/jakarta-cactus/framework/src/java/j2ee13/org/apache/cactus/util/FilterConfiguration.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- FilterConfiguration.java 3 Jan 2003 15:43:22 -0000 1.10
+++ FilterConfiguration.java 22 Feb 2003 20:24:16 -0000 1.11
@@ -74,7 +74,7 @@
"cactus.filterRedirectorName";
/**
- * @see WebConfiguration#getDefaultRedirectorName()
+ * @see AbstractWebConfiguration#getDefaultRedirectorName()
*/
public String getDefaultRedirectorName()
{
---------------------------------------------------------------------
To unsubscribe, e-mail: cactus-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: cactus-dev-help@jakarta.apache.org