353623 Added new methods to HttpExchange

This commit is contained in:
Michael Gorovoy 2011-08-25 21:56:40 -04:00
parent e620f43663
commit 103d7a87c2
11 changed files with 165 additions and 68 deletions

View File

@ -1,4 +1,5 @@
jetty-7.5.0-SNAPSHOT
+ 353623 Added new methods to HttpExchange
+ 353624 HttpURI accepts java.net.URI object in constructor
+ 354080 ServletContextHandler allows to replace any subordinate handler when restarted

View File

@ -675,7 +675,7 @@ public class HttpDestination implements Dumpable
setMethod(HttpMethods.CONNECT);
setVersion(exchange.getVersion());
String serverHostAndPort = serverAddress.toString();
setURI(serverHostAndPort);
setRequestURI(serverHostAndPort);
addRequestHeader(HttpHeaders.HOST, serverHostAndPort);
addRequestHeader(HttpHeaders.PROXY_CONNECTION, "keep-alive");
addRequestHeader(HttpHeaders.USER_AGENT, "Jetty-Client");

View File

@ -15,6 +15,7 @@ package org.eclipse.jetty.client;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.concurrent.atomic.AtomicInteger;
import org.eclipse.jetty.client.security.SecurityListener;
@ -37,8 +38,8 @@ import org.eclipse.jetty.util.thread.Timeout;
*
* This object encapsulates:
* <ul>
* <li>The HTTP server address, see {@link #setAddress(Address)} or {@link #setURL(String)})
* <li>The HTTP request method, URI and HTTP version (see {@link #setMethod(String)}, {@link #setURI(String)}, and {@link #setVersion(int)}
* <li>The HTTP server address, see {@link #setAddress(Address)}, or {@link #setURI(URI)}, or {@link #setURL(String)})
* <li>The HTTP request method, URI and HTTP version (see {@link #setMethod(String)}, {@link #setRequestURI(String)}, and {@link #setVersion(int)})
* <li>The request headers (see {@link #addRequestHeader(String, String)} or {@link #setRequestHeader(String, String)})
* <li>The request content (see {@link #setRequestContent(Buffer)} or {@link #setRequestContentSource(InputStream)})
* <li>The status of the exchange (see {@link #getStatus()})
@ -391,33 +392,11 @@ public class HttpExchange
}
/**
* @param url Including protocol, host and port
* @param url an absolute URL (for example 'http://localhost/foo/bar?a=1')
*/
public void setURL(String url)
{
HttpURI uri = new HttpURI(url);
String scheme = uri.getScheme();
if (scheme != null)
{
if (HttpSchemes.HTTP.equalsIgnoreCase(scheme))
setScheme(HttpSchemes.HTTP_BUFFER);
else if (HttpSchemes.HTTPS.equalsIgnoreCase(scheme))
setScheme(HttpSchemes.HTTPS_BUFFER);
else
setScheme(new ByteArrayBuffer(scheme));
}
int port = uri.getPort();
if (port <= 0)
port = "https".equalsIgnoreCase(scheme)?443:80;
setAddress(new Address(uri.getHost(),port));
String completePath = uri.getCompletePath();
if (completePath == null)
completePath = "/";
setURI(completePath);
setURI(URI.create(url));
}
/**
@ -456,6 +435,22 @@ public class HttpExchange
{
_scheme = scheme;
}
/**
* @param scheme the scheme of the URL (for example 'http')
*/
public void setScheme(String scheme)
{
if (scheme != null)
{
if (HttpSchemes.HTTP.equalsIgnoreCase(scheme))
setScheme(HttpSchemes.HTTP_BUFFER);
else if (HttpSchemes.HTTPS.equalsIgnoreCase(scheme))
setScheme(HttpSchemes.HTTPS_BUFFER);
else
setScheme(new ByteArrayBuffer(scheme));
}
}
/**
* @return the scheme of the URL
@ -511,20 +506,81 @@ public class HttpExchange
}
/**
* @return the path of the URL
* @return request URI
* @see #getRequestURI()
* @deprecated
*/
@Deprecated
public String getURI()
{
return getRequestURI();
}
/**
* @return request URI
*/
public String getRequestURI()
{
return _uri;
}
/**
* @param uri the path of the URL (for example '/foo/bar?a=1')
* Set the request URI
*
* @param uri new request URI
* @see #setRequestURI(String)
* @deprecated
*/
@Deprecated
public void setURI(String uri)
{
setRequestURI(uri);
}
/**
* Set the request URI
*
* Per RFC 2616 sec5, Request-URI = "*" | absoluteURI | abs_path | authority<br/>
* where:<br/><br/>
* "*" - request applies to server itself<br/>
* absoluteURI - required for proxy requests, e.g. http://localhost:8080/context<br/>
* (this form is generated automatically by HttpClient)<br/>
* abs_path - used for most methods, e.g. /context<br/>
* authority - used for CONNECT method only, e.g. localhost:8080<br/>
* <br/>
* For complete definition of URI components, see RFC 2396 sec3.<br/>
*
* @param uri new request URI
*/
public void setRequestURI(String uri)
{
_uri = uri;
}
/* ------------------------------------------------------------ */
/**
* @param uri an absolute URI (for example 'http://localhost/foo/bar?a=1')
*/
public void setURI(URI uri)
{
if (!uri.isAbsolute())
throw new IllegalArgumentException("!Absolute URI: "+uri);
if (uri.isOpaque())
throw new IllegalArgumentException("Opaque URI: "+uri);
String scheme = uri.getScheme();
int port = uri.getPort();
if (port <= 0)
port = "https".equalsIgnoreCase(scheme)?443:80;
setScheme(scheme);
setAddress(new Address(uri.getHost(),port));
HttpURI httpUri = new HttpURI(uri);
String completePath = httpUri.getCompletePath();
setRequestURI(completePath==null ? "/" : completePath);
}
/**
* Adds the specified request header

View File

@ -112,7 +112,7 @@ public class RedirectListener extends HttpEventListenerWrapper
if (_location.indexOf("://")>0)
_exchange.setURL(_location);
else
_exchange.setURI(_location);
_exchange.setRequestURI(_location);
// destination may have changed
HttpDestination destination=_destination.getHttpClient().getDestination(_exchange.getAddress(),HttpSchemes.HTTPS.equals(String.valueOf(_exchange.getScheme())));

View File

@ -253,7 +253,7 @@ public class WebdavListener extends HttpEventListenerWrapper
propfindExchange.setScheme( _exchange.getScheme() );
propfindExchange.setEventListener( new SecurityListener( _destination, propfindExchange ) );
propfindExchange.setConfigureListeners( false );
propfindExchange.setURI( uri );
propfindExchange.setRequestURI( uri );
_destination.send( propfindExchange );
@ -278,7 +278,7 @@ public class WebdavListener extends HttpEventListenerWrapper
mkcolExchange.setScheme( _exchange.getScheme() );
mkcolExchange.setEventListener( new SecurityListener( _destination, mkcolExchange ) );
mkcolExchange.setConfigureListeners( false );
mkcolExchange.setURI( uri );
mkcolExchange.setRequestURI( uri );
_destination.send( mkcolExchange );
@ -304,7 +304,7 @@ public class WebdavListener extends HttpEventListenerWrapper
supportedExchange.setScheme( _exchange.getScheme() );
supportedExchange.setEventListener( new SecurityListener( _destination, supportedExchange ) );
supportedExchange.setConfigureListeners( false );
supportedExchange.setURI( _exchange.getURI() );
supportedExchange.setRequestURI( _exchange.getURI() );
_destination.send( supportedExchange );

View File

@ -53,7 +53,7 @@ public abstract class AbstractConnectionTest
CountDownLatch latch = new CountDownLatch(1);
HttpExchange exchange = new ConnectionExchange(latch);
exchange.setAddress(new Address("localhost", port));
exchange.setURI("/");
exchange.setRequestURI("/");
httpClient.send(exchange);
Socket remote = serverSocket.accept();
@ -109,7 +109,7 @@ public abstract class AbstractConnectionTest
CountDownLatch latch = new CountDownLatch(1);
HttpExchange exchange = new ConnectionExchange(latch);
exchange.setAddress(new Address("localhost", port));
exchange.setURI("/");
exchange.setRequestURI("/");
httpClient.send(exchange);
boolean passed = latch.await(4000, TimeUnit.MILLISECONDS);
@ -158,7 +158,7 @@ public abstract class AbstractConnectionTest
}
};
exchange.setAddress(new Address("localhost", port));
exchange.setURI("/");
exchange.setRequestURI("/");
exchanges[i] = exchange;
}
@ -189,7 +189,7 @@ public abstract class AbstractConnectionTest
HttpExchange exchange = new ConnectionExchange(latch);
// Using a IP address has a different behavior than using a host name
exchange.setAddress(new Address("127.0.0.1", 1));
exchange.setURI("/");
exchange.setRequestURI("/");
httpClient.send(exchange);
boolean passed = latch.await(connectTimeout * 2L, TimeUnit.MILLISECONDS);
@ -218,7 +218,7 @@ public abstract class AbstractConnectionTest
{
HttpExchange exchange = new ConnectionExchange();
exchange.setAddress(new Address("localhost", port));
exchange.setURI("/");
exchange.setRequestURI("/");
HttpDestination dest = httpClient.getDestination(new Address("localhost", port),false);
httpClient.send(exchange);
@ -236,7 +236,7 @@ public abstract class AbstractConnectionTest
exchange = new ConnectionExchange();
exchange.setAddress(new Address("localhost", port));
exchange.setURI("/");
exchange.setRequestURI("/");
httpClient.send(exchange);
s.getInputStream().read(buf);

View File

@ -84,7 +84,7 @@ public abstract class AbstractHttpExchangeCancelTest
}
};
exchange.setAddress(newAddress());
exchange.setURI("/");
exchange.setRequestURI("/");
getHttpClient().send(exchange);
// Cancelling here is wrong and makes the test fail spuriously
@ -122,7 +122,7 @@ public abstract class AbstractHttpExchangeCancelTest
}
};
exchange.setAddress(newAddress());
exchange.setURI("/");
exchange.setRequestURI("/");
getHttpClient().send(exchange);
// Cancelling here is wrong and makes the test fail spuriously
@ -152,7 +152,7 @@ public abstract class AbstractHttpExchangeCancelTest
}
};
exchange.setAddress(newAddress());
exchange.setURI("/");
exchange.setRequestURI("/");
getHttpClient().send(exchange);
@ -177,7 +177,7 @@ public abstract class AbstractHttpExchangeCancelTest
}
};
exchange.setAddress(newAddress());
exchange.setURI("/");
exchange.setRequestURI("/");
getHttpClient().send(exchange);
@ -202,7 +202,7 @@ public abstract class AbstractHttpExchangeCancelTest
}
};
exchange.setAddress(newAddress());
exchange.setURI("/");
exchange.setRequestURI("/");
getHttpClient().send(exchange);
@ -227,7 +227,7 @@ public abstract class AbstractHttpExchangeCancelTest
}
};
exchange.setAddress(newAddress());
exchange.setURI("/");
exchange.setRequestURI("/");
getHttpClient().send(exchange);
@ -252,7 +252,7 @@ public abstract class AbstractHttpExchangeCancelTest
}
};
exchange.setAddress(newAddress());
exchange.setURI("/");
exchange.setRequestURI("/");
getHttpClient().send(exchange);
@ -277,7 +277,7 @@ public abstract class AbstractHttpExchangeCancelTest
}
};
exchange.setAddress(newAddress());
exchange.setURI("/?action=body");
exchange.setRequestURI("/?action=body");
getHttpClient().send(exchange);
@ -302,7 +302,7 @@ public abstract class AbstractHttpExchangeCancelTest
}
};
exchange.setAddress(newAddress());
exchange.setURI("/");
exchange.setRequestURI("/");
getHttpClient().send(exchange);
@ -322,7 +322,7 @@ public abstract class AbstractHttpExchangeCancelTest
((StdErrLog)Log.getLog()).setHideStacks(!Log.isDebugEnabled());
TestHttpExchange exchange = new TestHttpExchange();
exchange.setAddress(newAddress());
exchange.setURI("/?action=throw");
exchange.setRequestURI("/?action=throw");
getHttpClient().send(exchange);
@ -349,7 +349,7 @@ public abstract class AbstractHttpExchangeCancelTest
TestHttpExchange exchange = new TestHttpExchange();
exchange.setAddress(newAddress());
exchange.setURI("/?action=wait5000");
exchange.setRequestURI("/?action=wait5000");
long start = System.currentTimeMillis();
httpClient.send(exchange);

View File

@ -18,7 +18,7 @@ public class AsyncSslHttpExchangeTest extends SslHttpExchangeTest
@Override
public void setUp() throws Exception
{
_scheme="https://";
_scheme="https";
startServer();
_httpClient=new HttpClient();
_httpClient.setIdleTimeout(2000);

View File

@ -23,7 +23,7 @@ public class ExternalKeyStoreAsyncSslHttpExchangeTest extends SslHttpExchangeTes
@Override
public void setUp() throws Exception
{
_scheme = "https://";
_scheme = "https";
startServer();
_httpClient = new HttpClient();
_httpClient.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL);

View File

@ -16,12 +16,15 @@ package org.eclipse.jetty.client;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.matchers.JUnitMatchers.containsString;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
@ -32,8 +35,10 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.security.ProxyAuthorization;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeaders;
import org.eclipse.jetty.http.HttpMethods;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.io.Connection;
@ -58,7 +63,7 @@ import org.junit.Test;
public class HttpExchangeTest
{
protected int _maxConnectionsPerAddress = 2;
protected String _scheme = "http://";
protected String _scheme = "http";
protected Server _server;
protected int _port;
protected HttpClient _httpClient;
@ -233,7 +238,7 @@ public class HttpExchangeTest
}
};
httpExchange[n].setURL(_scheme+"localhost:"+_port+"/"+n);
httpExchange[n].setURL(_scheme+"://localhost:"+_port+"/"+n);
httpExchange[n].addRequestHeader("arbitrary","value");
if (close)
httpExchange[n].setRequestHeader("Connection","close");
@ -261,8 +266,7 @@ public class HttpExchangeTest
for (int i=0;i<20;i++)
{
ContentExchange httpExchange=new ContentExchange();
//httpExchange.setURL(_scheme+"localhost:"+_port+"/");
httpExchange.setURL(_scheme+"localhost:"+_port);
httpExchange.setURI(new URI(_scheme, null, "localhost", _port, null, null, null));
httpExchange.setMethod(HttpMethods.POST);
httpExchange.setRequestContent(new ByteArrayBuffer("<hello />"));
_httpClient.send(httpExchange);
@ -281,7 +285,7 @@ public class HttpExchangeTest
for (int i=0;i<10;i++)
{
ContentExchange httpExchange=new ContentExchange();
httpExchange.setURL(_scheme+"localhost:"+_port+"/?i="+i);
httpExchange.setURI(new URI(_scheme, null, "localhost", _port, "/", "i="+i, null));
httpExchange.setMethod(HttpMethods.GET);
_httpClient.send(httpExchange);
int status = httpExchange.waitForDone();
@ -301,7 +305,7 @@ public class HttpExchangeTest
for (int i=0;i<10;i++)
{
ContentExchange httpExchange=new ContentExchange();
httpExchange.setURL(_scheme+"localhost:"+_port+"/?i="+i);
httpExchange.setURL(_scheme+"://localhost:"+_port+"/?i="+i);
httpExchange.setMethod(HttpMethods.GET);
_httpClient.send(httpExchange);
int status = httpExchange.waitForDone();
@ -348,7 +352,7 @@ public class HttpExchangeTest
throwable.set(x);
}
};
httpExchange.setURL(_scheme+"localhost:"+_port+"/");
httpExchange.setURL(_scheme+"://localhost:"+_port+"/");
httpExchange.setMethod("SLEEP");
_httpClient.send(httpExchange);
new Thread()
@ -387,7 +391,7 @@ public class HttpExchangeTest
niobuf.put(bytes);
}
httpExchange.setURL(_scheme+"localhost:"+_port+"/");
httpExchange.setURL(_scheme+"://localhost:"+_port+"/");
httpExchange.setMethod(HttpMethods.POST);
httpExchange.setRequestContentType("application/data");
httpExchange.setRequestContent(babuf);
@ -400,7 +404,7 @@ public class HttpExchangeTest
assertEquals(babuf.length(),result.length());
httpExchange.reset();
httpExchange.setURL(_scheme+"localhost:"+_port+"/");
httpExchange.setURL(_scheme+"://localhost:"+_port+"/");
httpExchange.setMethod(HttpMethods.POST);
httpExchange.setRequestContentType("application/data");
httpExchange.setRequestContent(niobuf);
@ -419,8 +423,7 @@ public class HttpExchangeTest
{
};
//httpExchange.setURL(_scheme+"localhost:"+_port+"/");
httpExchange.setURL(_scheme+"localhost:"+_port);
httpExchange.setURL(_scheme+"://localhost:"+_port);
httpExchange.setMethod(HttpMethods.POST);
final String data="012345678901234567890123456789012345678901234567890123456789";
@ -478,7 +481,7 @@ public class HttpExchangeTest
@Test
public void testProxy() throws Exception
{
if (_scheme.equals("https://"))
if (_scheme.equals("https"))
return;
try
{
@ -488,7 +491,7 @@ public class HttpExchangeTest
ContentExchange httpExchange=new ContentExchange();
httpExchange.setAddress(new Address("jetty.eclipse.org",8080));
httpExchange.setMethod(HttpMethods.GET);
httpExchange.setURI("/jetty-6");
httpExchange.setRequestURI("/jetty-6");
_httpClient.send(httpExchange);
int status = httpExchange.waitForDone();
//httpExchange.waitForStatus(HttpExchange.STATUS_COMPLETED);
@ -509,14 +512,14 @@ public class HttpExchangeTest
@Test
public void testReserveConnections () throws Exception
{
final HttpDestination destination = _httpClient.getDestination (new Address("localhost", _port), _scheme.equalsIgnoreCase("https://"));
final HttpDestination destination = _httpClient.getDestination (new Address("localhost", _port), _scheme.equalsIgnoreCase("https"));
final org.eclipse.jetty.client.HttpConnection[] connections = new org.eclipse.jetty.client.HttpConnection[_maxConnectionsPerAddress];
for (int i=0; i < _maxConnectionsPerAddress; i++)
{
connections[i] = destination.reserveConnection(200);
assertNotNull(connections[i]);
HttpExchange ex = new ContentExchange();
ex.setURL(_scheme+"localhost:"+_port+"/?i="+i);
ex.setURL(_scheme+"://localhost:"+_port+"/?i="+i);
ex.setMethod(HttpMethods.GET);
connections[i].send(ex);
}
@ -533,6 +536,35 @@ public class HttpExchangeTest
c = destination.reserveConnection(500);
assertNotNull(c);
}
@Test
public void testOptionsWithExchange() throws Exception
{
ContentExchange httpExchange = new ContentExchange(true);
httpExchange.setURL(_scheme+"://localhost:"+_port);
httpExchange.setRequestURI("*");
httpExchange.setMethod(HttpMethods.OPTIONS);
httpExchange.setRequestHeader("Connection","close");
_httpClient.send(httpExchange);
int state = httpExchange.waitForDone();
assertEquals(HttpExchange.STATUS_COMPLETED, state);
assertEquals(HttpStatus.OK_200,httpExchange.getResponseStatus());
HttpFields headers = httpExchange.getResponseFields();
assertTrue("Response contains Allow header", headers.containsKey("Allow"));
String allow = headers.getStringField("Allow");
String expectedMethods[] =
{ "GET", "HEAD", "POST", "PUT", "DELETE", "MOVE", "OPTIONS", "TRACE" };
for (String expectedMethod : expectedMethods)
{
assertThat(allow,containsString(expectedMethod));
}
assertTrue("Response contains Content-Length header", headers.containsKey("Content-Length"));
assertEquals("Content-Length header value", 0, headers.getLongField("Content-Length"));
}
/* ------------------------------------------------------------ */
public static void copyStream(InputStream in, OutputStream out)
@ -600,6 +632,14 @@ public class HttpExchangeTest
}
response.getOutputStream().println("</hello>");
}
else if (request.getMethod().equalsIgnoreCase("OPTIONS"))
{
if ("*".equals(target))
{
response.setContentLength(0);
response.setHeader("Allow","GET,HEAD,POST,PUT,DELETE,MOVE,OPTIONS,TRACE");
}
}
else if (request.getMethod().equalsIgnoreCase("SLEEP"))
{
Thread.sleep(10000);

View File

@ -40,7 +40,7 @@ public class SslHttpExchangeTest extends HttpExchangeTest
@Override
public void setUp() throws Exception
{
_scheme="https://";
_scheme="https";
startServer();
_httpClient=new HttpClient();
_httpClient.setIdleTimeout(2000);