Merge branch 'jetty-9.3.x' of github.com:eclipse/jetty.project into jetty-9.3.x

This commit is contained in:
Joakim Erdfelt 2017-02-02 15:54:27 -07:00
commit 0254854299
12 changed files with 161 additions and 23 deletions

View File

@ -260,6 +260,13 @@ public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.Res
return !proceed || async; return !proceed || async;
} }
@Override
public boolean contentComplete()
{
return false;
}
@Override @Override
public boolean messageComplete() public boolean messageComplete()
{ {

View File

@ -284,6 +284,12 @@ public class ResponseContentParser extends StreamContentParser
} }
} }
@Override
public boolean contentComplete()
{
return false;
}
@Override @Override
public boolean messageComplete() public boolean messageComplete()
{ {

View File

@ -175,6 +175,7 @@ public class ServerFCGIConnection extends AbstractConnection
LOG.debug("Request {} end on {}", request, channel); LOG.debug("Request {} end on {}", request, channel);
if (channel != null) if (channel != null)
{ {
channel.onContentComplete();
channel.onRequestComplete(); channel.onRequestComplete();
} }
} }

View File

@ -582,7 +582,25 @@ public class HttpParser
_length=-1; _length=-1;
return s; return s;
} }
/* ------------------------------------------------------------------------------- */
private boolean handleHeaderContentMessage()
{
boolean handle_header = _handler.headerComplete();
boolean handle_content = _handler.contentComplete();
boolean handle_message = _handler.messageComplete();
return handle_header || handle_content || handle_message;
}
/* ------------------------------------------------------------------------------- */
private boolean handleContentMessage()
{
boolean handle_content = _handler.contentComplete();
boolean handle_message = _handler.messageComplete();
return handle_content || handle_message;
}
/* ------------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------------- */
/* Parse a request or response line /* Parse a request or response line
*/ */
@ -730,10 +748,7 @@ public class HttpParser
handle=_requestHandler.startRequest(_methodString,_uri.toString(), HttpVersion.HTTP_0_9); handle=_requestHandler.startRequest(_methodString,_uri.toString(), HttpVersion.HTTP_0_9);
setState(State.END); setState(State.END);
BufferUtil.clear(buffer); BufferUtil.clear(buffer);
handle=_handler.headerComplete()||handle; handle = handleHeaderContentMessage() || handle;
_headerComplete=true;
handle=_handler.messageComplete()||handle;
return handle;
} }
else else
{ {
@ -801,10 +816,7 @@ public class HttpParser
handle=_requestHandler.startRequest(_methodString,_uri.toString(), HttpVersion.HTTP_0_9); handle=_requestHandler.startRequest(_methodString,_uri.toString(), HttpVersion.HTTP_0_9);
setState(State.END); setState(State.END);
BufferUtil.clear(buffer); BufferUtil.clear(buffer);
handle=_handler.headerComplete()||handle; handle = handleHeaderContentMessage() || handle;
_headerComplete=true;
handle=_handler.messageComplete()||handle;
return handle;
} }
} }
else if (ch<0) else if (ch<0)
@ -1071,10 +1083,7 @@ public class HttpParser
case NO_CONTENT: case NO_CONTENT:
setState(State.END); setState(State.END);
handle=_handler.headerComplete()||handle; return handleHeaderContentMessage();
_headerComplete=true;
handle=_handler.messageComplete()||handle;
return handle;
default: default:
setState(State.CONTENT); setState(State.CONTENT);
@ -1334,7 +1343,7 @@ public class HttpParser
if (_responseStatus>0 && _headResponse) if (_responseStatus>0 && _headResponse)
{ {
setState(State.END); setState(State.END);
return _handler.messageComplete(); return handleContentMessage();
} }
else else
{ {
@ -1391,7 +1400,7 @@ public class HttpParser
case EOF_CONTENT: case EOF_CONTENT:
case CHUNK_END: case CHUNK_END:
setState(State.CLOSED); setState(State.CLOSED);
return _handler.messageComplete(); return handleContentMessage();
case CONTENT: case CONTENT:
case CHUNKED_CONTENT: case CHUNKED_CONTENT:
@ -1467,7 +1476,7 @@ public class HttpParser
if (content == 0) if (content == 0)
{ {
setState(State.END); setState(State.END);
return _handler.messageComplete(); return handleContentMessage();
} }
} }
@ -1491,7 +1500,7 @@ public class HttpParser
if (content == 0) if (content == 0)
{ {
setState(State.END); setState(State.END);
return _handler.messageComplete(); return handleContentMessage();
} }
else else
{ {
@ -1514,7 +1523,7 @@ public class HttpParser
if(_contentPosition == _contentLength) if(_contentPosition == _contentLength)
{ {
setState(State.END); setState(State.END);
return _handler.messageComplete(); return handleContentMessage();
} }
} }
break; break;
@ -1541,7 +1550,11 @@ public class HttpParser
if (ch == HttpTokens.LINE_FEED) if (ch == HttpTokens.LINE_FEED)
{ {
if (_chunkLength == 0) if (_chunkLength == 0)
{
setState(State.CHUNK_END); setState(State.CHUNK_END);
if (_handler.contentComplete())
return true;
}
else else
setState(State.CHUNK); setState(State.CHUNK);
} }
@ -1558,7 +1571,11 @@ public class HttpParser
if (ch == HttpTokens.LINE_FEED) if (ch == HttpTokens.LINE_FEED)
{ {
if (_chunkLength == 0) if (_chunkLength == 0)
{
setState(State.CHUNK_END); setState(State.CHUNK_END);
if (_handler.contentComplete())
return true;
}
else else
setState(State.CHUNK); setState(State.CHUNK);
} }
@ -1736,6 +1753,8 @@ public class HttpParser
public boolean headerComplete(); public boolean headerComplete();
public boolean contentComplete();
public boolean messageComplete(); public boolean messageComplete();
/** /**

View File

@ -231,6 +231,12 @@ public class HttpGeneratorServerHTTPTest
return false; return false;
} }
@Override
public boolean contentComplete()
{
return true;
}
@Override @Override
public boolean messageComplete() public boolean messageComplete()
{ {

View File

@ -1986,6 +1986,12 @@ public class HttpParserTest
return false; return false;
} }
@Override
public boolean contentComplete()
{
return false;
}
@Override @Override
public boolean messageComplete() public boolean messageComplete()
{ {

View File

@ -310,6 +310,12 @@ public class HttpTester
add(field.getName(),field.getValue()); add(field.getName(),field.getValue());
} }
@Override
public boolean contentComplete()
{
return false;
}
@Override @Override
public boolean messageComplete() public boolean messageComplete()
{ {

View File

@ -114,7 +114,10 @@ public class HttpChannelOverHTTP2 extends HttpChannel
boolean endStream = frame.isEndStream(); boolean endStream = frame.isEndStream();
if (endStream) if (endStream)
{
onContentComplete();
onRequestComplete(); onRequestComplete();
}
_delayedUntilContent = getHttpConfiguration().isDelayDispatchUntilContent() && _delayedUntilContent = getHttpConfiguration().isDelayDispatchUntilContent() &&
!endStream && !_expect100Continue; !endStream && !_expect100Continue;
@ -150,6 +153,7 @@ public class HttpChannelOverHTTP2 extends HttpChannel
{ {
onRequest(request); onRequest(request);
getRequest().setAttribute("org.eclipse.jetty.pushed", Boolean.TRUE); getRequest().setAttribute("org.eclipse.jetty.pushed", Boolean.TRUE);
onContentComplete();
onRequestComplete(); onRequestComplete();
if (LOG.isDebugEnabled()) if (LOG.isDebugEnabled())
@ -255,7 +259,11 @@ public class HttpChannelOverHTTP2 extends HttpChannel
boolean endStream = frame.isEndStream(); boolean endStream = frame.isEndStream();
if (endStream) if (endStream)
handle |= onRequestComplete(); {
boolean handle_content = onContentComplete();
boolean handle_request = onRequestComplete();
handle |= handle_content | handle_request;
}
if (LOG.isDebugEnabled()) if (LOG.isDebugEnabled())
{ {

View File

@ -624,6 +624,13 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
return _request.getHttpInput().addContent(content); return _request.getHttpInput().addContent(content);
} }
public boolean onContentComplete()
{
if (LOG.isDebugEnabled())
LOG.debug("{} onContentComplete", this);
return false;
}
public boolean onRequestComplete() public boolean onRequestComplete()
{ {
if (LOG.isDebugEnabled()) if (LOG.isDebugEnabled())

View File

@ -458,13 +458,19 @@ public class HttpChannelOverHttp extends HttpChannel implements HttpParser.Reque
} }
@Override @Override
public boolean messageComplete() public boolean contentComplete()
{ {
boolean handle = onRequestComplete() || _delayedForContent; boolean handle = onContentComplete() || _delayedForContent;
_delayedForContent = false; _delayedForContent = false;
return handle; return handle;
} }
@Override
public boolean messageComplete()
{
return onRequestComplete();
}
@Override @Override
public int getHeaderCacheSize() public int getHeaderCacheSize()
{ {

View File

@ -424,6 +424,12 @@ public class LocalConnector extends AbstractConnector
public void parsedHeader(HttpField field) public void parsedHeader(HttpField field)
{ {
} }
@Override
public boolean contentComplete()
{
return false;
}
@Override @Override
public boolean messageComplete() public boolean messageComplete()

View File

@ -152,7 +152,7 @@ public class HttpConnectionTest
@Test @Test
public void testDate() throws Exception public void testDate() throws Exception
{ {
String response=connector.getResponses("GET / HTTP/1.1\r\n"+ String response=connector.getResponse("GET / HTTP/1.1\r\n"+
"Host: localhost:80\r\n"+ "Host: localhost:80\r\n"+
"Connection: close\r\n"+ "Connection: close\r\n"+
"\r\n"); "\r\n");
@ -265,7 +265,7 @@ public class HttpConnectionTest
@Test @Test
public void testEmptyChunk() throws Exception public void testEmptyChunk() throws Exception
{ {
String response=connector.getResponses("GET /R1 HTTP/1.1\r\n"+ String response=connector.getResponse("GET /R1 HTTP/1.1\r\n"+
"Host: localhost\r\n"+ "Host: localhost\r\n"+
"Transfer-Encoding: chunked\r\n"+ "Transfer-Encoding: chunked\r\n"+
"Content-Type: text/plain\r\n"+ "Content-Type: text/plain\r\n"+
@ -279,6 +279,66 @@ public class HttpConnectionTest
checkContains(response,offset,"/R1"); checkContains(response,offset,"/R1");
} }
@Test
public void testChunk() throws Exception
{
String response=connector.getResponse("GET /R1 HTTP/1.1\r\n"+
"Host: localhost\r\n"+
"Transfer-Encoding: chunked\r\n"+
"Content-Type: text/plain\r\n"+
"Connection: close\r\n"+
"\r\n"+
"A\r\n" +
"0123456789\r\n"+
"0\r\n" +
"\r\n");
int offset=0;
offset = checkContains(response,offset,"HTTP/1.1 200");
offset = checkContains(response,offset,"/R1");
checkContains(response,offset,"0123456789");
}
@Test
public void testChunkTrailer() throws Exception
{
String response=connector.getResponse("GET /R1 HTTP/1.1\r\n"+
"Host: localhost\r\n"+
"Transfer-Encoding: chunked\r\n"+
"Content-Type: text/plain\r\n"+
"Connection: close\r\n"+
"\r\n"+
"A\r\n" +
"0123456789\r\n"+
"0\r\n" +
"Trailer: ignored\r\n" +
"\r\n");
int offset=0;
offset = checkContains(response,offset,"HTTP/1.1 200");
offset = checkContains(response,offset,"/R1");
checkContains(response,offset,"0123456789");
}
@Test
public void testChunkNoTrailer() throws Exception
{
String response=connector.getResponse("GET /R1 HTTP/1.1\r\n"+
"Host: localhost\r\n"+
"Transfer-Encoding: chunked\r\n"+
"Content-Type: text/plain\r\n"+
"Connection: close\r\n"+
"\r\n"+
"A\r\n" +
"0123456789\r\n"+
"0\r\n");
int offset=0;
offset = checkContains(response,offset,"HTTP/1.1 200");
offset = checkContains(response,offset,"/R1");
checkContains(response,offset,"0123456789");
}
@Test @Test
public void testHead() throws Exception public void testHead() throws Exception
{ {
@ -723,7 +783,7 @@ public class HttpConnectionTest
try try
{ {
int offset=0; int offset=0;
response=connector.getResponses("GET /R1 HTTP/1.1\r\n"+ response=connector.getResponse("GET /R1 HTTP/1.1\r\n"+
"Host: localhost\r\n"+ "Host: localhost\r\n"+
"Connection: TE, close\r\n"+ "Connection: TE, close\r\n"+
"Transfer-Encoding: chunked\r\n"+ "Transfer-Encoding: chunked\r\n"+