Merge branch 'master' into sslClose
Conflicts: jetty-client/src/main/java/org/eclipse/jetty/client/HttpExchange.java
This commit is contained in:
commit
21a111db27
|
@ -35,7 +35,9 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
import org.eclipse.jetty.util.thread.Timeout;
|
||||
|
||||
/**
|
||||
* <p>An HTTP client API that encapsulates an exchange (a request and its response) with a HTTP server.</p>
|
||||
* <p>
|
||||
* An HTTP client API that encapsulates an exchange (a request and its response) with a HTTP server.
|
||||
* </p>
|
||||
*
|
||||
* This object encapsulates:
|
||||
* <ul>
|
||||
|
@ -48,23 +50,25 @@ import org.eclipse.jetty.util.thread.Timeout;
|
|||
* <li>The ability to intercept callbacks (see {@link #setEventListener(HttpEventListener)}
|
||||
* </ul>
|
||||
*
|
||||
* <p>The HttpExchange class is intended to be used by a developer wishing to have close asynchronous
|
||||
* interaction with the the exchange.<br />
|
||||
* Typically a developer will extend the HttpExchange class with a derived
|
||||
* class that overrides some or all of the onXxx callbacks. <br />
|
||||
* There are also some predefined HttpExchange subtypes that can be used as a basis,
|
||||
* see {@link org.eclipse.jetty.client.ContentExchange} and {@link org.eclipse.jetty.client.CachedExchange}.</p>
|
||||
* <p>
|
||||
* The HttpExchange class is intended to be used by a developer wishing to have close asynchronous interaction with the the exchange.<br />
|
||||
* Typically a developer will extend the HttpExchange class with a derived class that overrides some or all of the onXxx callbacks. <br />
|
||||
* There are also some predefined HttpExchange subtypes that can be used as a basis, see {@link org.eclipse.jetty.client.ContentExchange} and
|
||||
* {@link org.eclipse.jetty.client.CachedExchange}.
|
||||
* </p>
|
||||
*
|
||||
* <p>Typically the HttpExchange is passed to the {@link HttpClient#send(HttpExchange)} method, which in
|
||||
* turn selects a {@link HttpDestination} and calls its {@link HttpDestination#send(HttpExchange)}, which
|
||||
* then creates or selects a {@link HttpConnection} and calls its {@link HttpConnection#send(HttpExchange)}.
|
||||
* A developer may wish to directly call send on the destination or connection if they wish to bypass
|
||||
* some handling provided (eg Cookie handling in the HttpDestination).</p>
|
||||
* <p>
|
||||
* Typically the HttpExchange is passed to the {@link HttpClient#send(HttpExchange)} method, which in turn selects a {@link HttpDestination} and calls its
|
||||
* {@link HttpDestination#send(HttpExchange)}, which then creates or selects a {@link HttpConnection} and calls its {@link HttpConnection#send(HttpExchange)}. A
|
||||
* developer may wish to directly call send on the destination or connection if they wish to bypass some handling provided (eg Cookie handling in the
|
||||
* HttpDestination).
|
||||
* </p>
|
||||
*
|
||||
* <p>In some circumstances, the HttpClient or HttpDestination may wish to retry a HttpExchange (eg. failed
|
||||
* pipeline request, authentication retry or redirection). In such cases, the HttpClient and/or HttpDestination
|
||||
* may insert their own HttpExchangeListener to intercept and filter the call backs intended for the
|
||||
* HttpExchange.</p>
|
||||
* <p>
|
||||
* In some circumstances, the HttpClient or HttpDestination may wish to retry a HttpExchange (eg. failed pipeline request, authentication retry or redirection).
|
||||
* In such cases, the HttpClient and/or HttpDestination may insert their own HttpExchangeListener to intercept and filter the call backs intended for the
|
||||
* HttpExchange.
|
||||
* </p>
|
||||
*/
|
||||
public class HttpExchange
|
||||
{
|
||||
|
@ -106,11 +110,17 @@ public class HttpExchange
|
|||
// a timeout for this exchange
|
||||
private long _timeout = -1;
|
||||
private volatile Timeout.Task _timeoutTask;
|
||||
<<<<<<< HEAD
|
||||
|
||||
private long _lastStateChange=System.currentTimeMillis();
|
||||
private long _sent=-1;
|
||||
private int _lastState=-1;
|
||||
private int _lastStatePeriod=-1;
|
||||
=======
|
||||
|
||||
private long _lastStateChange = -1;
|
||||
private long _sent = -1;
|
||||
>>>>>>> master
|
||||
|
||||
boolean _onRequestCompleteDone;
|
||||
boolean _onResponseCompleteDone;
|
||||
|
@ -133,8 +143,10 @@ public class HttpExchange
|
|||
}
|
||||
|
||||
/**
|
||||
* @param status the status to wait for
|
||||
* @throws InterruptedException if the waiting thread is interrupted
|
||||
* @param status
|
||||
* the status to wait for
|
||||
* @throws InterruptedException
|
||||
* if the waiting thread is interrupted
|
||||
* @deprecated Use {@link #waitForDone()} instead
|
||||
*/
|
||||
@Deprecated
|
||||
|
@ -144,21 +156,17 @@ public class HttpExchange
|
|||
}
|
||||
|
||||
/**
|
||||
* Wait until the exchange is "done".
|
||||
* Done is defined as when a final state has been passed to the
|
||||
* HttpExchange via the associated onXxx call. Note that an
|
||||
* exchange can transit a final state when being used as part
|
||||
* of a dialog (eg {@link SecurityListener}. Done status
|
||||
* is thus defined as:<pre>
|
||||
* done == onConnectionFailed
|
||||
* || onException
|
||||
* || onExpire
|
||||
* || onRequestComplete && onResponseComplete
|
||||
* Wait until the exchange is "done". Done is defined as when a final state has been passed to the HttpExchange via the associated onXxx call. Note that an
|
||||
* exchange can transit a final state when being used as part of a dialog (eg {@link SecurityListener}. Done status is thus defined as:
|
||||
*
|
||||
* <pre>
|
||||
* done == onConnectionFailed || onException || onExpire || onRequestComplete && onResponseComplete
|
||||
* </pre>
|
||||
*
|
||||
* @return the done status
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public int waitForDone () throws InterruptedException
|
||||
public int waitForDone() throws InterruptedException
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
|
@ -172,12 +180,12 @@ public class HttpExchange
|
|||
{
|
||||
// TODO - this should do a cancel and wakeup everybody that was waiting.
|
||||
// might need a version number concept
|
||||
synchronized(this)
|
||||
synchronized (this)
|
||||
{
|
||||
_timeoutTask=null;
|
||||
_onRequestCompleteDone=false;
|
||||
_onResponseCompleteDone=false;
|
||||
_onDone=false;
|
||||
_timeoutTask = null;
|
||||
_onRequestCompleteDone = false;
|
||||
_onResponseCompleteDone = false;
|
||||
_onDone = false;
|
||||
setStatus(STATUS_START);
|
||||
}
|
||||
}
|
||||
|
@ -188,7 +196,7 @@ public class HttpExchange
|
|||
{
|
||||
int oldStatus = _status.get();
|
||||
boolean set = false;
|
||||
if (oldStatus!=newStatus)
|
||||
if (oldStatus != newStatus)
|
||||
{
|
||||
long now = System.currentTimeMillis();
|
||||
_lastStatePeriod=(int)(now-_lastStateChange);
|
||||
|
@ -197,7 +205,7 @@ public class HttpExchange
|
|||
if (newStatus==STATUS_SENDING_REQUEST)
|
||||
_sent=_lastStateChange;
|
||||
}
|
||||
|
||||
|
||||
// State machine: from which old status you can go into which new status
|
||||
switch (oldStatus)
|
||||
{
|
||||
|
@ -209,7 +217,10 @@ public class HttpExchange
|
|||
case STATUS_WAITING_FOR_COMMIT:
|
||||
case STATUS_CANCELLING:
|
||||
case STATUS_EXCEPTED:
|
||||
set=_status.compareAndSet(oldStatus,newStatus);
|
||||
set = _status.compareAndSet(oldStatus,newStatus);
|
||||
break;
|
||||
case STATUS_EXPIRED:
|
||||
set = setStatusExpired(newStatus,oldStatus);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -219,11 +230,10 @@ public class HttpExchange
|
|||
case STATUS_WAITING_FOR_COMMIT:
|
||||
case STATUS_CANCELLING:
|
||||
case STATUS_EXCEPTED:
|
||||
set=_status.compareAndSet(oldStatus,newStatus);
|
||||
set = _status.compareAndSet(oldStatus,newStatus);
|
||||
break;
|
||||
case STATUS_EXPIRED:
|
||||
if (set=_status.compareAndSet(oldStatus,newStatus))
|
||||
getEventListener().onExpire();
|
||||
set = setStatusExpired(newStatus,oldStatus);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -233,11 +243,10 @@ public class HttpExchange
|
|||
case STATUS_SENDING_REQUEST:
|
||||
case STATUS_CANCELLING:
|
||||
case STATUS_EXCEPTED:
|
||||
set=_status.compareAndSet(oldStatus,newStatus);
|
||||
set = _status.compareAndSet(oldStatus,newStatus);
|
||||
break;
|
||||
case STATUS_EXPIRED:
|
||||
if (set=_status.compareAndSet(oldStatus,newStatus))
|
||||
getEventListener().onExpire();
|
||||
set = setStatusExpired(newStatus,oldStatus);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -245,16 +254,15 @@ public class HttpExchange
|
|||
switch (newStatus)
|
||||
{
|
||||
case STATUS_WAITING_FOR_RESPONSE:
|
||||
if (set=_status.compareAndSet(oldStatus,newStatus))
|
||||
if (set = _status.compareAndSet(oldStatus,newStatus))
|
||||
getEventListener().onRequestCommitted();
|
||||
break;
|
||||
case STATUS_CANCELLING:
|
||||
case STATUS_EXCEPTED:
|
||||
set=_status.compareAndSet(oldStatus,newStatus);
|
||||
set = _status.compareAndSet(oldStatus,newStatus);
|
||||
break;
|
||||
case STATUS_EXPIRED:
|
||||
if (set=_status.compareAndSet(oldStatus,newStatus))
|
||||
getEventListener().onExpire();
|
||||
set = setStatusExpired(newStatus,oldStatus);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -264,11 +272,10 @@ public class HttpExchange
|
|||
case STATUS_PARSING_HEADERS:
|
||||
case STATUS_CANCELLING:
|
||||
case STATUS_EXCEPTED:
|
||||
set=_status.compareAndSet(oldStatus,newStatus);
|
||||
set = _status.compareAndSet(oldStatus,newStatus);
|
||||
break;
|
||||
case STATUS_EXPIRED:
|
||||
if (set=_status.compareAndSet(oldStatus,newStatus))
|
||||
getEventListener().onExpire();
|
||||
set = setStatusExpired(newStatus,oldStatus);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -276,16 +283,15 @@ public class HttpExchange
|
|||
switch (newStatus)
|
||||
{
|
||||
case STATUS_PARSING_CONTENT:
|
||||
if (set=_status.compareAndSet(oldStatus,newStatus))
|
||||
if (set = _status.compareAndSet(oldStatus,newStatus))
|
||||
getEventListener().onResponseHeaderComplete();
|
||||
break;
|
||||
case STATUS_CANCELLING:
|
||||
case STATUS_EXCEPTED:
|
||||
set=_status.compareAndSet(oldStatus,newStatus);
|
||||
set = _status.compareAndSet(oldStatus,newStatus);
|
||||
break;
|
||||
case STATUS_EXPIRED:
|
||||
if (set=_status.compareAndSet(oldStatus,newStatus))
|
||||
getEventListener().onExpire();
|
||||
set = setStatusExpired(newStatus,oldStatus);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -293,16 +299,15 @@ public class HttpExchange
|
|||
switch (newStatus)
|
||||
{
|
||||
case STATUS_COMPLETED:
|
||||
if (set=_status.compareAndSet(oldStatus,newStatus))
|
||||
if (set = _status.compareAndSet(oldStatus,newStatus))
|
||||
getEventListener().onResponseComplete();
|
||||
break;
|
||||
case STATUS_CANCELLING:
|
||||
case STATUS_EXCEPTED:
|
||||
set=_status.compareAndSet(oldStatus,newStatus);
|
||||
set = _status.compareAndSet(oldStatus,newStatus);
|
||||
break;
|
||||
case STATUS_EXPIRED:
|
||||
if (set=_status.compareAndSet(oldStatus,newStatus))
|
||||
getEventListener().onExpire();
|
||||
set = setStatusExpired(newStatus,oldStatus);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -312,12 +317,12 @@ public class HttpExchange
|
|||
case STATUS_START:
|
||||
case STATUS_EXCEPTED:
|
||||
case STATUS_WAITING_FOR_RESPONSE:
|
||||
set=_status.compareAndSet(oldStatus,newStatus);
|
||||
set = _status.compareAndSet(oldStatus,newStatus);
|
||||
break;
|
||||
case STATUS_CANCELLING:
|
||||
case STATUS_EXPIRED:
|
||||
// Don't change the status, it's too late
|
||||
set=true;
|
||||
set = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -326,12 +331,12 @@ public class HttpExchange
|
|||
{
|
||||
case STATUS_EXCEPTED:
|
||||
case STATUS_CANCELLED:
|
||||
if (set=_status.compareAndSet(oldStatus,newStatus))
|
||||
if (set = _status.compareAndSet(oldStatus,newStatus))
|
||||
done();
|
||||
break;
|
||||
default:
|
||||
// Ignore other statuses, we're cancelling
|
||||
set=true;
|
||||
set = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -341,10 +346,10 @@ public class HttpExchange
|
|||
switch (newStatus)
|
||||
{
|
||||
case STATUS_START:
|
||||
set=_status.compareAndSet(oldStatus,newStatus);
|
||||
set = _status.compareAndSet(oldStatus,newStatus);
|
||||
break;
|
||||
default:
|
||||
set=true;
|
||||
set = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -362,6 +367,14 @@ public class HttpExchange
|
|||
}
|
||||
}
|
||||
|
||||
private boolean setStatusExpired(int newStatus, int oldStatus)
|
||||
{
|
||||
boolean set;
|
||||
if (set = _status.compareAndSet(oldStatus,newStatus))
|
||||
getEventListener().onExpire();
|
||||
return set;
|
||||
}
|
||||
|
||||
public boolean isDone()
|
||||
{
|
||||
synchronized (this)
|
||||
|
@ -374,7 +387,7 @@ public class HttpExchange
|
|||
* @deprecated
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean isDone (int status)
|
||||
public boolean isDone(int status)
|
||||
{
|
||||
return isDone();
|
||||
}
|
||||
|
@ -386,10 +399,10 @@ public class HttpExchange
|
|||
|
||||
public void setEventListener(HttpEventListener listener)
|
||||
{
|
||||
_listener=listener;
|
||||
_listener = listener;
|
||||
}
|
||||
|
||||
public void setTimeout( long timeout )
|
||||
public void setTimeout(long timeout)
|
||||
{
|
||||
_timeout = timeout;
|
||||
}
|
||||
|
@ -400,7 +413,8 @@ public class HttpExchange
|
|||
}
|
||||
|
||||
/**
|
||||
* @param url an absolute URL (for example 'http://localhost/foo/bar?a=1')
|
||||
* @param url
|
||||
* an absolute URL (for example 'http://localhost/foo/bar?a=1')
|
||||
*/
|
||||
public void setURL(String url)
|
||||
{
|
||||
|
@ -408,7 +422,8 @@ public class HttpExchange
|
|||
}
|
||||
|
||||
/**
|
||||
* @param address the address of the server
|
||||
* @param address
|
||||
* the address of the server
|
||||
*/
|
||||
public void setAddress(Address address)
|
||||
{
|
||||
|
@ -426,8 +441,7 @@ public class HttpExchange
|
|||
/**
|
||||
* the local address used by the connection
|
||||
*
|
||||
* Note: this method will not be populated unless the exchange
|
||||
* has been executed by the HttpClient
|
||||
* Note: this method will not be populated unless the exchange has been executed by the HttpClient
|
||||
*
|
||||
* @return the local address used for the running of the exchange if available, null otherwise.
|
||||
*/
|
||||
|
@ -437,15 +451,17 @@ public class HttpExchange
|
|||
}
|
||||
|
||||
/**
|
||||
* @param scheme the scheme of the URL (for example 'http')
|
||||
* @param scheme
|
||||
* the scheme of the URL (for example 'http')
|
||||
*/
|
||||
public void setScheme(Buffer scheme)
|
||||
{
|
||||
_scheme = scheme;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param scheme the scheme of the URL (for example 'http')
|
||||
* @param scheme
|
||||
* the scheme of the URL (for example 'http')
|
||||
*/
|
||||
public void setScheme(String scheme)
|
||||
{
|
||||
|
@ -469,7 +485,8 @@ public class HttpExchange
|
|||
}
|
||||
|
||||
/**
|
||||
* @param version the HTTP protocol version as integer, 9, 10 or 11 for 0.9, 1.0 or 1.1
|
||||
* @param version
|
||||
* the HTTP protocol version as integer, 9, 10 or 11 for 0.9, 1.0 or 1.1
|
||||
*/
|
||||
public void setVersion(int version)
|
||||
{
|
||||
|
@ -477,7 +494,8 @@ public class HttpExchange
|
|||
}
|
||||
|
||||
/**
|
||||
* @param version the HTTP protocol version as string
|
||||
* @param version
|
||||
* the HTTP protocol version as string
|
||||
*/
|
||||
public void setVersion(String version)
|
||||
{
|
||||
|
@ -498,7 +516,8 @@ public class HttpExchange
|
|||
}
|
||||
|
||||
/**
|
||||
* @param method the HTTP method (for example 'GET')
|
||||
* @param method
|
||||
* the HTTP method (for example 'GET')
|
||||
*/
|
||||
public void setMethod(String method)
|
||||
{
|
||||
|
@ -533,9 +552,10 @@ public class HttpExchange
|
|||
}
|
||||
|
||||
/**
|
||||
* Set the request URI
|
||||
* Set the request URI
|
||||
*
|
||||
* @param uri new request URI
|
||||
* @param uri
|
||||
* new request URI
|
||||
* @see #setRequestURI(String)
|
||||
* @deprecated
|
||||
*/
|
||||
|
@ -546,38 +566,41 @@ public class HttpExchange
|
|||
}
|
||||
|
||||
/**
|
||||
* Set the request 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/>
|
||||
* 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/>
|
||||
* (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
|
||||
*
|
||||
* @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')
|
||||
* @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);
|
||||
|
||||
throw new IllegalArgumentException("!Absolute URI: " + uri);
|
||||
|
||||
if (uri.isOpaque())
|
||||
throw new IllegalArgumentException("Opaque URI: "+uri);
|
||||
|
||||
LOG.debug("URI = {}", uri.toASCIIString());
|
||||
throw new IllegalArgumentException("Opaque URI: " + uri);
|
||||
|
||||
LOG.debug("URI = {}",uri.toASCIIString());
|
||||
|
||||
String scheme = uri.getScheme();
|
||||
int port = uri.getPort();
|
||||
|
@ -589,13 +612,16 @@ public class HttpExchange
|
|||
|
||||
HttpURI httpUri = new HttpURI(uri);
|
||||
String completePath = httpUri.getCompletePath();
|
||||
setRequestURI(completePath==null ? "/" : completePath);
|
||||
setRequestURI(completePath == null?"/":completePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the specified request header
|
||||
* @param name the header name
|
||||
* @param value the header value
|
||||
*
|
||||
* @param name
|
||||
* the header name
|
||||
* @param value
|
||||
* the header value
|
||||
*/
|
||||
public void addRequestHeader(String name, String value)
|
||||
{
|
||||
|
@ -604,8 +630,11 @@ public class HttpExchange
|
|||
|
||||
/**
|
||||
* Adds the specified request header
|
||||
* @param name the header name
|
||||
* @param value the header value
|
||||
*
|
||||
* @param name
|
||||
* the header name
|
||||
* @param value
|
||||
* the header value
|
||||
*/
|
||||
public void addRequestHeader(Buffer name, Buffer value)
|
||||
{
|
||||
|
@ -614,30 +643,37 @@ public class HttpExchange
|
|||
|
||||
/**
|
||||
* Sets the specified request header
|
||||
* @param name the header name
|
||||
* @param value the header value
|
||||
*
|
||||
* @param name
|
||||
* the header name
|
||||
* @param value
|
||||
* the header value
|
||||
*/
|
||||
public void setRequestHeader(String name, String value)
|
||||
{
|
||||
getRequestFields().put(name, value);
|
||||
getRequestFields().put(name,value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the specified request header
|
||||
* @param name the header name
|
||||
* @param value the header value
|
||||
*
|
||||
* @param name
|
||||
* the header name
|
||||
* @param value
|
||||
* the header value
|
||||
*/
|
||||
public void setRequestHeader(Buffer name, Buffer value)
|
||||
{
|
||||
getRequestFields().put(name, value);
|
||||
getRequestFields().put(name,value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value the content type of the request
|
||||
* @param value
|
||||
* the content type of the request
|
||||
*/
|
||||
public void setRequestContentType(String value)
|
||||
{
|
||||
getRequestFields().put(HttpHeaders.CONTENT_TYPE_BUFFER, value);
|
||||
getRequestFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -649,7 +685,8 @@ public class HttpExchange
|
|||
}
|
||||
|
||||
/**
|
||||
* @param requestContent the request content
|
||||
* @param requestContent
|
||||
* the request content
|
||||
*/
|
||||
public void setRequestContent(Buffer requestContent)
|
||||
{
|
||||
|
@ -657,7 +694,8 @@ public class HttpExchange
|
|||
}
|
||||
|
||||
/**
|
||||
* @param stream the request content as a stream
|
||||
* @param stream
|
||||
* the request content as a stream
|
||||
*/
|
||||
public void setRequestContentSource(InputStream stream)
|
||||
{
|
||||
|
@ -715,7 +753,8 @@ public class HttpExchange
|
|||
}
|
||||
|
||||
/**
|
||||
* @param retryStatus whether a retry will be attempted or not
|
||||
* @param retryStatus
|
||||
* whether a retry will be attempted or not
|
||||
*/
|
||||
public void setRetryStatus(boolean retryStatus)
|
||||
{
|
||||
|
@ -723,13 +762,10 @@ public class HttpExchange
|
|||
}
|
||||
|
||||
/**
|
||||
* Initiates the cancelling of this exchange.
|
||||
* The status of the exchange is set to {@link #STATUS_CANCELLING}.
|
||||
* Cancelling the exchange is an asynchronous operation with respect to the request/response,
|
||||
* and as such checking the request/response status of a cancelled exchange may return undefined results
|
||||
* (for example it may have only some of the response headers being sent by the server).
|
||||
* The cancelling of the exchange is completed when the exchange status (see {@link #getStatus()}) is
|
||||
* {@link #STATUS_CANCELLED}, and this can be waited using {@link #waitForDone()}.
|
||||
* Initiates the cancelling of this exchange. The status of the exchange is set to {@link #STATUS_CANCELLING}. Cancelling the exchange is an asynchronous
|
||||
* operation with respect to the request/response, and as such checking the request/response status of a cancelled exchange may return undefined results
|
||||
* (for example it may have only some of the response headers being sent by the server). The cancelling of the exchange is completed when the exchange
|
||||
* status (see {@link #getStatus()}) is {@link #STATUS_CANCELLED}, and this can be waited using {@link #waitForDone()}.
|
||||
*/
|
||||
public void cancel()
|
||||
{
|
||||
|
@ -739,10 +775,10 @@ public class HttpExchange
|
|||
|
||||
private void done()
|
||||
{
|
||||
synchronized(this)
|
||||
synchronized (this)
|
||||
{
|
||||
disassociate();
|
||||
_onDone=true;
|
||||
_onDone = true;
|
||||
notifyAll();
|
||||
}
|
||||
}
|
||||
|
@ -771,8 +807,8 @@ public class HttpExchange
|
|||
|
||||
void associate(HttpConnection connection)
|
||||
{
|
||||
if (connection.getEndPoint().getLocalHost() != null)
|
||||
_localAddress = new Address(connection.getEndPoint().getLocalHost(), connection.getEndPoint().getLocalPort());
|
||||
if (connection.getEndPoint().getLocalHost() != null)
|
||||
_localAddress = new Address(connection.getEndPoint().getLocalHost(),connection.getEndPoint().getLocalPort());
|
||||
|
||||
_connection = connection;
|
||||
if (getStatus() == STATUS_CANCELLING)
|
||||
|
@ -796,25 +832,50 @@ public class HttpExchange
|
|||
public static String toState(int s)
|
||||
{
|
||||
String state;
|
||||
switch(s)
|
||||
switch (s)
|
||||
{
|
||||
case STATUS_START: state="START"; break;
|
||||
case STATUS_WAITING_FOR_CONNECTION: state="CONNECTING"; break;
|
||||
case STATUS_WAITING_FOR_COMMIT: state="CONNECTED"; break;
|
||||
case STATUS_SENDING_REQUEST: state="SENDING"; break;
|
||||
case STATUS_WAITING_FOR_RESPONSE: state="WAITING"; break;
|
||||
case STATUS_PARSING_HEADERS: state="HEADERS"; break;
|
||||
case STATUS_PARSING_CONTENT: state="CONTENT"; break;
|
||||
case STATUS_COMPLETED: state="COMPLETED"; break;
|
||||
case STATUS_EXPIRED: state="EXPIRED"; break;
|
||||
case STATUS_EXCEPTED: state="EXCEPTED"; break;
|
||||
case STATUS_CANCELLING: state="CANCELLING"; break;
|
||||
case STATUS_CANCELLED: state="CANCELLED"; break;
|
||||
default: state="UNKNOWN";
|
||||
case STATUS_START:
|
||||
state = "START";
|
||||
break;
|
||||
case STATUS_WAITING_FOR_CONNECTION:
|
||||
state = "CONNECTING";
|
||||
break;
|
||||
case STATUS_WAITING_FOR_COMMIT:
|
||||
state = "CONNECTED";
|
||||
break;
|
||||
case STATUS_SENDING_REQUEST:
|
||||
state = "SENDING";
|
||||
break;
|
||||
case STATUS_WAITING_FOR_RESPONSE:
|
||||
state = "WAITING";
|
||||
break;
|
||||
case STATUS_PARSING_HEADERS:
|
||||
state = "HEADERS";
|
||||
break;
|
||||
case STATUS_PARSING_CONTENT:
|
||||
state = "CONTENT";
|
||||
break;
|
||||
case STATUS_COMPLETED:
|
||||
state = "COMPLETED";
|
||||
break;
|
||||
case STATUS_EXPIRED:
|
||||
state = "EXPIRED";
|
||||
break;
|
||||
case STATUS_EXCEPTED:
|
||||
state = "EXCEPTED";
|
||||
break;
|
||||
case STATUS_CANCELLING:
|
||||
state = "CANCELLING";
|
||||
break;
|
||||
case STATUS_CANCELLED:
|
||||
state = "CANCELLED";
|
||||
break;
|
||||
default:
|
||||
state = "UNKNOWN";
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
|
@ -837,79 +898,93 @@ public class HttpExchange
|
|||
}
|
||||
|
||||
/**
|
||||
* Callback called when the request headers have been sent to the server.
|
||||
* This implementation does nothing.
|
||||
* @throws IOException allowed to be thrown by overriding code
|
||||
* Callback called when the request headers have been sent to the server. This implementation does nothing.
|
||||
*
|
||||
* @throws IOException
|
||||
* allowed to be thrown by overriding code
|
||||
*/
|
||||
protected void onRequestCommitted() throws IOException
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback called when the request and its body have been sent to the server.
|
||||
* This implementation does nothing.
|
||||
* @throws IOException allowed to be thrown by overriding code
|
||||
* Callback called when the request and its body have been sent to the server. This implementation does nothing.
|
||||
*
|
||||
* @throws IOException
|
||||
* allowed to be thrown by overriding code
|
||||
*/
|
||||
protected void onRequestComplete() throws IOException
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback called when a response status line has been received from the server.
|
||||
* This implementation does nothing.
|
||||
* @param version the HTTP version
|
||||
* @param status the HTTP status code
|
||||
* @param reason the HTTP status reason string
|
||||
* @throws IOException allowed to be thrown by overriding code
|
||||
* Callback called when a response status line has been received from the server. This implementation does nothing.
|
||||
*
|
||||
* @param version
|
||||
* the HTTP version
|
||||
* @param status
|
||||
* the HTTP status code
|
||||
* @param reason
|
||||
* the HTTP status reason string
|
||||
* @throws IOException
|
||||
* allowed to be thrown by overriding code
|
||||
*/
|
||||
protected void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback called for each response header received from the server.
|
||||
* This implementation does nothing.
|
||||
* @param name the header name
|
||||
* @param value the header value
|
||||
* @throws IOException allowed to be thrown by overriding code
|
||||
* Callback called for each response header received from the server. This implementation does nothing.
|
||||
*
|
||||
* @param name
|
||||
* the header name
|
||||
* @param value
|
||||
* the header value
|
||||
* @throws IOException
|
||||
* allowed to be thrown by overriding code
|
||||
*/
|
||||
protected void onResponseHeader(Buffer name, Buffer value) throws IOException
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback called when the response headers have been completely received from the server.
|
||||
* This implementation does nothing.
|
||||
* @throws IOException allowed to be thrown by overriding code
|
||||
* Callback called when the response headers have been completely received from the server. This implementation does nothing.
|
||||
*
|
||||
* @throws IOException
|
||||
* allowed to be thrown by overriding code
|
||||
*/
|
||||
protected void onResponseHeaderComplete() throws IOException
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback called for each chunk of the response content received from the server.
|
||||
* This implementation does nothing.
|
||||
* @param content the buffer holding the content chunk
|
||||
* @throws IOException allowed to be thrown by overriding code
|
||||
* Callback called for each chunk of the response content received from the server. This implementation does nothing.
|
||||
*
|
||||
* @param content
|
||||
* the buffer holding the content chunk
|
||||
* @throws IOException
|
||||
* allowed to be thrown by overriding code
|
||||
*/
|
||||
protected void onResponseContent(Buffer content) throws IOException
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback called when the entire response has been received from the server
|
||||
* This implementation does nothing.
|
||||
* @throws IOException allowed to be thrown by overriding code
|
||||
* Callback called when the entire response has been received from the server This implementation does nothing.
|
||||
*
|
||||
* @throws IOException
|
||||
* allowed to be thrown by overriding code
|
||||
*/
|
||||
protected void onResponseComplete() throws IOException
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback called when an exception was thrown during an attempt to establish the connection
|
||||
* with the server (for example the server is not listening).
|
||||
* Callback called when an exception was thrown during an attempt to establish the connection with the server (for example the server is not listening).
|
||||
* This implementation logs a warning.
|
||||
* @param x the exception thrown attempting to establish the connection with the server
|
||||
*
|
||||
* @param x
|
||||
* the exception thrown attempting to establish the connection with the server
|
||||
*/
|
||||
protected void onConnectionFailed(Throwable x)
|
||||
{
|
||||
|
@ -917,9 +992,10 @@ public class HttpExchange
|
|||
}
|
||||
|
||||
/**
|
||||
* Callback called when any other exception occurs during the handling of this exchange.
|
||||
* This implementation logs a warning.
|
||||
* @param x the exception thrown during the handling of this exchange
|
||||
* Callback called when any other exception occurs during the handling of this exchange. This implementation logs a warning.
|
||||
*
|
||||
* @param x
|
||||
* the exception thrown during the handling of this exchange
|
||||
*/
|
||||
protected void onException(Throwable x)
|
||||
{
|
||||
|
@ -927,8 +1003,7 @@ public class HttpExchange
|
|||
}
|
||||
|
||||
/**
|
||||
* Callback called when no response has been received within the timeout.
|
||||
* This implementation logs a warning.
|
||||
* Callback called when no response has been received within the timeout. This implementation logs a warning.
|
||||
*/
|
||||
protected void onExpire()
|
||||
{
|
||||
|
@ -936,9 +1011,10 @@ public class HttpExchange
|
|||
}
|
||||
|
||||
/**
|
||||
* Callback called when the request is retried (due to failures or authentication).
|
||||
* Implementations must reset any consumable content that needs to be sent.
|
||||
* @throws IOException allowed to be thrown by overriding code
|
||||
* Callback called when the request is retried (due to failures or authentication). Implementations must reset any consumable content that needs to be sent.
|
||||
*
|
||||
* @throws IOException
|
||||
* allowed to be thrown by overriding code
|
||||
*/
|
||||
protected void onRetry() throws IOException
|
||||
{
|
||||
|
@ -957,8 +1033,7 @@ public class HttpExchange
|
|||
}
|
||||
|
||||
/**
|
||||
* @return true if the exchange should have listeners configured for it by the destination,
|
||||
* false if this is being managed elsewhere
|
||||
* @return true if the exchange should have listeners configured for it by the destination, false if this is being managed elsewhere
|
||||
* @see #setConfigureListeners(boolean)
|
||||
*/
|
||||
public boolean configureListeners()
|
||||
|
@ -967,7 +1042,8 @@ public class HttpExchange
|
|||
}
|
||||
|
||||
/**
|
||||
* @param autoConfigure whether the listeners are configured by the destination or elsewhere
|
||||
* @param autoConfigure
|
||||
* whether the listeners are configured by the destination or elsewhere
|
||||
*/
|
||||
public void setConfigureListeners(boolean autoConfigure)
|
||||
{
|
||||
|
@ -990,7 +1066,7 @@ public class HttpExchange
|
|||
HttpClient httpClient = destination.getHttpClient();
|
||||
long timeout = getTimeout();
|
||||
if (timeout > 0)
|
||||
httpClient.schedule(_timeoutTask, timeout);
|
||||
httpClient.schedule(_timeoutTask,timeout);
|
||||
else
|
||||
httpClient.schedule(_timeoutTask);
|
||||
}
|
||||
|
@ -1054,7 +1130,7 @@ public class HttpExchange
|
|||
}
|
||||
finally
|
||||
{
|
||||
synchronized(HttpExchange.this)
|
||||
synchronized (HttpExchange.this)
|
||||
{
|
||||
_onRequestCompleteDone = true;
|
||||
// Member _onDone may already be true, for example
|
||||
|
@ -1075,7 +1151,7 @@ public class HttpExchange
|
|||
}
|
||||
finally
|
||||
{
|
||||
synchronized(HttpExchange.this)
|
||||
synchronized (HttpExchange.this)
|
||||
{
|
||||
_onResponseCompleteDone = true;
|
||||
// Member _onDone may already be true, for example
|
||||
|
@ -1110,7 +1186,7 @@ public class HttpExchange
|
|||
|
||||
public void onRetry()
|
||||
{
|
||||
HttpExchange.this.setRetryStatus( true );
|
||||
HttpExchange.this.setRetryStatus(true);
|
||||
try
|
||||
{
|
||||
HttpExchange.this.onRetry();
|
||||
|
|
|
@ -110,25 +110,49 @@ public class RedirectListener extends HttpEventListenerWrapper
|
|||
if (_location != null)
|
||||
{
|
||||
if (_location.indexOf("://")>0)
|
||||
{
|
||||
_exchange.setURL(_location);
|
||||
}
|
||||
else
|
||||
{
|
||||
_exchange.setRequestURI(_location);
|
||||
}
|
||||
|
||||
// destination may have changed
|
||||
HttpDestination destination=_destination.getHttpClient().getDestination(_exchange.getAddress(),HttpSchemes.HTTPS.equals(String.valueOf(_exchange.getScheme())));
|
||||
|
||||
boolean isHttps = HttpSchemes.HTTPS.equals(String.valueOf(_exchange.getScheme()));
|
||||
HttpDestination destination=_destination.getHttpClient().getDestination(_exchange.getAddress(),isHttps);
|
||||
|
||||
if (_destination==destination)
|
||||
{
|
||||
_destination.resend(_exchange);
|
||||
}
|
||||
else
|
||||
{
|
||||
// unwrap to find ultimate listener.
|
||||
HttpEventListener listener=this;
|
||||
while(listener instanceof HttpEventListenerWrapper)
|
||||
{
|
||||
listener=((HttpEventListenerWrapper)listener).getEventListener();
|
||||
}
|
||||
|
||||
//reset the listener
|
||||
_exchange.getEventListener().onRetry();
|
||||
_exchange.reset();
|
||||
_exchange.setEventListener(listener);
|
||||
|
||||
// Set the new Host header
|
||||
Address address = _exchange.getAddress();
|
||||
int port = address.getPort();
|
||||
StringBuilder hostHeader = new StringBuilder( 64 );
|
||||
hostHeader.append( address.getHost() );
|
||||
if( !( ( port == 80 && !isHttps ) || ( port == 443 && isHttps ) ) )
|
||||
{
|
||||
hostHeader.append( ':' );
|
||||
hostHeader.append( port );
|
||||
}
|
||||
|
||||
_exchange.setRequestHeader( HttpHeaders.HOST, hostHeader.toString() );
|
||||
|
||||
destination.send(_exchange);
|
||||
}
|
||||
|
||||
|
@ -156,5 +180,28 @@ public class RedirectListener extends HttpEventListenerWrapper
|
|||
|
||||
super.onRetry();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegate failed connection
|
||||
*/
|
||||
@Override
|
||||
public void onConnectionFailed( Throwable ex )
|
||||
{
|
||||
setDelegatingRequests(true);
|
||||
setDelegatingResponses(true);
|
||||
|
||||
super.onConnectionFailed( ex );
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegate onException
|
||||
*/
|
||||
@Override
|
||||
public void onException( Throwable ex )
|
||||
{
|
||||
setDelegatingRequests(true);
|
||||
setDelegatingResponses(true);
|
||||
|
||||
super.onException( ex );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
package org.eclipse.jetty.server.handler;
|
||||
//========================================================================
|
||||
//Copyright (c) 1999-2009 Mort Bay Consulting Pty. Ltd.
|
||||
//------------------------------------------------------------------------
|
||||
//All rights reserved. This program and the accompanying materials
|
||||
//are made available under the terms of the Eclipse Public License v1.0
|
||||
//and Apache License v2.0 which accompanies this distribution.
|
||||
//The Eclipse Public License is available at
|
||||
//http://www.eclipse.org/legal/epl-v10.html
|
||||
//The Apache License v2.0 is available at
|
||||
//http://www.opensource.org/licenses/apache2.0.php
|
||||
//You may elect to redistribute this code under either of these licenses.
|
||||
//========================================================================
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.eclipse.jetty.server.Connector;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.bio.SocketConnector;
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.eclipse.jetty.toolchain.test.SimpleRequest;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Resource Handler test
|
||||
*
|
||||
* TODO: increase the testing going on here
|
||||
*/
|
||||
public class ResourceHandlerTest extends TestCase
|
||||
{
|
||||
private static Server _server;
|
||||
private static Connector _connector;
|
||||
private static ContextHandler _contextHandler;
|
||||
private static ResourceHandler _resourceHandler;
|
||||
|
||||
|
||||
@BeforeClass
|
||||
public void setUp() throws Exception
|
||||
{
|
||||
_server = new Server();
|
||||
_connector = new SocketConnector();
|
||||
_server.setConnectors(new Connector[] { _connector });
|
||||
|
||||
_resourceHandler = new ResourceHandler();
|
||||
|
||||
_contextHandler = new ContextHandler("/resource");
|
||||
_contextHandler.setHandler(_resourceHandler);
|
||||
_server.setHandler(_contextHandler);
|
||||
_server.start();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@AfterClass
|
||||
public void tearDown() throws Exception
|
||||
{
|
||||
_server.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleResourceHandler() throws Exception
|
||||
{
|
||||
_resourceHandler.setResourceBase(MavenTestingUtils.getTestResourceDir("simple").getAbsolutePath());
|
||||
|
||||
SimpleRequest sr = new SimpleRequest(new URI("http://localhost:" + _connector.getLocalPort()));
|
||||
|
||||
Assert.assertEquals("simple text", sr.getString("/resource/simple.txt"));
|
||||
|
||||
Assert.assertNotNull("missing jetty.css" , sr.getString("/resource/jetty-dir.css"));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
simple text
|
|
@ -14,27 +14,39 @@
|
|||
package org.eclipse.jetty.servlet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.GenericServlet;
|
||||
import javax.servlet.RequestDispatcher;
|
||||
import javax.servlet.Servlet;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletRequestWrapper;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.ServletResponseWrapper;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletRequestWrapper;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpServletResponseWrapper;
|
||||
|
||||
import org.eclipse.jetty.server.Dispatcher;
|
||||
import org.eclipse.jetty.server.LocalConnector;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
|
||||
import org.eclipse.jetty.server.handler.ResourceHandler;
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
@ -44,17 +56,27 @@ public class DispatcherTest
|
|||
{
|
||||
private Server _server;
|
||||
private LocalConnector _connector;
|
||||
private ServletContextHandler _context;
|
||||
|
||||
private ContextHandlerCollection _contextCollection;
|
||||
private ServletContextHandler _contextHandler;
|
||||
private ResourceHandler _resourceHandler;
|
||||
|
||||
@Before
|
||||
public void init() throws Exception
|
||||
{
|
||||
_server = new Server();
|
||||
_server.setSendServerVersion(false);
|
||||
_connector = new LocalConnector();
|
||||
_context = new ServletContextHandler();
|
||||
_context.setContextPath("/context");
|
||||
_server.setHandler(_context);
|
||||
|
||||
_contextCollection = new ContextHandlerCollection();
|
||||
_contextHandler = new ServletContextHandler();
|
||||
_contextHandler.setContextPath("/context");
|
||||
_contextCollection.addHandler(_contextHandler);
|
||||
_resourceHandler = new ResourceHandler();
|
||||
_resourceHandler.setResourceBase(MavenTestingUtils.getTestResourceDir("dispatchResourceTest").getAbsolutePath());
|
||||
ContextHandler resourceContextHandler = new ContextHandler("/resource");
|
||||
resourceContextHandler.setHandler(_resourceHandler);
|
||||
_contextCollection.addHandler(resourceContextHandler);
|
||||
_server.setHandler(_contextCollection);
|
||||
_server.addConnector( _connector );
|
||||
|
||||
_server.start();
|
||||
|
@ -70,8 +92,8 @@ public class DispatcherTest
|
|||
@Test
|
||||
public void testForward() throws Exception
|
||||
{
|
||||
_context.addServlet(ForwardServlet.class, "/ForwardServlet/*");
|
||||
_context.addServlet(AssertForwardServlet.class, "/AssertForwardServlet/*");
|
||||
_contextHandler.addServlet(ForwardServlet.class, "/ForwardServlet/*");
|
||||
_contextHandler.addServlet(AssertForwardServlet.class, "/AssertForwardServlet/*");
|
||||
|
||||
String expected=
|
||||
"HTTP/1.1 200 OK\r\n"+
|
||||
|
@ -87,8 +109,8 @@ public class DispatcherTest
|
|||
@Test
|
||||
public void testInclude() throws Exception
|
||||
{
|
||||
_context.addServlet(IncludeServlet.class, "/IncludeServlet/*");
|
||||
_context.addServlet(AssertIncludeServlet.class, "/AssertIncludeServlet/*");
|
||||
_contextHandler.addServlet(IncludeServlet.class, "/IncludeServlet/*");
|
||||
_contextHandler.addServlet(AssertIncludeServlet.class, "/AssertIncludeServlet/*");
|
||||
|
||||
String expected=
|
||||
"HTTP/1.1 200 OK\r\n"+
|
||||
|
@ -103,9 +125,9 @@ public class DispatcherTest
|
|||
@Test
|
||||
public void testForwardThenInclude() throws Exception
|
||||
{
|
||||
_context.addServlet(ForwardServlet.class, "/ForwardServlet/*");
|
||||
_context.addServlet(IncludeServlet.class, "/IncludeServlet/*");
|
||||
_context.addServlet(AssertForwardIncludeServlet.class, "/AssertForwardIncludeServlet/*");
|
||||
_contextHandler.addServlet(ForwardServlet.class, "/ForwardServlet/*");
|
||||
_contextHandler.addServlet(IncludeServlet.class, "/IncludeServlet/*");
|
||||
_contextHandler.addServlet(AssertForwardIncludeServlet.class, "/AssertForwardIncludeServlet/*");
|
||||
|
||||
String expected=
|
||||
"HTTP/1.1 200 OK\r\n"+
|
||||
|
@ -120,9 +142,9 @@ public class DispatcherTest
|
|||
@Test
|
||||
public void testIncludeThenForward() throws Exception
|
||||
{
|
||||
_context.addServlet(IncludeServlet.class, "/IncludeServlet/*");
|
||||
_context.addServlet(ForwardServlet.class, "/ForwardServlet/*");
|
||||
_context.addServlet(AssertIncludeForwardServlet.class, "/AssertIncludeForwardServlet/*");
|
||||
_contextHandler.addServlet(IncludeServlet.class, "/IncludeServlet/*");
|
||||
_contextHandler.addServlet(ForwardServlet.class, "/ForwardServlet/*");
|
||||
_contextHandler.addServlet(AssertIncludeForwardServlet.class, "/AssertIncludeForwardServlet/*");
|
||||
|
||||
|
||||
String expected=
|
||||
|
@ -140,8 +162,8 @@ public class DispatcherTest
|
|||
@Test
|
||||
public void testServletForward() throws Exception
|
||||
{
|
||||
_context.addServlet(DispatchServletServlet.class, "/dispatch/*");
|
||||
_context.addServlet(RogerThatServlet.class, "/roger/*");
|
||||
_contextHandler.addServlet(DispatchServletServlet.class, "/dispatch/*");
|
||||
_contextHandler.addServlet(RogerThatServlet.class, "/roger/*");
|
||||
|
||||
String expected=
|
||||
"HTTP/1.1 200 OK\r\n"+
|
||||
|
@ -157,8 +179,8 @@ public class DispatcherTest
|
|||
@Test
|
||||
public void testServletInclude() throws Exception
|
||||
{
|
||||
_context.addServlet(DispatchServletServlet.class, "/dispatch/*");
|
||||
_context.addServlet(RogerThatServlet.class, "/roger/*");
|
||||
_contextHandler.addServlet(DispatchServletServlet.class, "/dispatch/*");
|
||||
_contextHandler.addServlet(RogerThatServlet.class, "/roger/*");
|
||||
|
||||
String expected=
|
||||
"HTTP/1.1 200 OK\r\n"+
|
||||
|
@ -171,6 +193,61 @@ public class DispatcherTest
|
|||
assertEquals(expected, responses);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWorkingResourceHandler() throws Exception
|
||||
{
|
||||
String responses = _connector.getResponses("GET /resource/content.txt HTTP/1.0\n" + "Host: localhost\n\n");
|
||||
|
||||
assertTrue(responses.contains("content goes here")); // from inside the context.txt file
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("currently fails")
|
||||
public void testIncludeToResourceHandler() throws Exception
|
||||
{
|
||||
_contextHandler.addServlet(DispatchToResourceServlet.class, "/resourceServlet/*");
|
||||
|
||||
String responses = _connector.getResponses("GET /context/resourceServlet/content.txt?type=include HTTP/1.0\n" + "Host: localhost\n\n");
|
||||
|
||||
// from inside the context.txt file
|
||||
assertTrue(responses.contains("content goes here"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testForwardToResourceHandler() throws Exception
|
||||
{
|
||||
_contextHandler.addServlet(DispatchToResourceServlet.class, "/resourceServlet/*");
|
||||
|
||||
String responses = _connector.getResponses("GET /context/resourceServlet/content.txt?type=forward HTTP/1.0\n" + "Host: localhost\n\n");
|
||||
|
||||
// from inside the context.txt file
|
||||
assertTrue(responses.contains("content goes here"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("currently fails")
|
||||
public void testWrappedIncludeToResourceHandler() throws Exception
|
||||
{
|
||||
_contextHandler.addServlet(DispatchToResourceServlet.class, "/resourceServlet/*");
|
||||
|
||||
String responses = _connector.getResponses("GET /context/resourceServlet/content.txt?type=include&wrapped=true HTTP/1.0\n" + "Host: localhost\n\n");
|
||||
|
||||
// from inside the context.txt file
|
||||
assertTrue(responses.contains("content goes here"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("currently fails")
|
||||
public void testWrappedForwardToResourceHandler() throws Exception
|
||||
{
|
||||
_contextHandler.addServlet(DispatchToResourceServlet.class, "/resourceServlet/*");
|
||||
|
||||
String responses = _connector.getResponses("GET /context/resourceServlet/content.txt?type=forward&wrapped=true HTTP/1.0\n" + "Host: localhost\n\n");
|
||||
|
||||
// from inside the context.txt file
|
||||
assertTrue(responses.contains("content goes here"));
|
||||
}
|
||||
|
||||
public static class ForwardServlet extends HttpServlet implements Servlet
|
||||
{
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||
|
@ -230,6 +307,48 @@ public class DispatcherTest
|
|||
}
|
||||
}
|
||||
|
||||
public static class DispatchToResourceServlet extends HttpServlet implements Servlet
|
||||
{
|
||||
@Override
|
||||
public void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
|
||||
{
|
||||
ServletContext targetContext = getServletConfig().getServletContext().getContext("/resource");
|
||||
|
||||
RequestDispatcher dispatcher = targetContext.getRequestDispatcher(req.getPathInfo());
|
||||
|
||||
if ( "true".equals(req.getParameter("wrapped")))
|
||||
{
|
||||
if (req.getParameter("type").equals("forward"))
|
||||
{
|
||||
dispatcher.forward(new ServletRequestWrapper(req),new ServletResponseWrapper(res));
|
||||
}
|
||||
else if (req.getParameter("type").equals("include"))
|
||||
{
|
||||
dispatcher.include(new ServletRequestWrapper(req),new ServletResponseWrapper(res));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ServletException("type of forward or include is required");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (req.getParameter("type").equals("forward"))
|
||||
{
|
||||
dispatcher.forward(req,res);
|
||||
}
|
||||
else if (req.getParameter("type").equals("include"))
|
||||
{
|
||||
dispatcher.include(req,res);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ServletException("type of forward or include is required");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class AssertForwardServlet extends HttpServlet implements Servlet
|
||||
{
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
content goes here
|
Loading…
Reference in New Issue