282807 Better handling of 100 continues if response committed

git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@535 7e9141cc-0065-0410-87d8-b60c137991c4
This commit is contained in:
Greg Wilkins 2009-07-09 23:27:40 +00:00
parent 42a33c32fc
commit 1a47662030
4 changed files with 55 additions and 25 deletions

View File

@ -6,6 +6,7 @@ jetty-7.0.0.RC0 8 June 2009
+ 280843 Buffer pool uses isHeader + 280843 Buffer pool uses isHeader
+ 271535 Adding integration tests, and enabling RFC2616 tests + 271535 Adding integration tests, and enabling RFC2616 tests
+ 281287 Handle date headers before 1 Jan 1970 + 281287 Handle date headers before 1 Jan 1970
+ 282807 Better handling of 100 continues if response committed.
jetty-7.0.0.M4 1 June 2009 jetty-7.0.0.M4 1 June 2009
+ 281059 NPE in QTP with debug on + 281059 NPE in QTP with debug on

View File

@ -14,6 +14,7 @@
package org.eclipse.jetty.http; package org.eclipse.jetty.http;
import java.io.IOException; import java.io.IOException;
import java.io.InterruptedIOException;
import org.eclipse.jetty.io.Buffer; import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.BufferUtil; import org.eclipse.jetty.io.BufferUtil;
@ -305,6 +306,45 @@ public class HttpGenerator extends AbstractGenerator
// Should we flush the buffers? // Should we flush the buffers?
return super.isBufferFull() || _bufferChunked || _bypass || (_contentLength == HttpTokens.CHUNKED_CONTENT && _buffer != null && _buffer.space() < CHUNK_SPACE); return super.isBufferFull() || _bufferChunked || _bypass || (_contentLength == HttpTokens.CHUNKED_CONTENT && _buffer != null && _buffer.space() < CHUNK_SPACE);
} }
/* ------------------------------------------------------------ */
public void send1xx(int code) throws IOException
{
if (_state != STATE_HEADER)
return;
if (code<100||code>199)
throw new IllegalArgumentException("!1xx");
Status status=__status[code];
if (status==null)
throw new IllegalArgumentException(code+"?");
// get a header buffer
if (_header == null)
_header = _buffers.getHeader();
_header.put(status._responseLine);
_header.put(HttpTokens.CRLF);
try
{
// nasty semi busy flush!
while(_header.length()>0)
{
int len = _endp.flush(_header);
if (len<0)
throw new EofException();
if (len==0)
Thread.sleep(100);
}
}
catch(InterruptedException e)
{
Log.debug(e);
throw new InterruptedIOException(e.toString());
}
}
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public void completeHeader(HttpFields fields, boolean allContentAdded) throws IOException public void completeHeader(HttpFields fields, boolean allContentAdded) throws IOException
@ -682,7 +722,7 @@ public class HttpGenerator extends AbstractGenerator
} }
} }
if (!has_server && _status>100 && getSendServerVersion()) if (!has_server && _status>199 && getSendServerVersion())
_header.put(SERVER); _header.put(SERVER);
// end the header. // end the header.
@ -691,6 +731,8 @@ public class HttpGenerator extends AbstractGenerator
_state = STATE_CONTENT; _state = STATE_CONTENT;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**

View File

@ -307,12 +307,13 @@ public class HttpConnection implements Connection
// If the client is expecting 100 CONTINUE, then send it now. // If the client is expecting 100 CONTINUE, then send it now.
if (_expect100Continue) if (_expect100Continue)
{ {
// is content missing?
if (((HttpParser)_parser).getHeaderBuffer()==null || ((HttpParser)_parser).getHeaderBuffer().length()<2) if (((HttpParser)_parser).getHeaderBuffer()==null || ((HttpParser)_parser).getHeaderBuffer().length()<2)
{ {
_generator.setResponse(HttpStatus.CONTINUE_100, null); if (_generator.isCommitted())
_generator.completeHeader(null, true); throw new IllegalStateException("Committed before 100 Continues");
_generator.complete();
_generator.reset(false); ((HttpGenerator)_generator).send1xx(HttpStatus.CONTINUE_100);
} }
_expect100Continue=false; _expect100Continue=false;
} }
@ -800,11 +801,11 @@ public class HttpConnection implements Connection
switch(HttpHeaderValues.CACHE.getOrdinal(value)) switch(HttpHeaderValues.CACHE.getOrdinal(value))
{ {
case HttpHeaderValues.CONTINUE_ORDINAL: case HttpHeaderValues.CONTINUE_ORDINAL:
_expect100Continue=true; _expect100Continue=_generator instanceof HttpGenerator;
break; break;
case HttpHeaderValues.PROCESSING_ORDINAL: case HttpHeaderValues.PROCESSING_ORDINAL:
_expect102Processing=true; _expect102Processing=_generator instanceof HttpGenerator;
break; break;
default: default:
@ -819,10 +820,10 @@ public class HttpConnection implements Connection
switch(cb.getOrdinal()) switch(cb.getOrdinal())
{ {
case HttpHeaderValues.CONTINUE_ORDINAL: case HttpHeaderValues.CONTINUE_ORDINAL:
_expect100Continue=true; _expect100Continue=_generator instanceof HttpGenerator;
break; break;
case HttpHeaderValues.PROCESSING_ORDINAL: case HttpHeaderValues.PROCESSING_ORDINAL:
_expect102Processing=true; _expect102Processing=_generator instanceof HttpGenerator;
break; break;
default: default:
_expect=true; _expect=true;

View File

@ -379,22 +379,8 @@ public class Response implements HttpServletResponse
*/ */
public void sendProcessing() throws IOException public void sendProcessing() throws IOException
{ {
if (_connection.isExpecting102Processing()) if (_connection.isExpecting102Processing() && !isCommitted())
{ ((HttpGenerator)_connection.getGenerator()).send1xx(HttpStatus.PROCESSING_102);
Generator g = _connection.getGenerator();
if (g instanceof HttpGenerator)
{
HttpGenerator generator = (HttpGenerator)g;
boolean was_persistent=generator.isPersistent();
generator.setResponse(102,null);
generator.completeHeader(null,true);
generator.setPersistent(true);
generator.complete();
generator.flushBuffer();
generator.reset(false);
generator.setPersistent(was_persistent);
}
}
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */