jetty-9 jetty-http passing unit tests

This commit is contained in:
Greg Wilkins 2012-03-08 14:13:40 +11:00
parent 3d12ef7075
commit 8c25941e04
5 changed files with 567 additions and 648 deletions

View File

@ -20,6 +20,7 @@ import java.nio.ByteBuffer;
import javax.swing.text.View;
import org.eclipse.jetty.http.HttpGenerator.Action;
import org.eclipse.jetty.io.Buffers;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.EofException;
@ -81,9 +82,10 @@ public class HttpGenerator
private static final Logger LOG = Log.getLogger(HttpGenerator.class);
// states
enum State { START, COMPLETING_UNCOMMITTED, COMMITTING, COMMITTING_COMPLETING, COMMITTED, COMPLETING, END };
enum Result { NEED_COMMIT,NEED_CHUNK,NEED_BUFFER,FLUSH,FLUSH_CONTENT,NEED_COMPLETE,OK,SHUTDOWN_OUT};
enum Action { FLUSH, COMPLETE, PREPARE };
enum State { START, COMMITTING, COMMITTING_COMPLETING, COMMITTED, COMPLETING, END };
enum Result { NEED_CHUNK,NEED_HEADER,NEED_BUFFER,FLUSH,FLUSH_CONTENT,OK,SHUTDOWN_OUT};
public static final byte[] NO_BYTES = {};
@ -92,6 +94,8 @@ public class HttpGenerator
private State _state = State.START;
private int _status = 0;
private final HttpFields _fields;
private HttpVersion _version = HttpVersion.HTTP_1_1;
private byte[] _reason;
private byte[] _method;
@ -132,7 +136,13 @@ public class HttpGenerator
// data
private boolean _needCRLF = false;
/* ------------------------------------------------------------------------------- */
public HttpGenerator(HttpFields fields)
{
_fields=fields;
}
/* ------------------------------------------------------------------------------- */
public void reset()
{
@ -152,6 +162,7 @@ public class HttpGenerator
_needCRLF = false;
_uri=null;
_noContent=false;
_fields.clear();
}
/* ------------------------------------------------------------ */
@ -193,7 +204,7 @@ public class HttpGenerator
/* ------------------------------------------------------------ */
public boolean isCommitted()
{
return _state != State.START;
return _state.ordinal() >= State.COMMITTED.ordinal();
}
/* ------------------------------------------------------------ */
@ -367,25 +378,115 @@ public class HttpGenerator
return _method==null;
}
/* ------------------------------------------------------------ */
public Result commit(HttpFields fields,ByteBuffer header,ByteBuffer buffer, ByteBuffer content, boolean last) throws IOException
public Result generate(ByteBuffer header, ByteBuffer chunk, ByteBuffer buffer, ByteBuffer content, Action action)
{
Result result = Result.OK;
if (_state==State.END)
return result;
if (action==null)
action=Action.PREPARE;
// Do we have content to handle
if (BufferUtil.hasContent(content))
{
// Do we have too much content?
if (_contentLength>0 && content.remaining()>(_contentLength-_contentPrepared))
{
LOG.warn("Content truncated at {}",new Throwable());
content.limit(content.position()+(int)(_contentLength-_contentPrepared));
}
if (isResponse() && _status==0)
throw new EofException(); // TODO ???
// Can we do a direct flush
if (BufferUtil.isEmpty(buffer) && content.remaining()>_largeContent)
{
if (isCommitted())
{
if (isChunking())
{
if (chunk==null)
return Result.NEED_CHUNK;
BufferUtil.clearToFill(chunk);
prepareChunk(chunk,content.remaining());
BufferUtil.flipToFlush(chunk,0);
}
_contentPrepared+=content.remaining();
return Result.FLUSH_CONTENT;
}
int pos=header.position();
_state=action==Action.COMPLETE?State.COMMITTING_COMPLETING:State.COMMITTING;
result=Result.FLUSH_CONTENT;
}
else
{
// we copy content to buffer
// if we don't have one, we need one
if (buffer==null)
return Result.NEED_BUFFER;
// Copy the content
_contentPrepared+=BufferUtil.put(content,buffer);
// are we full?
if (BufferUtil.isAtCapacity(buffer))
{
if (isCommitted())
{
if (isChunking())
{
if (chunk==null)
return Result.NEED_CHUNK;
BufferUtil.clearToFill(chunk);
prepareChunk(chunk,buffer.remaining());
BufferUtil.flipToFlush(chunk,0);
}
return Result.FLUSH;
}
_state=action==Action.COMPLETE?State.COMMITTING_COMPLETING:State.COMMITTING;
result=Result.FLUSH;
}
}
}
// Handle the actions
if (result==Result.OK)
{
switch(action)
{
case COMPLETE:
if (!isCommitted())
_state=State.COMMITTING_COMPLETING;
else if (_state==State.COMMITTED)
_state=State.COMPLETING;
result=BufferUtil.hasContent(buffer)?Result.FLUSH:Result.OK;
break;
case FLUSH:
if (!isCommitted())
_state=State.COMMITTING;
result=BufferUtil.hasContent(buffer)?Result.FLUSH:Result.OK;
break;
}
}
// flip header if we have one
final int pos=header==null?-1:BufferUtil.flipToFill(header);
try
{
BufferUtil.flipToFill(header);
switch(_state)
// handle by state
switch (_state)
{
case START:
case COMPLETING_UNCOMMITTED:
return Result.OK;
case COMMITTING:
case COMMITTING_COMPLETING:
{
if (isRequest())
{
if (header==null || header.capacity()<=CHUNK_SIZE)
return Result.NEED_HEADER;
if(_version==HttpVersion.HTTP_0_9)
{
_noContent=true;
@ -399,14 +500,22 @@ public class HttpGenerator
else
{
// Responses
// Do we need a response header?
if (_version == HttpVersion.HTTP_0_9)
{
_persistent = false;
_contentLength = HttpTokens.EOF_CONTENT;
_state = State.COMMITTED;
return prepareContent(null,buffer,content);
if (result==Result.FLUSH_CONTENT)
_contentPrepared+=content.remaining();
return result;
}
// yes we need a response header
if (header==null || header.capacity()<=CHUNK_SIZE)
return Result.NEED_HEADER;
// Are we persistent by default?
if (_persistent==null)
_persistent=(_version.ordinal() > HttpVersion.HTTP_1_0.ordinal());
@ -430,69 +539,115 @@ public class HttpGenerator
_noContent=true;
}
}
generateHeaders(fields,header,content,last);
_state = _state==State.COMPLETING_UNCOMMITTED?State.COMMITTING_COMPLETING:State.COMMITTING;
// fall through to COMMITTING states
case COMMITTING:
case COMMITTING_COMPLETING:
boolean completing=action==Action.COMPLETE||_state==State.COMMITTING_COMPLETING;
generateHeaders(header,content,completing);
_state = completing?State.COMPLETING:State.COMMITTED;
// Handle any content
if (BufferUtil.hasContent(content))
// handle result
switch(result)
{
// Do we have too much content?
if (_contentLength>0 && content.remaining()>(_contentLength-_contentPrepared))
{
LOG.warn("Content truncated at {}",new Throwable());
content.limit(content.position()+(int)(_contentLength-_contentPrepared));
}
// Can we do a direct flush
if (BufferUtil.isEmpty(buffer) && content.remaining()>_largeContent)
{
_contentPrepared+=content.remaining();
case FLUSH:
if (isChunking())
prepareChunk(header,buffer.remaining());
break;
case FLUSH_CONTENT:
if (isChunking())
prepareChunk(header,content.remaining());
return Result.FLUSH_CONTENT;
}
// we copy content to buffer
// if we don't have one, we need one
if (buffer==null)
return Result.NEED_BUFFER;
_contentPrepared+=BufferUtil.put(content,buffer);
if (isChunking())
prepareChunk(header,buffer.remaining());
return Result.FLUSH;
_contentPrepared+=content.remaining();
break;
case OK:
if (BufferUtil.hasContent(buffer))
{
if (isChunking())
prepareChunk(header,buffer.remaining());
}
result=Result.FLUSH;
}
_state = _state==State.COMMITTING?State.COMMITTED:State.COMPLETING;
break;
default:
throw new IllegalStateException(this.toString());
}
}
catch(BufferOverflowException e)
{
throw new RuntimeException("Header>"+header.capacity(),e);
return result;
}
case COMMITTED:
return Result.OK;
case COMPLETING:
// handle content with commit
if (isChunking())
{
if (chunk==null)
return Result.NEED_CHUNK;
BufferUtil.clearToFill(chunk);
switch(result)
{
case FLUSH:
prepareChunk(chunk,buffer.remaining());
break;
case FLUSH_CONTENT:
prepareChunk(chunk,content.remaining());
case OK:
if (BufferUtil.hasContent(buffer))
{
result=Result.FLUSH;
prepareChunk(chunk,buffer.remaining());
}
else
{
result=Result.FLUSH;
_state=State.END;
prepareChunk(chunk,0);
}
}
BufferUtil.flipToFlush(chunk,0);
}
else if (result==Result.OK)
{
if (BufferUtil.hasContent(buffer))
result=Result.FLUSH;
else
_state=State.END;
}
return result;
default:
throw new IllegalStateException();
}
}
finally
{
BufferUtil.flipToFlush(header,pos);
if (pos>=0)
BufferUtil.flipToFlush(header,pos);
}
return _state==State.COMPLETING?Result.NEED_COMPLETE:Result.OK;
}
/* ------------------------------------------------------------ */
private void prepareChunk(ByteBuffer chunk, int remaining)
{
// if we need CRLF add this to header
if (_needCRLF)
BufferUtil.putCRLF(chunk);
// Add the chunk size to the header
if (remaining>0)
{
BufferUtil.putHexInt(chunk, remaining);
BufferUtil.putCRLF(chunk);
_needCRLF=true;
}
else
{
chunk.put(LAST_CHUNK);
_needCRLF=false;
}
}
/* ------------------------------------------------------------ */
private void generateRequestLine(ByteBuffer header)
{
@ -545,7 +700,7 @@ public class HttpGenerator
}
/* ------------------------------------------------------------ */
private void generateHeaders(HttpFields fields,ByteBuffer header,ByteBuffer content,boolean last)
private void generateHeaders(ByteBuffer header,ByteBuffer content,boolean last)
{
// Add Date header
@ -566,9 +721,9 @@ public class HttpGenerator
StringBuilder connection = null;
// Generate fields
if (fields != null)
if (_fields != null)
{
for (HttpFields.Field field : fields)
for (HttpFields.Field field : _fields)
{
HttpHeader name = HttpHeader.CACHE.get(field.getName());
@ -579,8 +734,14 @@ public class HttpGenerator
long length = field.getLongValue();
if (length>=0)
{
if (length < _contentPrepared || last && length != _contentPrepared)
LOG.warn("Incorrect ContentLength ignored ",new Throwable());
long prepared=_contentPrepared+BufferUtil.remaining(content);
if (length < prepared || last && length != prepared)
{
LOG.warn("Incorrect ContentLength: "+length+"!="+prepared);
if (LOG.isDebugEnabled())
LOG.debug(new Throwable());
_contentLength=HttpTokens.UNKNOWN_CONTENT;
}
else
{
// write the field to the header
@ -694,9 +855,14 @@ public class HttpGenerator
}
default:
header.put(name.toBytesColonSpace());
field.putValueTo(header);
header.put(CRLF);
if (name==null)
field.putTo(header);
else
{
header.put(name.toBytesColonSpace());
field.putValueTo(header);
header.put(CRLF);
}
}
}
@ -828,178 +994,6 @@ public class HttpGenerator
}
/* ------------------------------------------------------------ */
public Result prepareContent(ByteBuffer chunk, ByteBuffer buffer, ByteBuffer content)
{
// Do we have too much content?
if (_contentLength>0 && content.remaining()>(_contentLength-_contentPrepared))
{
LOG.warn("Content truncated at {}",new Throwable());
content.limit(content.position()+(int)(_contentLength-_contentPrepared));
}
switch (_state)
{
case START:
// Can we do a direct flush
if (BufferUtil.isEmpty(buffer) && content.remaining()>_largeContent)
return Result.NEED_COMMIT;
// we copy content to buffer
// if we don't have one, we need one
if (buffer==null)
return Result.NEED_BUFFER;
// copy content to buffer
_contentPrepared+=BufferUtil.put(content,buffer);
// are we full?
if (BufferUtil.isAtCapacity(buffer))
return Result.NEED_COMMIT;
return Result.OK;
case COMPLETING:
return Result.NEED_COMPLETE;
case COMMITTED:
// Can we do a direct flush
if (BufferUtil.isEmpty(buffer) && content.remaining()>_largeContent)
{
if (isChunking())
{
if (chunk==null)
return Result.NEED_CHUNK;
BufferUtil.clearToFill(chunk);
prepareChunk(chunk,content.remaining());
BufferUtil.flipToFlush(chunk,0);
}
_contentPrepared+=content.remaining();
return Result.FLUSH_CONTENT;
}
// we copy content to buffer
// if we don't have one, we need one
if (buffer==null)
return Result.NEED_BUFFER;
// Copy the content
_contentPrepared+=BufferUtil.put(content,buffer);
// are we full?
if (BufferUtil.isAtCapacity(buffer))
{
if (isChunking())
{
if (chunk==null)
return Result.NEED_CHUNK;
BufferUtil.clearToFill(chunk);
prepareChunk(chunk,buffer.remaining());
BufferUtil.flipToFlush(chunk,0);
}
return Result.FLUSH;
}
return Result.OK;
default:
throw new IllegalStateException();
}
}
/* ------------------------------------------------------------ */
private void prepareChunk(ByteBuffer chunk, int remaining)
{
// if we need CRLF add this to header
if (_needCRLF)
BufferUtil.putCRLF(chunk);
// Add the chunk size to the header
if (remaining>0)
{
BufferUtil.putHexInt(chunk, remaining);
BufferUtil.putCRLF(chunk);
_needCRLF=true;
}
else
{
chunk.put(LAST_CHUNK);
_needCRLF=false;
}
}
/* ------------------------------------------------------------ */
/**
* @throws IOException
*/
public Result flush(ByteBuffer chunk, ByteBuffer buffer) throws IOException
{
switch(_state)
{
case START:
return Result.NEED_COMMIT;
case COMMITTED:
if (isChunking())
{
if (chunk==null)
return Result.NEED_CHUNK;
if (BufferUtil.hasContent(buffer))
{
BufferUtil.clearToFill(chunk);
prepareChunk(chunk,buffer.remaining());
BufferUtil.flipToFlush(chunk,0);
}
}
}
return Result.FLUSH;
}
/* ------------------------------------------------------------ */
/**
* Complete the message.
*
* @throws IOException
*/
public Result complete(ByteBuffer chunk, ByteBuffer buffer) throws IOException
{
if (_state == State.END)
return Result.OK;
switch(_state)
{
case START:
case COMPLETING_UNCOMMITTED:
_state=State.COMPLETING_UNCOMMITTED;
return Result.NEED_COMMIT;
case COMPLETING:
case COMMITTED:
_state=State.COMPLETING;
if (isChunking())
{
if (BufferUtil.hasContent(buffer))
{
if (chunk==null)
return Result.NEED_CHUNK;
BufferUtil.clearToFill(chunk);
prepareChunk(chunk,buffer.remaining());
BufferUtil.flipToFlush(chunk,0);
return Result.FLUSH;
}
_state=State.END;
BufferUtil.clearToFill(chunk);
prepareChunk(chunk,0);
BufferUtil.flipToFlush(chunk,0);
return Result.FLUSH;
}
else if (BufferUtil.hasContent(buffer))
return Result.FLUSH;
}
_state=State.END;
return Result.OK;
}
/* ------------------------------------------------------------------------------- */
public static byte[] getReasonBuffer(int code)

View File

@ -449,7 +449,7 @@ public class HttpParser
break;
case CONNECTION:
switch(_value)
switch(_value==null?HttpHeaderValue.UNKNOWN:_value)
{
case CLOSE:
_persistent=false;
@ -662,7 +662,7 @@ public class HttpParser
else if (HttpHeaderValue.hasKnownValues(_header))
{
_value=HttpHeaderValue.CACHE.get(buffer,start,length);
_field1=_value.toString();
_field1=_value!=null?_value.toString():BufferUtil.toString(buffer,start,length,StringUtil.__ISO_8859_1_CHARSET);
}
else
{

View File

@ -24,6 +24,7 @@ import java.nio.ByteBuffer;
import javax.swing.text.View;
import org.eclipse.jetty.http.HttpGenerator.Action;
import org.eclipse.jetty.io.ByteArrayEndPoint;
import org.eclipse.jetty.io.SimpleBuffers;
import org.eclipse.jetty.util.BufferUtil;
@ -41,9 +42,9 @@ public class HttpGeneratorClientTest
@Test
public void testRequestNoContent() throws Exception
{
ByteBuffer header=BufferUtil.allocate(8096);
ByteBuffer header=BufferUtil.allocate(2048);
HttpFields fields = new HttpFields();
HttpGenerator gen = new HttpGenerator();
HttpGenerator gen = new HttpGenerator(fields);
fields.add("Host","something");
fields.add("User-Agent","test");
@ -51,23 +52,24 @@ public class HttpGeneratorClientTest
gen.setRequest(HttpMethod.GET,"/index.html",HttpVersion.HTTP_1_1);
HttpGenerator.Result
result=gen.complete(null,null);
assertEquals(HttpGenerator.State.COMPLETING_UNCOMMITTED,gen.getState());
assertEquals(HttpGenerator.Result.NEED_COMMIT,result);
result=gen.generate(null,null,null,null,Action.COMPLETE);
assertEquals(HttpGenerator.State.COMMITTING_COMPLETING,gen.getState());
assertEquals(HttpGenerator.Result.NEED_HEADER,result);
result=gen.commit(fields,header,null,null,true);
assertEquals(HttpGenerator.Result.NEED_COMPLETE,result);
String out = BufferUtil.toString(header);
result=gen.generate(header,null,null,null,null);
assertEquals(HttpGenerator.Result.FLUSH,result);
String head = BufferUtil.toString(header);
BufferUtil.clear(header);
assertThat(out,containsString("GET /index.html HTTP/1.1"));
assertThat(out,not(containsString("Content-Length")));
result=gen.complete(null,null);
result=gen.generate(null,null,null,null,null);
assertEquals(HttpGenerator.Result.OK,result);
assertEquals(HttpGenerator.State.END,gen.getState());
assertEquals(0,gen.getContentWritten()); }
assertEquals(0,gen.getContentWritten());
assertThat(head,containsString("GET /index.html HTTP/1.1"));
assertThat(head,not(containsString("Content-Length")));
}
@Test
public void testRequestWithSmallContent() throws Exception
@ -77,7 +79,7 @@ public class HttpGeneratorClientTest
ByteBuffer content=BufferUtil.toBuffer("Hello World");
ByteBuffer content1=BufferUtil.toBuffer(". The quick brown fox jumped over the lazy dog.");
HttpFields fields = new HttpFields();
HttpGenerator gen = new HttpGenerator();
HttpGenerator gen = new HttpGenerator(fields);
gen.setVersion(HttpVersion.HTTP_1_1);
gen.setRequest("POST","/index.html");
@ -86,35 +88,36 @@ public class HttpGeneratorClientTest
HttpGenerator.Result
result=gen.prepareContent(null,null,content);
result=gen.generate(null,null,null,content,null);
assertEquals(HttpGenerator.Result.NEED_BUFFER,result);
assertEquals(HttpGenerator.State.START,gen.getState());
result=gen.prepareContent(null,buffer,content);
result=gen.generate(null,null,buffer,content,null);
assertEquals(HttpGenerator.Result.OK,result);
assertEquals(HttpGenerator.State.START,gen.getState());
assertEquals("Hello World",BufferUtil.toString(buffer));
assertTrue(BufferUtil.isEmpty(content));
result=gen.prepareContent(null,buffer,content1);
result=gen.generate(null,null,buffer,content1,null);
assertEquals(HttpGenerator.Result.OK,result);
assertEquals(HttpGenerator.State.START,gen.getState());
assertEquals("Hello World. The quick brown fox jumped over the lazy dog.",BufferUtil.toString(buffer));
assertTrue(BufferUtil.isEmpty(content));
assertTrue(BufferUtil.isEmpty(content1));
result=gen.complete(null,buffer);
assertEquals(HttpGenerator.Result.NEED_COMMIT,result);
assertEquals(HttpGenerator.State.COMPLETING_UNCOMMITTED,gen.getState());
result=gen.generate(null,null,buffer,null,Action.COMPLETE);
assertEquals(HttpGenerator.Result.NEED_HEADER,result);
assertEquals(HttpGenerator.State.COMMITTING_COMPLETING,gen.getState());
result=gen.commit(fields,header,buffer,content,true);
result=gen.generate(header,null,buffer,null,null);
assertEquals(HttpGenerator.Result.FLUSH,result);
assertEquals(HttpGenerator.State.COMPLETING,gen.getState());
String head = BufferUtil.toString(header);
BufferUtil.clear(header);
String body = BufferUtil.toString(buffer);
BufferUtil.clear(buffer);
result=gen.complete(null,buffer);
result=gen.generate(null,null,buffer,null,null);
assertEquals(HttpGenerator.Result.OK,result);
assertEquals(HttpGenerator.State.END,gen.getState());
@ -136,7 +139,7 @@ public class HttpGeneratorClientTest
ByteBuffer content0=BufferUtil.toBuffer("Hello World! ");
ByteBuffer content1=BufferUtil.toBuffer("The quick brown fox jumped over the lazy dog. ");
HttpFields fields = new HttpFields();
HttpGenerator gen = new HttpGenerator();
HttpGenerator gen = new HttpGenerator(fields);
gen.setVersion(HttpVersion.HTTP_1_1);
gen.setRequest("POST","/index.html");
@ -145,25 +148,25 @@ public class HttpGeneratorClientTest
HttpGenerator.Result
result=gen.prepareContent(null,null,content0);
result=gen.generate(null,null,null,content0,null);
assertEquals(HttpGenerator.Result.NEED_BUFFER,result);
assertEquals(HttpGenerator.State.START,gen.getState());
result=gen.prepareContent(null,buffer,content0);
result=gen.generate(null,null,buffer,content0,null);
assertEquals(HttpGenerator.Result.OK,result);
assertEquals(HttpGenerator.State.START,gen.getState());
assertEquals("Hello World! ",BufferUtil.toString(buffer));
assertEquals(0,content0.remaining());
result=gen.prepareContent(null,buffer,content1);
assertEquals(HttpGenerator.Result.NEED_COMMIT,result);
assertEquals(HttpGenerator.State.START,gen.getState());
result=gen.generate(null,null,buffer,content1,null);
assertEquals(HttpGenerator.Result.NEED_HEADER,result);
assertEquals(HttpGenerator.State.COMMITTING,gen.getState());
assertEquals("Hello World! The",BufferUtil.toString(buffer));
assertEquals(43,content1.remaining());
result=gen.commit(fields,header,buffer,content1,false);
result=gen.generate(header,null,buffer,content1,null);
assertEquals(HttpGenerator.Result.FLUSH,result);
assertEquals(HttpGenerator.State.COMMITTING,gen.getState());
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
assertEquals("Hello World! The",BufferUtil.toString(buffer));
assertEquals(43,content1.remaining());
assertTrue(gen.isChunking());
@ -173,16 +176,12 @@ public class HttpGeneratorClientTest
String body = BufferUtil.toString(buffer);
BufferUtil.clear(buffer);
result=gen.commit(fields,header,buffer,content1,false);
assertEquals(HttpGenerator.Result.OK,result);
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
result=gen.prepareContent(null,buffer,content1);
result=gen.generate(null,null,buffer,content1,null);
assertEquals(HttpGenerator.Result.NEED_CHUNK,result);
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
ByteBuffer chunk=BufferUtil.allocate(HttpGenerator.CHUNK_SIZE);
result=gen.prepareContent(chunk,buffer,content1);
result=gen.generate(null,chunk,buffer,content1,null);
assertEquals(HttpGenerator.Result.FLUSH,result);
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
assertEquals("\r\n10\r\n",BufferUtil.toString(chunk));
@ -192,7 +191,7 @@ public class HttpGeneratorClientTest
BufferUtil.clear(chunk);
BufferUtil.clear(buffer);
result=gen.prepareContent(chunk,buffer,content1);
result=gen.generate(null,chunk,buffer,content1,null);
assertEquals(HttpGenerator.Result.FLUSH,result);
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
assertEquals("\r\n10\r\n",BufferUtil.toString(chunk));
@ -202,14 +201,14 @@ public class HttpGeneratorClientTest
BufferUtil.clear(chunk);
BufferUtil.clear(buffer);
result=gen.prepareContent(chunk,buffer,content1);
result=gen.generate(null,chunk,buffer,content1,null);
assertEquals(HttpGenerator.Result.OK,result);
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
assertEquals("",BufferUtil.toString(chunk));
assertEquals(" lazy dog. ",BufferUtil.toString(buffer));
assertEquals(0,content1.remaining());
result=gen.complete(chunk,buffer);
result=gen.generate(null,chunk,buffer,null,Action.COMPLETE);
assertEquals(HttpGenerator.Result.FLUSH,result);
assertEquals(HttpGenerator.State.COMPLETING,gen.getState());
assertEquals("\r\nB\r\n",BufferUtil.toString(chunk));
@ -218,16 +217,15 @@ public class HttpGeneratorClientTest
BufferUtil.clear(chunk);
BufferUtil.clear(buffer);
result=gen.complete(chunk,buffer);
result=gen.generate(null,chunk,buffer,null,null);
assertEquals(HttpGenerator.Result.FLUSH,result);
assertEquals(HttpGenerator.State.END,gen.getState());
assertEquals("\r\n0\r\n\r\n",BufferUtil.toString(chunk));
assertEquals(0,buffer.remaining());
body += BufferUtil.toString(chunk);
BufferUtil.clear(chunk);
BufferUtil.clear(buffer);
result=gen.complete(chunk,buffer);
result=gen.generate(null,chunk,buffer,null,null);
assertEquals(HttpGenerator.Result.OK,result);
assertEquals(HttpGenerator.State.END,gen.getState());
@ -249,7 +247,7 @@ public class HttpGeneratorClientTest
ByteBuffer content0=BufferUtil.toBuffer("Hello Cruel World! ");
ByteBuffer content1=BufferUtil.toBuffer("The quick brown fox jumped over the lazy dog. ");
HttpFields fields = new HttpFields();
HttpGenerator gen = new HttpGenerator();
HttpGenerator gen = new HttpGenerator(fields);
gen.setLargeContent(8);
gen.setVersion(HttpVersion.HTTP_1_1);
@ -259,11 +257,11 @@ public class HttpGeneratorClientTest
HttpGenerator.Result
result=gen.prepareContent(null,null,content0);
assertEquals(HttpGenerator.Result.NEED_COMMIT,result);
assertEquals(HttpGenerator.State.START,gen.getState());
result=gen.generate(null,null,null,content0,null);
assertEquals(HttpGenerator.Result.NEED_HEADER,result);
assertEquals(HttpGenerator.State.COMMITTING,gen.getState());
result=gen.commit(fields,header,null,content0,false);
result=gen.generate(header,null,null,content0,null);
assertEquals(HttpGenerator.Result.FLUSH_CONTENT,result);
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
assertTrue(gen.isChunking());
@ -273,16 +271,16 @@ public class HttpGeneratorClientTest
String body = BufferUtil.toString(content0);
BufferUtil.clear(content0);
result=gen.commit(fields,header,null,content0,false);
result=gen.generate(header,null,null,content0,null);
assertEquals(HttpGenerator.Result.OK,result);
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
result=gen.prepareContent(null,null,content1);
result=gen.generate(null,null,null,content1,null);
assertEquals(HttpGenerator.Result.NEED_CHUNK,result);
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
ByteBuffer chunk=BufferUtil.allocate(HttpGenerator.CHUNK_SIZE);
result=gen.prepareContent(chunk,null,content1);
result=gen.generate(null,chunk,null,content1,null);
assertEquals(HttpGenerator.Result.FLUSH_CONTENT,result);
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
assertEquals("\r\n2E\r\n",BufferUtil.toString(chunk));
@ -290,13 +288,13 @@ public class HttpGeneratorClientTest
body += BufferUtil.toString(chunk)+BufferUtil.toString(content1);
BufferUtil.clear(content1);
result=gen.complete(chunk,null);
result=gen.generate(null,chunk,null,null,Action.COMPLETE);
assertEquals(HttpGenerator.Result.FLUSH,result);
assertEquals(HttpGenerator.State.END,gen.getState());
assertEquals("\r\n0\r\n\r\n",BufferUtil.toString(chunk));
body += BufferUtil.toString(chunk);
result=gen.complete(chunk,null);
result=gen.generate(null,chunk,null,null,null);
assertEquals(HttpGenerator.Result.OK,result);
assertEquals(HttpGenerator.State.END,gen.getState());
@ -320,7 +318,7 @@ public class HttpGeneratorClientTest
ByteBuffer content0=BufferUtil.toBuffer("Hello World! ");
ByteBuffer content1=BufferUtil.toBuffer("The quick brown fox jumped over the lazy dog. ");
HttpFields fields = new HttpFields();
HttpGenerator gen = new HttpGenerator();
HttpGenerator gen = new HttpGenerator(fields);
gen.setVersion(HttpVersion.HTTP_1_1);
gen.setRequest("POST","/index.html");
@ -331,23 +329,23 @@ public class HttpGeneratorClientTest
HttpGenerator.Result
result=gen.prepareContent(null,null,content0);
result=gen.generate(null,null,null,content0,null);
assertEquals(HttpGenerator.Result.NEED_BUFFER,result);
assertEquals(HttpGenerator.State.START,gen.getState());
result=gen.prepareContent(null,buffer,content0);
result=gen.generate(null,null,buffer,content0,null);
assertEquals(HttpGenerator.Result.OK,result);
assertEquals(HttpGenerator.State.START,gen.getState());
assertEquals("Hello World! ",BufferUtil.toString(buffer));
assertEquals(0,content0.remaining());
result=gen.prepareContent(null,buffer,content1);
assertEquals(HttpGenerator.Result.NEED_COMMIT,result);
assertEquals(HttpGenerator.State.START,gen.getState());
result=gen.generate(null,null,buffer,content1,null);
assertEquals(HttpGenerator.Result.NEED_HEADER,result);
assertEquals(HttpGenerator.State.COMMITTING,gen.getState());
assertEquals("Hello World! The",BufferUtil.toString(buffer));
assertEquals(43,content1.remaining());
result=gen.commit(fields,header,buffer,content1,false);
result=gen.generate(header,null,buffer,content1,null);
assertEquals(HttpGenerator.Result.FLUSH,result);
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
assertEquals("Hello World! The",BufferUtil.toString(buffer));
@ -359,7 +357,7 @@ public class HttpGeneratorClientTest
String body = BufferUtil.toString(buffer);
BufferUtil.clear(buffer);
result=gen.prepareContent(null,buffer,content1);
result=gen.generate(null,null,buffer,content1,null);
assertEquals(HttpGenerator.Result.FLUSH,result);
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
assertEquals(" quick brown fox",BufferUtil.toString(buffer));
@ -367,7 +365,7 @@ public class HttpGeneratorClientTest
body += BufferUtil.toString(buffer);
BufferUtil.clear(buffer);
result=gen.prepareContent(null,buffer,content1);
result=gen.generate(null,null,buffer,content1,null);
assertEquals(HttpGenerator.Result.FLUSH,result);
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
assertEquals(" jumped over the",BufferUtil.toString(buffer));
@ -375,20 +373,20 @@ public class HttpGeneratorClientTest
body += BufferUtil.toString(buffer);
BufferUtil.clear(buffer);
result=gen.prepareContent(null,buffer,content1);
result=gen.generate(null,null,buffer,content1,null);
assertEquals(HttpGenerator.Result.OK,result);
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
assertEquals(" lazy dog. ",BufferUtil.toString(buffer));
assertEquals(0,content1.remaining());
result=gen.complete(null,buffer);
result=gen.generate(null,null,buffer,null,Action.COMPLETE);
assertEquals(HttpGenerator.Result.FLUSH,result);
assertEquals(HttpGenerator.State.COMPLETING,gen.getState());
assertEquals(" lazy dog. ",BufferUtil.toString(buffer));
body += BufferUtil.toString(buffer);
BufferUtil.clear(buffer);
result=gen.complete(null,buffer);
result=gen.generate(null,null,buffer,null,null);
assertEquals(HttpGenerator.Result.OK,result);
assertEquals(HttpGenerator.State.END,gen.getState());
assertEquals(0,buffer.remaining());
@ -411,7 +409,7 @@ public class HttpGeneratorClientTest
ByteBuffer content0=BufferUtil.toBuffer("Hello World! ");
ByteBuffer content1=BufferUtil.toBuffer("The quick brown fox jumped over the lazy dog. ");
HttpFields fields = new HttpFields();
HttpGenerator gen = new HttpGenerator();
HttpGenerator gen = new HttpGenerator(fields);
gen.setLargeContent(8);
gen.setVersion(HttpVersion.HTTP_1_1);
@ -423,11 +421,11 @@ public class HttpGeneratorClientTest
HttpGenerator.Result
result=gen.prepareContent(null,null,content0);
assertEquals(HttpGenerator.Result.NEED_COMMIT,result);
assertEquals(HttpGenerator.State.START,gen.getState());
result=gen.generate(null,null,null,content0,null);
assertEquals(HttpGenerator.Result.NEED_HEADER,result);
assertEquals(HttpGenerator.State.COMMITTING,gen.getState());
result=gen.commit(fields,header,null,content0,false);
result=gen.generate(header,null,null,content0,null);
assertEquals(HttpGenerator.Result.FLUSH_CONTENT,result);
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
assertTrue(!gen.isChunking());
@ -437,21 +435,17 @@ public class HttpGeneratorClientTest
String body = BufferUtil.toString(content0);
BufferUtil.clear(content0);
result=gen.commit(fields,header,null,null,false);
result=gen.generate(header,null,null,null,null);
assertEquals(HttpGenerator.Result.OK,result);
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
result=gen.prepareContent(null,null,content1);
result=gen.generate(null,null,null,content1,null);
assertEquals(HttpGenerator.Result.FLUSH_CONTENT,result);
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
body += BufferUtil.toString(content1);
BufferUtil.clear(content1);
result=gen.complete(null,null);
assertEquals(HttpGenerator.Result.OK,result);
assertEquals(HttpGenerator.State.END,gen.getState());
result=gen.complete(null,null);
result=gen.generate(null,null,null,null,Action.COMPLETE);
assertEquals(HttpGenerator.Result.OK,result);
assertEquals(HttpGenerator.State.END,gen.getState());

View File

@ -13,22 +13,29 @@
package org.eclipse.jetty.http;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.matchers.JUnitMatchers.containsString;
import static org.junit.matchers.JUnitMatchers.either;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import javax.swing.text.View;
import org.eclipse.jetty.http.HttpGenerator.Action;
import org.eclipse.jetty.io.ByteArrayEndPoint;
import org.eclipse.jetty.io.SimpleBuffers;
import org.eclipse.jetty.util.BufferUtil;
import org.hamcrest.CoreMatchers;
import org.junit.Test;
import org.junit.matchers.JUnitMatchers;
/**
*
@ -48,32 +55,31 @@ public class HttpGeneratorTest
{
ByteBuffer header=BufferUtil.allocate(8096);
HttpFields fields = new HttpFields();
HttpGenerator gen = new HttpGenerator();
HttpGenerator gen = new HttpGenerator(fields);
fields.add("Host","something");
fields.add("User-Agent","test");
gen.setRequest(HttpMethod.GET,"/index.html",HttpVersion.HTTP_1_1);
gen.setVersion(HttpVersion.HTTP_1_1);
gen.setResponse(200,null);
fields.add("Last-Modified",HttpFields.__01Jan1970);
HttpGenerator.Result
result=gen.complete(null,null);
assertEquals(HttpGenerator.State.COMPLETING_UNCOMMITTED,gen.getState());
assertEquals(HttpGenerator.Result.NEED_COMMIT,result);
result=gen.generate(null,null,null,null,Action.COMPLETE);
assertEquals(HttpGenerator.State.COMMITTING_COMPLETING,gen.getState());
assertEquals(HttpGenerator.Result.NEED_HEADER,result);
result=gen.commit(fields,header,null,null,true);
assertEquals(HttpGenerator.Result.NEED_COMPLETE,result);
result=gen.generate(header,null,null,null,null);
assertEquals(HttpGenerator.Result.FLUSH,result);
String head = BufferUtil.toString(header);
BufferUtil.clear(header);
result=gen.generate(null,null,null,null,null);
assertEquals(HttpGenerator.Result.OK,result);
assertEquals(HttpGenerator.State.END,gen.getState());
assertEquals(0,gen.getContentWritten());
assertThat(head,containsString("HTTP/1.1 200 OK"));
assertThat(head,containsString("Last-Modified: Thu, 01 Jan 1970 00?00?00 GMT"));
assertThat(head,not(containsString("Content-Length")));
assertThat(head,containsString("Content-Length: 0"));
result=gen.complete(null,null);
assertEquals(HttpGenerator.Result.OK,result);
assertEquals(HttpGenerator.State.END,gen.getState());
assertEquals(0,gen.getContentWritten());
}
@Test
@ -84,7 +90,7 @@ public class HttpGeneratorTest
ByteBuffer content=BufferUtil.toBuffer("Hello World");
ByteBuffer content1=BufferUtil.toBuffer(". The quick brown fox jumped over the lazy dog.");
HttpFields fields = new HttpFields();
HttpGenerator gen = new HttpGenerator();
HttpGenerator gen = new HttpGenerator(fields);
gen.setVersion(HttpVersion.HTTP_1_1);
gen.setResponse(200,null);
@ -92,35 +98,36 @@ public class HttpGeneratorTest
HttpGenerator.Result
result=gen.prepareContent(null,null,content);
result=gen.generate(null,null,null,content,null);
assertEquals(HttpGenerator.Result.NEED_BUFFER,result);
assertEquals(HttpGenerator.State.START,gen.getState());
result=gen.prepareContent(null,buffer,content);
result=gen.generate(null,null,buffer,content,null);
assertEquals(HttpGenerator.Result.OK,result);
assertEquals(HttpGenerator.State.START,gen.getState());
assertEquals("Hello World",BufferUtil.toString(buffer));
assertTrue(BufferUtil.isEmpty(content));
result=gen.prepareContent(null,buffer,content1);
result=gen.generate(null,null,buffer,content1,null);
assertEquals(HttpGenerator.Result.OK,result);
assertEquals(HttpGenerator.State.START,gen.getState());
assertEquals("Hello World. The quick brown fox jumped over the lazy dog.",BufferUtil.toString(buffer));
assertTrue(BufferUtil.isEmpty(content));
assertTrue(BufferUtil.isEmpty(content1));
result=gen.complete(null,buffer);
assertEquals(HttpGenerator.Result.NEED_COMMIT,result);
assertEquals(HttpGenerator.State.COMPLETING_UNCOMMITTED,gen.getState());
result=gen.generate(null,null,buffer,null,Action.COMPLETE);
assertEquals(HttpGenerator.Result.NEED_HEADER,result);
assertEquals(HttpGenerator.State.COMMITTING_COMPLETING,gen.getState());
result=gen.commit(fields,header,buffer,content,true);
result=gen.generate(header,null,buffer,null,null);
assertEquals(HttpGenerator.Result.FLUSH,result);
assertEquals(HttpGenerator.State.COMPLETING,gen.getState());
String head = BufferUtil.toString(header);
BufferUtil.clear(header);
String body = BufferUtil.toString(buffer);
BufferUtil.clear(buffer);
result=gen.complete(null,buffer);
result=gen.generate(null,null,buffer,null,null);
assertEquals(HttpGenerator.Result.OK,result);
assertEquals(HttpGenerator.State.END,gen.getState());
@ -142,7 +149,7 @@ public class HttpGeneratorTest
ByteBuffer content0=BufferUtil.toBuffer("Hello World! ");
ByteBuffer content1=BufferUtil.toBuffer("The quick brown fox jumped over the lazy dog. ");
HttpFields fields = new HttpFields();
HttpGenerator gen = new HttpGenerator();
HttpGenerator gen = new HttpGenerator(fields);
gen.setVersion(HttpVersion.HTTP_1_1);
gen.setResponse(200,null);
@ -150,23 +157,23 @@ public class HttpGeneratorTest
HttpGenerator.Result
result=gen.prepareContent(null,null,content0);
result=gen.generate(null,null,null,content0,null);
assertEquals(HttpGenerator.Result.NEED_BUFFER,result);
assertEquals(HttpGenerator.State.START,gen.getState());
result=gen.prepareContent(null,buffer,content0);
result=gen.generate(null,null,buffer,content0,null);
assertEquals(HttpGenerator.Result.OK,result);
assertEquals(HttpGenerator.State.START,gen.getState());
assertEquals("Hello World! ",BufferUtil.toString(buffer));
assertEquals(0,content0.remaining());
result=gen.prepareContent(null,buffer,content1);
assertEquals(HttpGenerator.Result.NEED_COMMIT,result);
assertEquals(HttpGenerator.State.START,gen.getState());
result=gen.generate(null,null,buffer,content1,null);
assertEquals(HttpGenerator.Result.NEED_HEADER,result);
assertEquals(HttpGenerator.State.COMMITTING,gen.getState());
assertEquals("Hello World! The",BufferUtil.toString(buffer));
assertEquals(43,content1.remaining());
result=gen.commit(fields,header,buffer,content1,false);
result=gen.generate(header,null,buffer,content1,null);
assertEquals(HttpGenerator.Result.FLUSH,result);
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
assertEquals("Hello World! The",BufferUtil.toString(buffer));
@ -178,12 +185,12 @@ public class HttpGeneratorTest
String body = BufferUtil.toString(buffer);
BufferUtil.clear(buffer);
result=gen.prepareContent(null,buffer,content1);
result=gen.generate(null,null,buffer,content1,null);
assertEquals(HttpGenerator.Result.NEED_CHUNK,result);
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
ByteBuffer chunk=BufferUtil.allocate(HttpGenerator.CHUNK_SIZE);
result=gen.prepareContent(chunk,buffer,content1);
result=gen.generate(null,chunk,buffer,content1,null);
assertEquals(HttpGenerator.Result.FLUSH,result);
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
assertEquals("\r\n10\r\n",BufferUtil.toString(chunk));
@ -193,7 +200,7 @@ public class HttpGeneratorTest
BufferUtil.clear(chunk);
BufferUtil.clear(buffer);
result=gen.prepareContent(chunk,buffer,content1);
result=gen.generate(null,chunk,buffer,content1,null);
assertEquals(HttpGenerator.Result.FLUSH,result);
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
assertEquals("\r\n10\r\n",BufferUtil.toString(chunk));
@ -203,14 +210,14 @@ public class HttpGeneratorTest
BufferUtil.clear(chunk);
BufferUtil.clear(buffer);
result=gen.prepareContent(chunk,buffer,content1);
result=gen.generate(null,chunk,buffer,content1,null);
assertEquals(HttpGenerator.Result.OK,result);
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
assertEquals("",BufferUtil.toString(chunk));
assertEquals(" lazy dog. ",BufferUtil.toString(buffer));
assertEquals(0,content1.remaining());
result=gen.complete(chunk,buffer);
result=gen.generate(null,chunk,buffer,null,Action.COMPLETE);
assertEquals(HttpGenerator.Result.FLUSH,result);
assertEquals(HttpGenerator.State.COMPLETING,gen.getState());
assertEquals("\r\nB\r\n",BufferUtil.toString(chunk));
@ -219,16 +226,15 @@ public class HttpGeneratorTest
BufferUtil.clear(chunk);
BufferUtil.clear(buffer);
result=gen.complete(chunk,buffer);
result=gen.generate(null,chunk,buffer,null,null);
assertEquals(HttpGenerator.Result.FLUSH,result);
assertEquals(HttpGenerator.State.END,gen.getState());
assertEquals("\r\n0\r\n\r\n",BufferUtil.toString(chunk));
assertEquals(0,buffer.remaining());
body += BufferUtil.toString(chunk);
BufferUtil.clear(chunk);
BufferUtil.clear(buffer);
result=gen.complete(chunk,buffer);
result=gen.generate(null,chunk,buffer,null,null);
assertEquals(HttpGenerator.Result.OK,result);
assertEquals(HttpGenerator.State.END,gen.getState());
@ -250,7 +256,7 @@ public class HttpGeneratorTest
ByteBuffer content0=BufferUtil.toBuffer("Hello Cruel World! ");
ByteBuffer content1=BufferUtil.toBuffer("The quick brown fox jumped over the lazy dog. ");
HttpFields fields = new HttpFields();
HttpGenerator gen = new HttpGenerator();
HttpGenerator gen = new HttpGenerator(fields);
gen.setLargeContent(8);
gen.setVersion(HttpVersion.HTTP_1_1);
@ -259,11 +265,11 @@ public class HttpGeneratorTest
HttpGenerator.Result
result=gen.prepareContent(null,null,content0);
assertEquals(HttpGenerator.Result.NEED_COMMIT,result);
assertEquals(HttpGenerator.State.START,gen.getState());
result=gen.generate(null,null,null,content0,null);
assertEquals(HttpGenerator.Result.NEED_HEADER,result);
assertEquals(HttpGenerator.State.COMMITTING,gen.getState());
result=gen.commit(fields,header,null,content0,false);
result=gen.generate(header,null,null,content0,null);
assertEquals(HttpGenerator.Result.FLUSH_CONTENT,result);
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
assertTrue(gen.isChunking());
@ -273,16 +279,16 @@ public class HttpGeneratorTest
String body = BufferUtil.toString(content0);
BufferUtil.clear(content0);
result=gen.commit(fields,header,null,content0,false);
result=gen.generate(header,null,null,content0,null);
assertEquals(HttpGenerator.Result.OK,result);
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
result=gen.prepareContent(null,null,content1);
result=gen.generate(null,null,null,content1,null);
assertEquals(HttpGenerator.Result.NEED_CHUNK,result);
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
ByteBuffer chunk=BufferUtil.allocate(HttpGenerator.CHUNK_SIZE);
result=gen.prepareContent(chunk,null,content1);
result=gen.generate(null,chunk,null,content1,null);
assertEquals(HttpGenerator.Result.FLUSH_CONTENT,result);
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
assertEquals("\r\n2E\r\n",BufferUtil.toString(chunk));
@ -290,13 +296,13 @@ public class HttpGeneratorTest
body += BufferUtil.toString(chunk)+BufferUtil.toString(content1);
BufferUtil.clear(content1);
result=gen.complete(chunk,null);
result=gen.generate(null,chunk,null,null,Action.COMPLETE);
assertEquals(HttpGenerator.Result.FLUSH,result);
assertEquals(HttpGenerator.State.END,gen.getState());
assertEquals("\r\n0\r\n\r\n",BufferUtil.toString(chunk));
body += BufferUtil.toString(chunk);
result=gen.complete(chunk,null);
result=gen.generate(null,chunk,null,null,null);
assertEquals(HttpGenerator.Result.OK,result);
assertEquals(HttpGenerator.State.END,gen.getState());
@ -320,7 +326,7 @@ public class HttpGeneratorTest
ByteBuffer content0=BufferUtil.toBuffer("Hello World! ");
ByteBuffer content1=BufferUtil.toBuffer("The quick brown fox jumped over the lazy dog. ");
HttpFields fields = new HttpFields();
HttpGenerator gen = new HttpGenerator();
HttpGenerator gen = new HttpGenerator(fields);
gen.setVersion(HttpVersion.HTTP_1_1);
gen.setResponse(200,null);
@ -330,23 +336,23 @@ public class HttpGeneratorTest
HttpGenerator.Result
result=gen.prepareContent(null,null,content0);
result=gen.generate(null,null,null,content0,null);
assertEquals(HttpGenerator.Result.NEED_BUFFER,result);
assertEquals(HttpGenerator.State.START,gen.getState());
result=gen.prepareContent(null,buffer,content0);
result=gen.generate(null,null,buffer,content0,null);
assertEquals(HttpGenerator.Result.OK,result);
assertEquals(HttpGenerator.State.START,gen.getState());
assertEquals("Hello World! ",BufferUtil.toString(buffer));
assertEquals(0,content0.remaining());
result=gen.prepareContent(null,buffer,content1);
assertEquals(HttpGenerator.Result.NEED_COMMIT,result);
assertEquals(HttpGenerator.State.START,gen.getState());
result=gen.generate(null,null,buffer,content1,null);
assertEquals(HttpGenerator.Result.NEED_HEADER,result);
assertEquals(HttpGenerator.State.COMMITTING,gen.getState());
assertEquals("Hello World! The",BufferUtil.toString(buffer));
assertEquals(43,content1.remaining());
result=gen.commit(fields,header,buffer,content1,false);
result=gen.generate(header,null,buffer,content1,null);
assertEquals(HttpGenerator.Result.FLUSH,result);
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
assertEquals("Hello World! The",BufferUtil.toString(buffer));
@ -358,7 +364,7 @@ public class HttpGeneratorTest
String body = BufferUtil.toString(buffer);
BufferUtil.clear(buffer);
result=gen.prepareContent(null,buffer,content1);
result=gen.generate(null,null,buffer,content1,null);
assertEquals(HttpGenerator.Result.FLUSH,result);
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
assertEquals(" quick brown fox",BufferUtil.toString(buffer));
@ -366,7 +372,7 @@ public class HttpGeneratorTest
body += BufferUtil.toString(buffer);
BufferUtil.clear(buffer);
result=gen.prepareContent(null,buffer,content1);
result=gen.generate(null,null,buffer,content1,null);
assertEquals(HttpGenerator.Result.FLUSH,result);
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
assertEquals(" jumped over the",BufferUtil.toString(buffer));
@ -374,20 +380,20 @@ public class HttpGeneratorTest
body += BufferUtil.toString(buffer);
BufferUtil.clear(buffer);
result=gen.prepareContent(null,buffer,content1);
result=gen.generate(null,null,buffer,content1,null);
assertEquals(HttpGenerator.Result.OK,result);
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
assertEquals(" lazy dog. ",BufferUtil.toString(buffer));
assertEquals(0,content1.remaining());
result=gen.complete(null,buffer);
result=gen.generate(null,null,buffer,null,Action.COMPLETE);
assertEquals(HttpGenerator.Result.FLUSH,result);
assertEquals(HttpGenerator.State.COMPLETING,gen.getState());
assertEquals(" lazy dog. ",BufferUtil.toString(buffer));
body += BufferUtil.toString(buffer);
BufferUtil.clear(buffer);
result=gen.complete(null,buffer);
result=gen.generate(null,null,buffer,null,null);
assertEquals(HttpGenerator.Result.OK,result);
assertEquals(HttpGenerator.State.END,gen.getState());
assertEquals(0,buffer.remaining());
@ -410,7 +416,7 @@ public class HttpGeneratorTest
ByteBuffer content0=BufferUtil.toBuffer("Hello World! ");
ByteBuffer content1=BufferUtil.toBuffer("The quick brown fox jumped over the lazy dog. ");
HttpFields fields = new HttpFields();
HttpGenerator gen = new HttpGenerator();
HttpGenerator gen = new HttpGenerator(fields);
gen.setLargeContent(8);
gen.setVersion(HttpVersion.HTTP_1_1);
@ -421,11 +427,11 @@ public class HttpGeneratorTest
HttpGenerator.Result
result=gen.prepareContent(null,null,content0);
assertEquals(HttpGenerator.Result.NEED_COMMIT,result);
assertEquals(HttpGenerator.State.START,gen.getState());
result=gen.generate(null,null,null,content0,null);
assertEquals(HttpGenerator.Result.NEED_HEADER,result);
assertEquals(HttpGenerator.State.COMMITTING,gen.getState());
result=gen.commit(fields,header,null,content0,false);
result=gen.generate(header,null,null,content0,null);
assertEquals(HttpGenerator.Result.FLUSH_CONTENT,result);
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
assertTrue(!gen.isChunking());
@ -435,24 +441,20 @@ public class HttpGeneratorTest
String body = BufferUtil.toString(content0);
BufferUtil.clear(content0);
result=gen.commit(fields,header,null,null,false);
result=gen.generate(header,null,null,null,null);
assertEquals(HttpGenerator.Result.OK,result);
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
result=gen.prepareContent(null,null,content1);
result=gen.generate(null,null,null,content1,null);
assertEquals(HttpGenerator.Result.FLUSH_CONTENT,result);
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
body += BufferUtil.toString(content1);
BufferUtil.clear(content1);
result=gen.complete(null,null);
result=gen.generate(null,null,null,null,Action.COMPLETE);
assertEquals(HttpGenerator.Result.OK,result);
assertEquals(HttpGenerator.State.END,gen.getState());
result=gen.complete(null,null);
assertEquals(HttpGenerator.Result.OK,result);
assertEquals(HttpGenerator.State.END,gen.getState());
assertEquals(59,gen.getContentWritten());
// System.err.println(head+body);
@ -471,9 +473,9 @@ public class HttpGeneratorTest
public void testHTTP() throws Exception
{
HttpFields fields = new HttpFields();
HttpGenerator gen = new HttpGenerator();
// Handler handler = new Handler();
// HttpParser parser=null;
HttpGenerator gen = new HttpGenerator(fields);
Handler handler = new Handler();
HttpParser parser=null;
// For HTTP version
@ -488,7 +490,7 @@ public class HttpGeneratorTest
// For none, keep-alive, close
for (int c=0;c<(v==11?connect.length:(connect.length-1));c++)
{
String t="v="+v+",r="+r+",chunks="+chunks+",connect="+c+",tr="+tr[r];
String t="v="+v+",chunks="+chunks+",connect="+connect[c]+",tr="+r+"="+tr[r];
// System.err.println(t);
gen.reset();
@ -496,7 +498,7 @@ public class HttpGeneratorTest
String response=tr[r].build(v,gen,"OK\r\nTest",connect[c],null,chunks, fields);
System.out.println("RESPONSE: "+t+"\n"+response+(gen.isPersistent()?"...\n":"---\n"));
// System.err.println("===\n"+t+"\n"+response+(gen.isPersistent()?"...\n":"---\n"));
if (v==9)
{
@ -506,13 +508,12 @@ public class HttpGeneratorTest
continue;
}
/*
parser=new HttpParser(new ByteArrayBuffer(response.getBytes()), handler);
parser=new HttpParser(handler);
parser.setHeadResponse(tr[r]._head);
try
{
parser.parse();
parser.parseNext(BufferUtil.toBuffer(response));
}
catch(IOException e)
{
@ -522,21 +523,21 @@ public class HttpGeneratorTest
}
if (tr[r]._body!=null)
assertEquals(t,tr[r]._body, this.content);
assertEquals(t,tr[r]._body, this._content);
if (v==10)
assertTrue(t,hb.isPersistent() || tr[r]._contentLength==null || c==2 || c==0);
assertTrue(t,gen.isPersistent() || tr[r]._contentLength>=0|| c==2 || c==0);
else
assertTrue(t,hb.isPersistent() || c==2 || c==3);
assertTrue(t,gen.isPersistent() || c==2 || c==3);
if (v>9)
assertEquals("OK Test",f2);
assertEquals("OK??Test",_reason);
if (content==null)
if (_content==null)
assertTrue(t,tr[r]._body==null);
else
assertTrue(t,tr[r]._contentLength==null || content.length()==Integer.parseInt(tr[r]._contentLength));
*/
assertThat(t,tr[r]._contentLength,either(equalTo(_content.length())).or(equalTo(-1)));
}
}
}
@ -550,12 +551,12 @@ public class HttpGeneratorTest
private String _body;
private boolean _head;
String _contentType;
String _contentLength;
int _contentLength;
String _connection;
String _te;
String _other;
private TR(int code,String contentType, String contentLength ,String content,boolean head)
private TR(int code,String contentType, int contentLength ,String content,boolean head)
{
_code=code;
_contentType=contentType;
@ -576,10 +577,10 @@ public class HttpGeneratorTest
if (_contentType!=null)
fields.put("Content-Type",_contentType);
if (_contentLength!=null)
if (_contentLength>=0)
{
fields.put("Content-Length",_contentLength);
gen.setContentLength(Long.parseLong(_contentLength));
fields.put("Content-Length",""+_contentLength);
gen.setContentLength(_contentLength);
}
if (_connection!=null)
fields.put("Connection",_connection);
@ -591,11 +592,12 @@ public class HttpGeneratorTest
ByteBuffer content=_body==null?null:BufferUtil.toBuffer(_body);
if (content!=null)
content.limit(0);
ByteBuffer header=null;
ByteBuffer chunk=null;
ByteBuffer buffer=null;
mainLoop: while(true)
while(!gen.isComplete())
{
// if we have unwritten content
if (content!=null && content.position()<content.capacity())
@ -603,171 +605,88 @@ public class HttpGeneratorTest
// if we need a new chunk
if (content.remaining()==0)
{
content.limit(content.capacity());
if (chunks-->1)
content.limit(content.position()+content.remaining()/2);
else
content.limit(content.capacity());
}
switch(gen.getState())
{
case START:
case COMPLETING_UNCOMMITTED:
case COMMITTED:
case COMPLETING:
case END:
// System.err.printf("content %d %s%n",chunks,BufferUtil.toDetailString(content));
}
}
// Generate
Action action=BufferUtil.hasContent(content)?null:Action.COMPLETE;
/* System.err.printf("generate(%s,%s,%s,%s,%s)@%s%n",
BufferUtil.toSummaryString(header),
BufferUtil.toSummaryString(chunk),
BufferUtil.toSummaryString(buffer),
BufferUtil.toSummaryString(content),
action,gen.getState());*/
HttpGenerator.Result result=gen.generate(header,chunk,buffer,content,action);
/*System.err.printf("%s (%s,%s,%s,%s,%s)@%s%n",
result,
BufferUtil.toSummaryString(header),
BufferUtil.toSummaryString(chunk),
BufferUtil.toSummaryString(buffer),
BufferUtil.toSummaryString(content),
action,gen.getState());*/
switch(gen.prepareContent(chunk,buffer,content))
{
case FLUSH:
if (BufferUtil.hasContent(chunk))
{
response+=BufferUtil.toString(chunk);
chunk.position(chunk.limit());
}
if (BufferUtil.hasContent(buffer))
{
response+=BufferUtil.toString(buffer);
buffer.position(buffer.limit());
}
break;
case FLUSH_CONTENT:
if (BufferUtil.hasContent(chunk))
{
response+=BufferUtil.toString(chunk);
chunk.position(chunk.limit());
}
if (BufferUtil.hasContent(content))
{
response+=BufferUtil.toString(content);
content.position(content.limit());
}
break;
case NEED_BUFFER:
buffer=BufferUtil.allocate(8192);
break;
case NEED_CHUNK:
chunk=BufferUtil.allocate(HttpGenerator.CHUNK_SIZE);
break;
case NEED_COMMIT:
{
commitLoop: while (true)
{
ByteBuffer header=BufferUtil.allocate(4096);
switch(gen.commit(fields,header,buffer,content,chunks==0))
{
case FLUSH:
if (BufferUtil.hasContent(header))
{
response+=BufferUtil.toString(header);
header.position(header.limit());
}
if (BufferUtil.hasContent(buffer))
{
response+=BufferUtil.toString(buffer);
buffer.position(buffer.limit());
}
break;
case FLUSH_CONTENT:
if (BufferUtil.hasContent(header))
{
response+=BufferUtil.toString(header);
header.position(header.limit());
}
if (BufferUtil.hasContent(content))
{
response+=BufferUtil.toString(content);
content.position(content.limit());
}
break;
case NEED_BUFFER:
buffer=BufferUtil.allocate(8192);
break;
case OK:
break commitLoop;
default:
throw new IllegalStateException(gen.toString());
}
}
}
break;
case NEED_COMPLETE:
{
completeLoop: while (true)
{
ByteBuffer header=BufferUtil.allocate(4096);
switch(gen.complete(chunk,buffer))
{
case FLUSH:
if (BufferUtil.hasContent(chunk))
{
response+=BufferUtil.toString(chunk);
chunk.position(chunk.limit());
}
if (BufferUtil.hasContent(buffer))
{
response+=BufferUtil.toString(buffer);
buffer.position(buffer.limit());
}
break;
case OK:
break completeLoop;
default:
throw new IllegalStateException(gen.toString());
}
}
}
break;
}
continue;
}
while (true)
switch(result)
{
switch(gen.complete(chunk,buffer))
{
case FLUSH:
if (BufferUtil.hasContent(chunk))
{
response+=BufferUtil.toString(chunk);
chunk.position(chunk.limit());
}
if (BufferUtil.hasContent(buffer))
{
response+=BufferUtil.toString(buffer);
buffer.position(buffer.limit());
}
break;
case NEED_HEADER:
header=BufferUtil.allocate(2048);
break;
case NEED_BUFFER:
buffer=BufferUtil.allocate(8192);
break;
case OK:
break mainLoop;
default:
throw new IllegalStateException(gen.toString());
}
case NEED_CHUNK:
header=null;
chunk=BufferUtil.allocate(HttpGenerator.CHUNK_SIZE);
break;
case FLUSH:
if (BufferUtil.hasContent(header))
{
response+=BufferUtil.toString(header);
header.position(header.limit());
}
else if (BufferUtil.hasContent(chunk))
{
response+=BufferUtil.toString(chunk);
chunk.position(chunk.limit());
}
if (BufferUtil.hasContent(buffer))
{
response+=BufferUtil.toString(buffer);
buffer.position(buffer.limit());
}
break;
case FLUSH_CONTENT:
if (BufferUtil.hasContent(header))
{
response+=BufferUtil.toString(header);
header.position(header.limit());
}
else if (BufferUtil.hasContent(chunk))
{
response+=BufferUtil.toString(chunk);
chunk.position(chunk.limit());
}
if (BufferUtil.hasContent(content))
{
response+=BufferUtil.toString(content);
content.position(content.limit());
}
break;
case OK:
case SHUTDOWN_OUT:
// TODO
}
}
return response;
}
@ -780,87 +699,72 @@ public class HttpGeneratorTest
private final TR[] tr =
{
/* 0 */ new TR(200,null,null,null,false),
/* 1 */ new TR(200,null,null,CONTENT,false),
/* 2 */ new TR(200,null,""+CONTENT.length(),null,true),
/* 3 */ new TR(200,null,""+CONTENT.length(),CONTENT,false),
/* 4 */ new TR(200,"text/html",null,null,true),
/* 5 */ new TR(200,"text/html",null,CONTENT,false),
/* 6 */ new TR(200,"text/html",""+CONTENT.length(),null,true),
/* 7 */ new TR(200,"text/html",""+CONTENT.length(),CONTENT,false),
/* 0 */ new TR(200,null,-1,null,false),
/* 1 */ new TR(200,null,-1,CONTENT,false),
/* 2 */ new TR(200,null,CONTENT.length(),null,true),
/* 3 */ new TR(200,null,CONTENT.length(),CONTENT,false),
/* 4 */ new TR(200,"text/html",-1,null,true),
/* 5 */ new TR(200,"text/html",-1,CONTENT,false),
/* 6 */ new TR(200,"text/html",CONTENT.length(),null,true),
/* 7 */ new TR(200,"text/html",CONTENT.length(),CONTENT,false),
};
private String content;
private String f0;
private String f1;
private String f2;
private String[] hdr;
private String[] val;
private int h;
private String _content;
private String _version;
private int _status;
private String _reason;
private List<String> _hdr=new ArrayList<>();
private List<String> _val=new ArrayList<>();
private class Handler extends HttpParser.EventHandler
private class Handler implements HttpParser.ResponseHandler
{
private int index=0;
@Override
public boolean startResponse(String version, int status, String reason) throws IOException
{
_version=version;
_status=status;
_reason=reason;
return false;
}
@Override
public void content(ByteBuffer ref)
public boolean parsedHeader(String name, String value) throws IOException
{
if (index == 0)
content= "";
content= content.substring(0, index) + ref;
index+=ref.length();
_hdr.add(name);
_val.add(value);
return false;
}
@Override
public void startRequest(ByteBuffer tok0, ByteBuffer tok1, ByteBuffer tok2)
public boolean headerComplete() throws IOException
{
h= -1;
hdr= new String[9];
val= new String[9];
f0= tok0.toString();
f1= tok1.toString();
if (tok2!=null)
f2= tok2.toString();
else
f2=null;
index=0;
// System.out.println(f0+" "+f1+" "+f2);
_content= null;
return false;
}
@Override
public boolean content(ByteBuffer ref) throws IOException
{
if (_content==null)
_content="";
_content+=BufferUtil.toString(ref);
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jetty.EventHandler#startResponse(org.eclipse.io.Buffer, int, org.eclipse.io.Buffer)
*/
@Override
public void startResponse(ByteBuffer version, int status, ByteBuffer reason)
public boolean messageComplete(long contentLength) throws IOException
{
h= -1;
hdr= new String[9];
val= new String[9];
f0= version.toString();
f1= ""+status;
if (reason!=null)
f2= reason.toString();
else
f2=null;
index=0;
return true;
}
@Override
public void parsedHeader(ByteBuffer name,ByteBuffer value)
public boolean earlyEOF()
{
hdr[++h]= name.toString();
val[h]= value.toString();
return true;
}
@Override
public void headerComplete()
{
content= null;
}
@Override
public void messageComplete(long contentLength)
{
}
}
}

View File

@ -79,10 +79,19 @@ public class BufferUtil
}
/* ------------------------------------------------------------ */
public static void flipToFill(ByteBuffer buffer)
public static int flipToFill(ByteBuffer buffer)
{
buffer.position(buffer.hasRemaining()?buffer.limit():0);
int position=buffer.position();
int limit=buffer.limit();
if (position==limit)
{
buffer.position(0);
buffer.limit(buffer.capacity());
return 0;
}
buffer.position(limit);
buffer.limit(buffer.capacity());
return position;
}
@ -155,11 +164,9 @@ public class BufferUtil
public static int put(ByteBuffer from, ByteBuffer to, int maxBytes)
{
int put;
int pos=to.position();
int pos=flipToFill(to);
try
{
flipToFill(to);
maxBytes=Math.min(maxBytes,to.remaining());
int remaining=from.remaining();
if (remaining>0)
@ -205,11 +212,9 @@ public class BufferUtil
public static int put(ByteBuffer from, ByteBuffer to)
{
int put;
int pos=to.position();
int pos= flipToFill(to);
try
{
flipToFill(to);
int remaining=from.remaining();
if (remaining>0)
{
@ -561,9 +566,11 @@ public class BufferUtil
{
return ByteBuffer.wrap(s.getBytes(charset));
}
public static String toDetailString(ByteBuffer buffer)
public static String toSummaryString(ByteBuffer buffer)
{
if (buffer==null)
return "null";
StringBuilder buf = new StringBuilder();
buf.append("[p=");
buf.append(buffer.position());
@ -571,6 +578,26 @@ public class BufferUtil
buf.append(buffer.limit());
buf.append(",c=");
buf.append(buffer.capacity());
buf.append(",r=");
buf.append(buffer.remaining());
buf.append("]");
return buf.toString();
}
public static String toDetailString(ByteBuffer buffer)
{
if (buffer==null)
return "null";
StringBuilder buf = new StringBuilder();
buf.append("[p=");
buf.append(buffer.position());
buf.append(",l=");
buf.append(buffer.limit());
buf.append(",c=");
buf.append(buffer.capacity());
buf.append(",r=");
buf.append(buffer.remaining());
buf.append("]={");
for (int i=0;i<buffer.position();i++)