279725 Support 100 and 102 expectations
git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@356 7e9141cc-0065-0410-87d8-b60c137991c4
This commit is contained in:
parent
4a38907a2c
commit
963fd5da81
|
@ -8,6 +8,7 @@ jetty-7.0.0.M3-SNAPSHOT
|
||||||
+ Portable continuations for jetty6 and servlet3
|
+ Portable continuations for jetty6 and servlet3
|
||||||
+ Refactored continuations to only support response wrapping
|
+ Refactored continuations to only support response wrapping
|
||||||
+ Added ContinuationThrowable
|
+ Added ContinuationThrowable
|
||||||
|
+ 279725 Support 100 and 102 expectations
|
||||||
|
|
||||||
jetty-7.0.0.M2 18 May 2009
|
jetty-7.0.0.M2 18 May 2009
|
||||||
+ JETTY-937 Work around Sun JVM bugs
|
+ JETTY-937 Work around Sun JVM bugs
|
||||||
|
|
|
@ -216,7 +216,7 @@ class SelectConnector extends AbstractLifeCycle implements HttpClient.Connector,
|
||||||
if (attachment instanceof HttpDestination)
|
if (attachment instanceof HttpDestination)
|
||||||
((HttpDestination)attachment).onConnectionFailed(ex);
|
((HttpDestination)attachment).onConnectionFailed(ex);
|
||||||
else
|
else
|
||||||
Log.warn(ex);
|
super.connectionFailed(channel,ex,attachment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ package org.eclipse.jetty.continuation;
|
||||||
|
|
||||||
import java.util.EventListener;
|
import java.util.EventListener;
|
||||||
|
|
||||||
import javax.servlet.ServletRequest;
|
|
||||||
import javax.servlet.ServletRequestListener;
|
import javax.servlet.ServletRequestListener;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -245,7 +245,8 @@ public abstract class SelectorManager extends AbstractLifeCycle
|
||||||
/* ------------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------------- */
|
||||||
protected void connectionFailed(SocketChannel channel,Throwable ex,Object attachment)
|
protected void connectionFailed(SocketChannel channel,Throwable ex,Object attachment)
|
||||||
{
|
{
|
||||||
Log.warn(ex);
|
Log.warn(ex+","+channel+","+attachment);
|
||||||
|
Log.debug(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------------- */
|
||||||
|
|
|
@ -98,11 +98,14 @@ public class HttpConnection implements Connection
|
||||||
|
|
||||||
private Object _associatedObject; // associated object
|
private Object _associatedObject; // associated object
|
||||||
|
|
||||||
private transient int _expect = UNKNOWN;
|
private int _version = UNKNOWN;
|
||||||
private transient int _version = UNKNOWN;
|
|
||||||
private transient boolean _head = false;
|
private boolean _expect = false;
|
||||||
private transient boolean _host = false;
|
private boolean _expect100Continue = false;
|
||||||
private transient boolean _delayedHandling=false;
|
private boolean _expect102Processing = false;
|
||||||
|
private boolean _head = false;
|
||||||
|
private boolean _host = false;
|
||||||
|
private boolean _delayedHandling=false;
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
public static HttpConnection getCurrentConnection()
|
public static HttpConnection getCurrentConnection()
|
||||||
|
@ -288,12 +291,19 @@ public class HttpConnection implements Connection
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/**
|
/**
|
||||||
* @return The input stream for this connection. The stream will be created if it does not already exist.
|
* Get the inputStream from the connection.
|
||||||
|
* <p>
|
||||||
|
* If the associated response has the Expect header set to 100 Continue,
|
||||||
|
* then accessing the input stream indicates that the handler/servlet
|
||||||
|
* is ready for the request body and thus a 100 Continue response is sent.
|
||||||
|
*
|
||||||
|
* @return The input stream for this connection.
|
||||||
|
* The stream will be created if it does not already exist.
|
||||||
*/
|
*/
|
||||||
public ServletInputStream getInputStream() throws IOException
|
public ServletInputStream getInputStream() throws IOException
|
||||||
{
|
{
|
||||||
// If the client is expecting 100 CONTINUE, then send it now.
|
// If the client is expecting 100 CONTINUE, then send it now.
|
||||||
if (_expect == HttpHeaderValues.CONTINUE_ORDINAL)
|
if (_expect100Continue)
|
||||||
{
|
{
|
||||||
if (((HttpParser)_parser).getHeaderBuffer()==null || ((HttpParser)_parser).getHeaderBuffer().length()<2)
|
if (((HttpParser)_parser).getHeaderBuffer()==null || ((HttpParser)_parser).getHeaderBuffer().length()<2)
|
||||||
{
|
{
|
||||||
|
@ -302,7 +312,7 @@ public class HttpConnection implements Connection
|
||||||
_generator.complete();
|
_generator.complete();
|
||||||
_generator.reset(false);
|
_generator.reset(false);
|
||||||
}
|
}
|
||||||
_expect = UNKNOWN;
|
_expect100Continue=false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_in == null)
|
if (_in == null)
|
||||||
|
@ -593,10 +603,10 @@ public class HttpConnection implements Connection
|
||||||
{
|
{
|
||||||
_request._async.doComplete();
|
_request._async.doComplete();
|
||||||
|
|
||||||
if (_expect == HttpHeaderValues.CONTINUE_ORDINAL)
|
if (_expect100Continue)
|
||||||
{
|
{
|
||||||
// Continue not sent so don't parse any content
|
// Continue not sent so don't parse any content
|
||||||
_expect = UNKNOWN;
|
_expect100Continue = false;
|
||||||
if (_parser instanceof HttpParser)
|
if (_parser instanceof HttpParser)
|
||||||
((HttpParser)_parser).setState(HttpParser.STATE_END);
|
((HttpParser)_parser).setState(HttpParser.STATE_END);
|
||||||
}
|
}
|
||||||
|
@ -705,7 +715,17 @@ public class HttpConnection implements Connection
|
||||||
return _request.getAsyncContinuation().isSuspended();
|
return _request.getAsyncContinuation().isSuspended();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
public boolean isExpecting100Continues()
|
||||||
|
{
|
||||||
|
return _expect100Continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
public boolean isExpecting102Processing()
|
||||||
|
{
|
||||||
|
return _expect102Processing;
|
||||||
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@ -722,7 +742,9 @@ public class HttpConnection implements Connection
|
||||||
public void startRequest(Buffer method, Buffer uri, Buffer version) throws IOException
|
public void startRequest(Buffer method, Buffer uri, Buffer version) throws IOException
|
||||||
{
|
{
|
||||||
_host = false;
|
_host = false;
|
||||||
_expect = UNKNOWN;
|
_expect = false;
|
||||||
|
_expect100Continue=false;
|
||||||
|
_expect102Processing=false;
|
||||||
_delayedHandling=false;
|
_delayedHandling=false;
|
||||||
_charset=null;
|
_charset=null;
|
||||||
|
|
||||||
|
@ -771,7 +793,39 @@ public class HttpConnection implements Connection
|
||||||
|
|
||||||
case HttpHeaders.EXPECT_ORDINAL:
|
case HttpHeaders.EXPECT_ORDINAL:
|
||||||
value = HttpHeaderValues.CACHE.lookup(value);
|
value = HttpHeaderValues.CACHE.lookup(value);
|
||||||
_expect = HttpHeaderValues.CACHE.getOrdinal(value);
|
switch(HttpHeaderValues.CACHE.getOrdinal(value))
|
||||||
|
{
|
||||||
|
case HttpHeaderValues.CONTINUE_ORDINAL:
|
||||||
|
_expect100Continue=true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HttpHeaderValues.PROCESSING_ORDINAL:
|
||||||
|
_expect102Processing=true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
String[] values = value.toString().split(",");
|
||||||
|
for (int i=0;values!=null && i<values.length;i++)
|
||||||
|
{
|
||||||
|
CachedBuffer cb=HttpHeaderValues.CACHE.get(values[i].trim());
|
||||||
|
if (cb==null)
|
||||||
|
_expect=true;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch(cb.getOrdinal())
|
||||||
|
{
|
||||||
|
case HttpHeaderValues.CONTINUE_ORDINAL:
|
||||||
|
_expect100Continue=true;
|
||||||
|
break;
|
||||||
|
case HttpHeaderValues.PROCESSING_ORDINAL:
|
||||||
|
_expect102Processing=true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_expect=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HttpHeaders.ACCEPT_ENCODING_ORDINAL:
|
case HttpHeaders.ACCEPT_ENCODING_ORDINAL:
|
||||||
|
@ -786,8 +840,7 @@ public class HttpConnection implements Connection
|
||||||
|
|
||||||
case HttpHeaders.CONNECTION_ORDINAL:
|
case HttpHeaders.CONNECTION_ORDINAL:
|
||||||
//looks rather clumsy, but the idea is to optimize for a single valued header
|
//looks rather clumsy, but the idea is to optimize for a single valued header
|
||||||
int ordinal = HttpHeaderValues.CACHE.getOrdinal(value);
|
switch(HttpHeaderValues.CACHE.getOrdinal(value))
|
||||||
switch(ordinal)
|
|
||||||
{
|
{
|
||||||
case -1:
|
case -1:
|
||||||
{
|
{
|
||||||
|
@ -858,20 +911,11 @@ public class HttpConnection implements Connection
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_expect != UNKNOWN)
|
if (_expect)
|
||||||
{
|
|
||||||
if (_expect == HttpHeaderValues.CONTINUE_ORDINAL)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
else if (_expect == HttpHeaderValues.PROCESSING_ORDINAL)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
_generator.sendError(HttpStatus.EXPECTATION_FAILED_417, null, null, true);
|
_generator.sendError(HttpStatus.EXPECTATION_FAILED_417, null, null, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -881,7 +925,7 @@ public class HttpConnection implements Connection
|
||||||
_request.setCharacterEncodingUnchecked(_charset);
|
_request.setCharacterEncodingUnchecked(_charset);
|
||||||
|
|
||||||
// Either handle now or wait for first content
|
// Either handle now or wait for first content
|
||||||
if ((((HttpParser)_parser).getContentLength()<=0 && !((HttpParser)_parser).isChunking())||_expect==HttpHeaderValues.CONTINUE_ORDINAL)
|
if ((((HttpParser)_parser).getContentLength()<=0 && !((HttpParser)_parser).isChunking())||_expect100Continue)
|
||||||
handleRequest();
|
handleRequest();
|
||||||
else
|
else
|
||||||
_delayedHandling=true;
|
_delayedHandling=true;
|
||||||
|
@ -900,6 +944,7 @@ public class HttpConnection implements Connection
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
*
|
||||||
|
@ -914,6 +959,7 @@ public class HttpConnection implements Connection
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
*
|
||||||
|
@ -924,7 +970,6 @@ public class HttpConnection implements Connection
|
||||||
{
|
{
|
||||||
Log.debug("Bad request!: "+version+" "+status+" "+reason);
|
Log.debug("Bad request!: "+version+" "+status+" "+reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -382,16 +382,13 @@ public class Response implements HttpServletResponse
|
||||||
* @see javax.servlet.http.HttpServletResponse#sendError(int)
|
* @see javax.servlet.http.HttpServletResponse#sendError(int)
|
||||||
*/
|
*/
|
||||||
public void sendProcessing() throws IOException
|
public void sendProcessing() throws IOException
|
||||||
|
{
|
||||||
|
if (_connection.isExpecting102Processing())
|
||||||
{
|
{
|
||||||
Generator g = _connection.getGenerator();
|
Generator g = _connection.getGenerator();
|
||||||
if (g instanceof HttpGenerator)
|
if (g instanceof HttpGenerator)
|
||||||
{
|
{
|
||||||
HttpGenerator generator = (HttpGenerator)g;
|
HttpGenerator generator = (HttpGenerator)g;
|
||||||
|
|
||||||
String expect = _connection.getRequest().getHeader(HttpHeaders.EXPECT);
|
|
||||||
|
|
||||||
if (expect!=null && expect.startsWith("102") && generator.getVersion()>=HttpVersions.HTTP_1_1_ORDINAL)
|
|
||||||
{
|
|
||||||
boolean was_persistent=generator.isPersistent();
|
boolean was_persistent=generator.isPersistent();
|
||||||
generator.setResponse(102,null);
|
generator.setResponse(102,null);
|
||||||
generator.completeHeader(null,true);
|
generator.completeHeader(null,true);
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
2 - two
|
2 - three
|
|
@ -1 +1 @@
|
||||||
1 - one
|
1 - two
|
Loading…
Reference in New Issue