jetty-9 work in progress
This commit is contained in:
parent
a4bee5b12d
commit
3d12ef7075
|
@ -1073,13 +1073,12 @@ public class HttpFields implements Iterable<HttpFields.Field>
|
|||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void putTo(ByteBuffer buffer) throws IOException
|
||||
public void putTo(ByteBuffer buffer)
|
||||
{
|
||||
HttpHeader header = HttpHeader.CACHE.get(_name);
|
||||
if (header!=null)
|
||||
{
|
||||
buffer.put(header.toBuffer());
|
||||
buffer.put(__colon_space);
|
||||
buffer.put(header.toBytesColonSpace());
|
||||
|
||||
if (HttpHeaderValue.hasKnownValues(header))
|
||||
{
|
||||
|
@ -1089,6 +1088,8 @@ public class HttpFields implements Iterable<HttpFields.Field>
|
|||
else
|
||||
buffer.put(toSanitisedBytes(_value));
|
||||
}
|
||||
else
|
||||
buffer.put(toSanitisedBytes(_value));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1101,7 +1102,7 @@ public class HttpFields implements Iterable<HttpFields.Field>
|
|||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void putValueTo(ByteBuffer buffer) throws IOException
|
||||
public void putValueTo(ByteBuffer buffer)
|
||||
{
|
||||
buffer.put(toSanitisedBytes(_value));
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ public class HttpGenerator
|
|||
|
||||
// states
|
||||
|
||||
enum State { START, CHUNKING, STREAMING, COMPLETING, END };
|
||||
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};
|
||||
|
||||
public static final byte[] NO_BYTES = {};
|
||||
|
@ -112,8 +112,7 @@ public class HttpGenerator
|
|||
|
||||
|
||||
// common _content
|
||||
private static final byte[] LAST_CHUNK =
|
||||
{ (byte) '0', (byte) '\015', (byte) '\012', (byte) '\015', (byte) '\012'};
|
||||
private static final byte[] LAST_CHUNK = { (byte) '0', (byte) '\015', (byte) '\012', (byte) '\015', (byte) '\012'};
|
||||
private static final byte[] CONTENT_LENGTH_0 = StringUtil.getBytes("Content-Length: 0\015\012");
|
||||
private static final byte[] CONNECTION_KEEP_ALIVE = StringUtil.getBytes("Connection: keep-alive\015\012");
|
||||
private static final byte[] CONNECTION_CLOSE = StringUtil.getBytes("Connection: close\015\012");
|
||||
|
@ -124,7 +123,7 @@ public class HttpGenerator
|
|||
private static byte[] SERVER = StringUtil.getBytes("Server: Jetty(7.0.x)\015\012");
|
||||
|
||||
// other statics
|
||||
private static final int CHUNK_SPACE = 12;
|
||||
public static final int CHUNK_SIZE = 12;
|
||||
|
||||
public static void setServerVersion(String version)
|
||||
{
|
||||
|
@ -133,9 +132,6 @@ public class HttpGenerator
|
|||
|
||||
// data
|
||||
private boolean _needCRLF = false;
|
||||
private boolean _sentEOC = false;
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
public void reset()
|
||||
|
@ -154,7 +150,6 @@ public class HttpGenerator
|
|||
_method=null;
|
||||
|
||||
_needCRLF = false;
|
||||
_sentEOC = false;
|
||||
_uri=null;
|
||||
_noContent=false;
|
||||
}
|
||||
|
@ -201,6 +196,12 @@ public class HttpGenerator
|
|||
return _state != State.START;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public boolean isChunking()
|
||||
{
|
||||
return _contentLength==HttpTokens.CHUNKED_CONTENT;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public int getLargeContent()
|
||||
{
|
||||
|
@ -366,58 +367,34 @@ public class HttpGenerator
|
|||
return _method==null;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public boolean needsHeader()
|
||||
public Result commit(HttpFields fields,ByteBuffer header,ByteBuffer buffer, ByteBuffer content, boolean last) throws IOException
|
||||
{
|
||||
return _state==State.START || _contentLength==HttpTokens.CHUNKED_CONTENT;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public Result commit(HttpFields fields,ByteBuffer header,ByteBuffer buffer, ByteBuffer content, boolean last)
|
||||
throws IOException
|
||||
{
|
||||
|
||||
if (header==null)
|
||||
throw new IllegalArgumentException("!header");
|
||||
|
||||
if (isResponse() && _status==0)
|
||||
throw new EofException(); // TODO ???
|
||||
|
||||
|
||||
if (_state == State.START)
|
||||
{
|
||||
if (isRequest() && _version==HttpVersion.HTTP_0_9)
|
||||
_noContent=true;
|
||||
|
||||
boolean has_server = false;
|
||||
int pos=header.position();
|
||||
try
|
||||
{
|
||||
BufferUtil.flipToFill(header);
|
||||
|
||||
switch(_state)
|
||||
{
|
||||
case START:
|
||||
case COMPLETING_UNCOMMITTED:
|
||||
|
||||
if (isRequest())
|
||||
{
|
||||
_persistent=true;
|
||||
|
||||
if (_version == HttpVersion.HTTP_0_9)
|
||||
if(_version==HttpVersion.HTTP_0_9)
|
||||
{
|
||||
_contentLength = HttpTokens.NO_CONTENT;
|
||||
header.put(_method);
|
||||
header.put((byte)' ');
|
||||
header.put(_uri);
|
||||
header.put(HttpTokens.CRLF);
|
||||
_state = State.END;
|
||||
_noContent=true;
|
||||
return Result.FLUSH;
|
||||
generateRequestLine(header);
|
||||
_state = State.END;
|
||||
return Result.OK;
|
||||
}
|
||||
|
||||
header.put(_method);
|
||||
header.put((byte)' ');
|
||||
header.put(_uri);
|
||||
header.put((byte)' ');
|
||||
header.put((_version==HttpVersion.HTTP_1_0?HttpVersion.HTTP_1_0:HttpVersion.HTTP_1_1).toBytes());
|
||||
header.put(HttpTokens.CRLF);
|
||||
_persistent=true;
|
||||
generateRequestLine(header);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -426,7 +403,7 @@ public class HttpGenerator
|
|||
{
|
||||
_persistent = false;
|
||||
_contentLength = HttpTokens.EOF_CONTENT;
|
||||
_state = State.STREAMING;
|
||||
_state = State.COMMITTED;
|
||||
return prepareContent(null,buffer,content);
|
||||
}
|
||||
|
||||
|
@ -434,6 +411,107 @@ public class HttpGenerator
|
|||
if (_persistent==null)
|
||||
_persistent=(_version.ordinal() > HttpVersion.HTTP_1_0.ordinal());
|
||||
|
||||
generateResponseLine(header);
|
||||
|
||||
// Handle 1xx
|
||||
if (_status>=100 && _status<200 )
|
||||
{
|
||||
_noContent=true;
|
||||
|
||||
if (_status!=101 )
|
||||
{
|
||||
header.put(HttpTokens.CRLF);
|
||||
_state = State.START;
|
||||
return Result.OK;
|
||||
}
|
||||
}
|
||||
else if (_status==204 || _status==304)
|
||||
{
|
||||
_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:
|
||||
|
||||
// Handle any content
|
||||
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));
|
||||
}
|
||||
|
||||
// Can we do a direct flush
|
||||
if (BufferUtil.isEmpty(buffer) && content.remaining()>_largeContent)
|
||||
{
|
||||
_contentPrepared+=content.remaining();
|
||||
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;
|
||||
}
|
||||
_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);
|
||||
}
|
||||
finally
|
||||
{
|
||||
BufferUtil.flipToFlush(header,pos);
|
||||
}
|
||||
|
||||
return _state==State.COMPLETING?Result.NEED_COMPLETE:Result.OK;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
private void generateRequestLine(ByteBuffer header)
|
||||
{
|
||||
header.put(_method);
|
||||
header.put((byte)' ');
|
||||
header.put(_uri);
|
||||
switch(_version)
|
||||
{
|
||||
case HTTP_1_0:
|
||||
case HTTP_1_1:
|
||||
header.put((byte)' ');
|
||||
header.put(_version.toBytes());
|
||||
}
|
||||
header.put(HttpTokens.CRLF);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
private void generateResponseLine(ByteBuffer header)
|
||||
{
|
||||
// Look for prepared response line
|
||||
Status status = _status<__status.length?__status[_status]:null;
|
||||
if (status!=null)
|
||||
|
@ -464,24 +542,11 @@ public class HttpGenerator
|
|||
header.put(_reason);
|
||||
header.put(HttpTokens.CRLF);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle 1xx
|
||||
if (_status>=100 && _status<200 )
|
||||
/* ------------------------------------------------------------ */
|
||||
private void generateHeaders(HttpFields fields,ByteBuffer header,ByteBuffer content,boolean last)
|
||||
{
|
||||
_noContent=true;
|
||||
|
||||
if (_status!=101 )
|
||||
{
|
||||
header.put(HttpTokens.CRLF);
|
||||
_state = State.START;
|
||||
return Result.FLUSH;
|
||||
}
|
||||
}
|
||||
else if (_status==204 || _status==304)
|
||||
{
|
||||
_noContent=true;
|
||||
}
|
||||
}
|
||||
|
||||
// Add Date header
|
||||
if (_status>=200 && _date!=null)
|
||||
|
@ -492,6 +557,7 @@ public class HttpGenerator
|
|||
}
|
||||
|
||||
// default field values
|
||||
boolean has_server = false;
|
||||
HttpFields.Field transfer_encoding=null;
|
||||
boolean keep_alive=false;
|
||||
boolean close=false;
|
||||
|
@ -518,7 +584,9 @@ public class HttpGenerator
|
|||
else
|
||||
{
|
||||
// write the field to the header
|
||||
field.putTo(header);
|
||||
header.put(HttpHeader.CONTENT_LENGTH.toBytesColonSpace());
|
||||
BufferUtil.putDecLong(header,length);
|
||||
BufferUtil.putCRLF(header);
|
||||
_contentLength=length;
|
||||
content_length=true;
|
||||
}
|
||||
|
@ -695,7 +763,7 @@ public class HttpGenerator
|
|||
}
|
||||
|
||||
// Add transfer_encoding if needed
|
||||
if (_contentLength == HttpTokens.CHUNKED_CONTENT)
|
||||
if (isChunking())
|
||||
{
|
||||
// try to use user supplied encoding as it may have other values.
|
||||
if (transfer_encoding != null && !HttpHeaderValue.CHUNKED.toString().equalsIgnoreCase(transfer_encoding.getValue()))
|
||||
|
@ -717,6 +785,7 @@ public class HttpGenerator
|
|||
_persistent=false;
|
||||
}
|
||||
|
||||
// If this is a response, work out persistence
|
||||
if (isResponse())
|
||||
{
|
||||
if (!_persistent && (close || _version.ordinal() > HttpVersion.HTTP_1_0.ordinal()))
|
||||
|
@ -756,55 +825,19 @@ public class HttpGenerator
|
|||
|
||||
// end the header.
|
||||
header.put(HttpTokens.CRLF);
|
||||
_state = _contentLength==HttpTokens.CHUNKED_CONTENT?State.CHUNKING:State.STREAMING;
|
||||
|
||||
}
|
||||
catch(BufferOverflowException e)
|
||||
{
|
||||
throw new RuntimeException("Header>"+header.capacity(),e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
BufferUtil.flipToFlush(header,pos);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle the content
|
||||
if (BufferUtil.hasContent(content))
|
||||
{
|
||||
// Can we do a direct flush
|
||||
if (BufferUtil.isEmpty(buffer) && content.remaining()>_largeContent)
|
||||
{
|
||||
_contentPrepared+=content.remaining();
|
||||
if (_state==State.CHUNKING)
|
||||
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 (_state==State.CHUNKING)
|
||||
prepareChunk(header,buffer.remaining());
|
||||
}
|
||||
|
||||
if (BufferUtil.hasContent(buffer))
|
||||
{
|
||||
if (last && BufferUtil.isEmpty(content) || _contentLength>0&&_contentLength==_contentPrepared)
|
||||
return Result.NEED_COMPLETE;
|
||||
|
||||
return Result.FLUSH;
|
||||
}
|
||||
return Result.OK;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
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:
|
||||
|
@ -817,14 +850,7 @@ public class HttpGenerator
|
|||
if (buffer==null)
|
||||
return Result.NEED_BUFFER;
|
||||
|
||||
// are we limited by content length?
|
||||
if (_contentLength>0)
|
||||
{
|
||||
_contentPrepared+=BufferUtil.put(content,buffer,_contentLength-_contentPrepared);
|
||||
if (_contentPrepared==_contentLength)
|
||||
return Result.NEED_COMMIT;
|
||||
}
|
||||
else
|
||||
// copy content to buffer
|
||||
_contentPrepared+=BufferUtil.put(content,buffer);
|
||||
|
||||
// are we full?
|
||||
|
@ -833,74 +859,49 @@ public class HttpGenerator
|
|||
|
||||
return Result.OK;
|
||||
|
||||
case STREAMING:
|
||||
case COMPLETING:
|
||||
return Result.NEED_COMPLETE;
|
||||
|
||||
case COMMITTED:
|
||||
|
||||
// Can we do a direct flush
|
||||
if (BufferUtil.isEmpty(buffer) && content.remaining()>_largeContent)
|
||||
{
|
||||
if (_contentLength>0)
|
||||
{
|
||||
long total=_contentPrepared+content.remaining();
|
||||
if (total>_contentLength)
|
||||
throw new IllegalStateException();
|
||||
if (total==_contentLength)
|
||||
return Result.NEED_COMPLETE;
|
||||
}
|
||||
_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;
|
||||
|
||||
// are we limited by content length?
|
||||
if (_contentLength>0)
|
||||
{
|
||||
_contentPrepared+=BufferUtil.put(content,buffer,_contentLength-_contentPrepared);
|
||||
if (_contentPrepared==_contentLength)
|
||||
return Result.NEED_COMPLETE;
|
||||
}
|
||||
else
|
||||
_contentPrepared+=BufferUtil.put(content,buffer);
|
||||
|
||||
// are we full?
|
||||
if (BufferUtil.isAtCapacity(buffer))
|
||||
return Result.FLUSH;
|
||||
|
||||
return Result.OK;
|
||||
|
||||
|
||||
case CHUNKING:
|
||||
if (isChunking())
|
||||
{
|
||||
if (chunk==null)
|
||||
return Result.NEED_CHUNK;
|
||||
|
||||
// Can we do a direct flush
|
||||
if (BufferUtil.isEmpty(buffer) && content.remaining()>_largeContent)
|
||||
{
|
||||
_contentPrepared+=content.remaining();
|
||||
BufferUtil.clear(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))
|
||||
{
|
||||
BufferUtil.clear(chunk);
|
||||
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();
|
||||
}
|
||||
|
@ -914,17 +915,21 @@ public class HttpGenerator
|
|||
BufferUtil.putCRLF(chunk);
|
||||
|
||||
// Add the chunk size to the header
|
||||
if (remaining>0)
|
||||
{
|
||||
BufferUtil.putHexInt(chunk, remaining);
|
||||
BufferUtil.putCRLF(chunk);
|
||||
|
||||
// Need a CRLF after the content
|
||||
_needCRLF=remaining>0;
|
||||
_needCRLF=true;
|
||||
}
|
||||
else
|
||||
{
|
||||
chunk.put(LAST_CHUNK);
|
||||
_needCRLF=false;
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Complete the message.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public Result flush(ByteBuffer chunk, ByteBuffer buffer) throws IOException
|
||||
|
@ -933,14 +938,18 @@ public class HttpGenerator
|
|||
{
|
||||
case START:
|
||||
return Result.NEED_COMMIT;
|
||||
case CHUNKING:
|
||||
case COMMITTED:
|
||||
if (isChunking())
|
||||
{
|
||||
if (chunk==null)
|
||||
return Result.NEED_CHUNK;
|
||||
|
||||
if (BufferUtil.hasContent(buffer))
|
||||
{
|
||||
BufferUtil.clear(chunk);
|
||||
BufferUtil.clearToFill(chunk);
|
||||
prepareChunk(chunk,buffer.remaining());
|
||||
BufferUtil.flipToFlush(chunk,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Result.FLUSH;
|
||||
|
@ -960,40 +969,37 @@ public class HttpGenerator
|
|||
switch(_state)
|
||||
{
|
||||
case START:
|
||||
case COMPLETING_UNCOMMITTED:
|
||||
_state=State.COMPLETING_UNCOMMITTED;
|
||||
return Result.NEED_COMMIT;
|
||||
|
||||
case CHUNKING:
|
||||
case COMPLETING:
|
||||
case COMMITTED:
|
||||
_state=State.COMPLETING;
|
||||
if (isChunking())
|
||||
{
|
||||
if (BufferUtil.hasContent(buffer))
|
||||
{
|
||||
if (chunk==null)
|
||||
return Result.NEED_CHUNK;
|
||||
|
||||
if (BufferUtil.hasContent(buffer))
|
||||
{
|
||||
_state=State.COMPLETING;
|
||||
BufferUtil.clear(chunk);
|
||||
BufferUtil.clearToFill(chunk);
|
||||
prepareChunk(chunk,buffer.remaining());
|
||||
BufferUtil.flipToFlush(chunk,0);
|
||||
return Result.FLUSH;
|
||||
}
|
||||
|
||||
if (!_sentEOC)
|
||||
{
|
||||
_state=State.END;
|
||||
BufferUtil.clearToFill(chunk);
|
||||
prepareChunk(chunk,0);
|
||||
_sentEOC=true;
|
||||
BufferUtil.flipToFlush(chunk,0);
|
||||
return Result.FLUSH;
|
||||
}
|
||||
return Result.OK;
|
||||
|
||||
case STREAMING:
|
||||
if (BufferUtil.hasContent(buffer))
|
||||
{
|
||||
_state=State.COMPLETING;
|
||||
else if (BufferUtil.hasContent(buffer))
|
||||
return Result.FLUSH;
|
||||
|
||||
}
|
||||
_state=State.END;
|
||||
return Result.OK;
|
||||
}
|
||||
return Result.OK;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
public static byte[] getReasonBuffer(int code)
|
||||
|
@ -1004,11 +1010,11 @@ public class HttpGenerator
|
|||
return null;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("%s{s=%d}",
|
||||
return String.format("%s{s=%s}",
|
||||
getClass().getSimpleName(),
|
||||
_state);
|
||||
}
|
||||
|
|
|
@ -72,4 +72,16 @@ public enum HttpVersion
|
|||
{
|
||||
return _string;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public static HttpVersion fromVersion(int version)
|
||||
{
|
||||
switch(version)
|
||||
{
|
||||
case 9: return HttpVersion.HTTP_0_9;
|
||||
case 10: return HttpVersion.HTTP_1_0;
|
||||
case 11: return HttpVersion.HTTP_1_1;
|
||||
default: throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,8 +13,11 @@
|
|||
|
||||
package org.eclipse.jetty.http;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.not;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.matchers.JUnitMatchers.containsString;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
@ -23,332 +26,444 @@ import javax.swing.text.View;
|
|||
|
||||
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.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.matchers.JUnitMatchers;
|
||||
|
||||
public class HttpGeneratorClientTest
|
||||
{
|
||||
public final static String CONTENT="The quick brown fox jumped over the lazy dog.\nNow is the time for all good men to come to the aid of the party\nThe moon is blue to a fish in love.\n";
|
||||
public final static String[] connect={null,"keep-alive","close"};
|
||||
|
||||
|
||||
@Test
|
||||
public void testContentLength() throws Exception
|
||||
public void testRequestNoContent() throws Exception
|
||||
{
|
||||
ByteBuffer bb=new ByteArrayBuffer(8096);
|
||||
ByteBuffer sb=new ByteArrayBuffer(1500);
|
||||
ByteArrayEndPoint endp = new ByteArrayEndPoint(new byte[0],4096);
|
||||
HttpGenerator generator = new HttpGenerator(new SimpleBuffers(sb,bb),endp);
|
||||
|
||||
generator.setRequest("GET","/usr");
|
||||
|
||||
ByteBuffer header=BufferUtil.allocate(8096);
|
||||
HttpFields fields = new HttpFields();
|
||||
fields.add("Header","Value");
|
||||
fields.add("Content-Type","text/plain");
|
||||
HttpGenerator gen = new HttpGenerator();
|
||||
|
||||
String content = "The quick brown fox jumped over the lazy dog";
|
||||
fields.addLongField("Content-Length",content.length());
|
||||
fields.add("Host","something");
|
||||
fields.add("User-Agent","test");
|
||||
|
||||
generator.completeHeader(fields,false);
|
||||
gen.setRequest(HttpMethod.GET,"/index.html",HttpVersion.HTTP_1_1);
|
||||
|
||||
generator.addContent(new ByteArrayBuffer(content),true);
|
||||
generator.flushBuffer();
|
||||
generator.complete();
|
||||
generator.flushBuffer();
|
||||
HttpGenerator.Result
|
||||
result=gen.complete(null,null);
|
||||
assertEquals(HttpGenerator.State.COMPLETING_UNCOMMITTED,gen.getState());
|
||||
assertEquals(HttpGenerator.Result.NEED_COMMIT,result);
|
||||
|
||||
String result=endp.getOut().toString().replace("\r\n","|").replace('\r','|').replace('\n','|');
|
||||
assertEquals("GET /usr HTTP/1.1|Header: Value|Content-Type: text/plain|Content-Length: 44||"+content,result);
|
||||
result=gen.commit(fields,header,null,null,true);
|
||||
assertEquals(HttpGenerator.Result.NEED_COMPLETE,result);
|
||||
String out = 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);
|
||||
assertEquals(HttpGenerator.Result.OK,result);
|
||||
|
||||
|
||||
assertEquals(HttpGenerator.State.END,gen.getState());
|
||||
assertEquals(0,gen.getContentWritten()); }
|
||||
|
||||
@Test
|
||||
public void testRequestWithSmallContent() throws Exception
|
||||
{
|
||||
ByteBuffer header=BufferUtil.allocate(4096);
|
||||
ByteBuffer buffer=BufferUtil.allocate(8096);
|
||||
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();
|
||||
|
||||
gen.setVersion(HttpVersion.HTTP_1_1);
|
||||
gen.setRequest("POST","/index.html");
|
||||
fields.add("Host","something");
|
||||
fields.add("User-Agent","test");
|
||||
|
||||
HttpGenerator.Result
|
||||
|
||||
result=gen.prepareContent(null,null,content);
|
||||
assertEquals(HttpGenerator.Result.NEED_BUFFER,result);
|
||||
assertEquals(HttpGenerator.State.START,gen.getState());
|
||||
|
||||
result=gen.prepareContent(null,buffer,content);
|
||||
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);
|
||||
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));
|
||||
|
||||
result=gen.complete(null,buffer);
|
||||
assertEquals(HttpGenerator.Result.NEED_COMMIT,result);
|
||||
assertEquals(HttpGenerator.State.COMPLETING_UNCOMMITTED,gen.getState());
|
||||
|
||||
result=gen.commit(fields,header,buffer,content,true);
|
||||
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);
|
||||
assertEquals(HttpGenerator.Result.OK,result);
|
||||
assertEquals(HttpGenerator.State.END,gen.getState());
|
||||
|
||||
assertThat(head,containsString("POST /index.html HTTP/1.1"));
|
||||
assertThat(head,containsString("Host: something"));
|
||||
assertThat(head,containsString("Content-Length: 58"));
|
||||
assertTrue(head.endsWith("\r\n\r\n"));
|
||||
|
||||
assertEquals("Hello World. The quick brown fox jumped over the lazy dog.",body);
|
||||
|
||||
assertEquals(58,gen.getContentWritten());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAutoContentLength() throws Exception
|
||||
public void testRequestWithChunkedContent() throws Exception
|
||||
{
|
||||
ByteBuffer bb=new ByteArrayBuffer(8096);
|
||||
ByteBuffer sb=new ByteArrayBuffer(1500);
|
||||
ByteArrayEndPoint endp = new ByteArrayEndPoint(new byte[0],4096);
|
||||
HttpGenerator generator = new HttpGenerator(new SimpleBuffers(sb,bb),endp);
|
||||
|
||||
generator.setRequest("GET","/usr");
|
||||
|
||||
ByteBuffer header=BufferUtil.allocate(4096);
|
||||
ByteBuffer buffer=BufferUtil.allocate(16);
|
||||
ByteBuffer content0=BufferUtil.toBuffer("Hello World! ");
|
||||
ByteBuffer content1=BufferUtil.toBuffer("The quick brown fox jumped over the lazy dog. ");
|
||||
HttpFields fields = new HttpFields();
|
||||
fields.add("Header","Value");
|
||||
fields.add("Content-Type","text/plain");
|
||||
HttpGenerator gen = new HttpGenerator();
|
||||
|
||||
String content = "The quick brown fox jumped over the lazy dog";
|
||||
gen.setVersion(HttpVersion.HTTP_1_1);
|
||||
gen.setRequest("POST","/index.html");
|
||||
fields.add("Host","something");
|
||||
fields.add("User-Agent","test");
|
||||
|
||||
generator.addContent(new ByteArrayBuffer(content),true);
|
||||
generator.completeHeader(fields,true);
|
||||
HttpGenerator.Result
|
||||
|
||||
generator.flushBuffer();
|
||||
generator.complete();
|
||||
generator.flushBuffer();
|
||||
result=gen.prepareContent(null,null,content0);
|
||||
assertEquals(HttpGenerator.Result.NEED_BUFFER,result);
|
||||
assertEquals(HttpGenerator.State.START,gen.getState());
|
||||
|
||||
String result=endp.getOut().toString().replace("\r\n","|").replace('\r','|').replace('\n','|');
|
||||
assertEquals("GET /usr HTTP/1.1|Header: Value|Content-Type: text/plain|Content-Length: 44||"+content,result);
|
||||
result=gen.prepareContent(null,buffer,content0);
|
||||
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());
|
||||
assertEquals("Hello World! The",BufferUtil.toString(buffer));
|
||||
assertEquals(43,content1.remaining());
|
||||
|
||||
result=gen.commit(fields,header,buffer,content1,false);
|
||||
assertEquals(HttpGenerator.Result.FLUSH,result);
|
||||
assertEquals(HttpGenerator.State.COMMITTING,gen.getState());
|
||||
assertEquals("Hello World! The",BufferUtil.toString(buffer));
|
||||
assertEquals(43,content1.remaining());
|
||||
assertTrue(gen.isChunking());
|
||||
|
||||
String head = BufferUtil.toString(header);
|
||||
BufferUtil.clear(header);
|
||||
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);
|
||||
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);
|
||||
assertEquals(HttpGenerator.Result.FLUSH,result);
|
||||
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
|
||||
assertEquals("\r\n10\r\n",BufferUtil.toString(chunk));
|
||||
assertEquals(" quick brown fox",BufferUtil.toString(buffer));
|
||||
assertEquals(27,content1.remaining());
|
||||
body += BufferUtil.toString(chunk)+BufferUtil.toString(buffer);
|
||||
BufferUtil.clear(chunk);
|
||||
BufferUtil.clear(buffer);
|
||||
|
||||
result=gen.prepareContent(chunk,buffer,content1);
|
||||
assertEquals(HttpGenerator.Result.FLUSH,result);
|
||||
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
|
||||
assertEquals("\r\n10\r\n",BufferUtil.toString(chunk));
|
||||
assertEquals(" jumped over the",BufferUtil.toString(buffer));
|
||||
assertEquals(11,content1.remaining());
|
||||
body += BufferUtil.toString(chunk)+BufferUtil.toString(buffer);
|
||||
BufferUtil.clear(chunk);
|
||||
BufferUtil.clear(buffer);
|
||||
|
||||
result=gen.prepareContent(chunk,buffer,content1);
|
||||
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);
|
||||
assertEquals(HttpGenerator.Result.FLUSH,result);
|
||||
assertEquals(HttpGenerator.State.COMPLETING,gen.getState());
|
||||
assertEquals("\r\nB\r\n",BufferUtil.toString(chunk));
|
||||
assertEquals(" lazy dog. ",BufferUtil.toString(buffer));
|
||||
body += BufferUtil.toString(chunk)+BufferUtil.toString(buffer);
|
||||
BufferUtil.clear(chunk);
|
||||
BufferUtil.clear(buffer);
|
||||
|
||||
result=gen.complete(chunk,buffer);
|
||||
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);
|
||||
assertEquals(HttpGenerator.Result.OK,result);
|
||||
assertEquals(HttpGenerator.State.END,gen.getState());
|
||||
|
||||
assertEquals(59,gen.getContentWritten());
|
||||
|
||||
// System.err.println(head+body);
|
||||
|
||||
assertThat(head,containsString("POST /index.html HTTP/1.1"));
|
||||
assertThat(head,containsString("Host: something"));
|
||||
assertThat(head,not(containsString("Content-Length")));
|
||||
assertThat(head,containsString("Transfer-Encoding: chunked"));
|
||||
assertTrue(head.endsWith("\r\n\r\n10\r\n"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChunked() throws Exception
|
||||
public void testRequestWithLargeChunkedContent() throws Exception
|
||||
{
|
||||
ByteBuffer bb=new ByteArrayBuffer(8096);
|
||||
ByteBuffer sb=new ByteArrayBuffer(1500);
|
||||
ByteArrayEndPoint endp = new ByteArrayEndPoint(new byte[0],4096);
|
||||
HttpGenerator generator = new HttpGenerator(new SimpleBuffers(sb,bb),endp);
|
||||
|
||||
generator.setRequest("GET","/usr");
|
||||
|
||||
ByteBuffer header=BufferUtil.allocate(4096);
|
||||
ByteBuffer content0=BufferUtil.toBuffer("Hello Cruel World! ");
|
||||
ByteBuffer content1=BufferUtil.toBuffer("The quick brown fox jumped over the lazy dog. ");
|
||||
HttpFields fields = new HttpFields();
|
||||
fields.add("Header","Value");
|
||||
fields.add("Content-Type","text/plain");
|
||||
HttpGenerator gen = new HttpGenerator();
|
||||
gen.setLargeContent(8);
|
||||
|
||||
String content = "The quick brown fox jumped over the lazy dog";
|
||||
gen.setVersion(HttpVersion.HTTP_1_1);
|
||||
gen.setRequest("POST","/index.html");
|
||||
fields.add("Host","something");
|
||||
fields.add("User-Agent","test");
|
||||
|
||||
generator.completeHeader(fields,false);
|
||||
HttpGenerator.Result
|
||||
|
||||
generator.addContent(new ByteArrayBuffer(content),false);
|
||||
generator.flushBuffer();
|
||||
generator.complete();
|
||||
generator.flushBuffer();
|
||||
result=gen.prepareContent(null,null,content0);
|
||||
assertEquals(HttpGenerator.Result.NEED_COMMIT,result);
|
||||
assertEquals(HttpGenerator.State.START,gen.getState());
|
||||
|
||||
String result=endp.getOut().toString().replace("\r\n","|").replace('\r','|').replace('\n','|');
|
||||
assertEquals("GET /usr HTTP/1.1|Header: Value|Content-Type: text/plain|Transfer-Encoding: chunked||2C|"+content+"|0||",result);
|
||||
result=gen.commit(fields,header,null,content0,false);
|
||||
assertEquals(HttpGenerator.Result.FLUSH_CONTENT,result);
|
||||
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
|
||||
assertTrue(gen.isChunking());
|
||||
|
||||
String head = BufferUtil.toString(header);
|
||||
BufferUtil.clear(header);
|
||||
String body = BufferUtil.toString(content0);
|
||||
BufferUtil.clear(content0);
|
||||
|
||||
result=gen.commit(fields,header,null,content0,false);
|
||||
assertEquals(HttpGenerator.Result.OK,result);
|
||||
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
|
||||
|
||||
result=gen.prepareContent(null,null,content1);
|
||||
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);
|
||||
assertEquals(HttpGenerator.Result.FLUSH_CONTENT,result);
|
||||
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
|
||||
assertEquals("\r\n2E\r\n",BufferUtil.toString(chunk));
|
||||
|
||||
body += BufferUtil.toString(chunk)+BufferUtil.toString(content1);
|
||||
BufferUtil.clear(content1);
|
||||
|
||||
result=gen.complete(chunk,null);
|
||||
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);
|
||||
assertEquals(HttpGenerator.Result.OK,result);
|
||||
assertEquals(HttpGenerator.State.END,gen.getState());
|
||||
|
||||
assertEquals(65,gen.getContentWritten());
|
||||
|
||||
// System.err.println(head+body);
|
||||
|
||||
assertThat(head,containsString("POST /index.html HTTP/1.1"));
|
||||
assertThat(head,containsString("Host: something"));
|
||||
assertThat(head,not(containsString("Content-Length")));
|
||||
assertThat(head,containsString("Transfer-Encoding: chunked"));
|
||||
assertTrue(head.endsWith("\r\n\r\n13\r\n"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testRequestWithKnownContent() throws Exception
|
||||
{
|
||||
ByteBuffer header=BufferUtil.allocate(4096);
|
||||
ByteBuffer buffer=BufferUtil.allocate(16);
|
||||
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();
|
||||
|
||||
gen.setVersion(HttpVersion.HTTP_1_1);
|
||||
gen.setRequest("POST","/index.html");
|
||||
fields.add("Host","something");
|
||||
fields.add("User-Agent","test");
|
||||
fields.add("Content-Length","59");
|
||||
gen.setContentLength(59);
|
||||
|
||||
HttpGenerator.Result
|
||||
|
||||
result=gen.prepareContent(null,null,content0);
|
||||
assertEquals(HttpGenerator.Result.NEED_BUFFER,result);
|
||||
assertEquals(HttpGenerator.State.START,gen.getState());
|
||||
|
||||
result=gen.prepareContent(null,buffer,content0);
|
||||
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());
|
||||
assertEquals("Hello World! The",BufferUtil.toString(buffer));
|
||||
assertEquals(43,content1.remaining());
|
||||
|
||||
result=gen.commit(fields,header,buffer,content1,false);
|
||||
assertEquals(HttpGenerator.Result.FLUSH,result);
|
||||
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
|
||||
assertEquals("Hello World! The",BufferUtil.toString(buffer));
|
||||
assertEquals(43,content1.remaining());
|
||||
assertTrue(!gen.isChunking());
|
||||
|
||||
String head = BufferUtil.toString(header);
|
||||
BufferUtil.clear(header);
|
||||
String body = BufferUtil.toString(buffer);
|
||||
BufferUtil.clear(buffer);
|
||||
|
||||
result=gen.prepareContent(null,buffer,content1);
|
||||
assertEquals(HttpGenerator.Result.FLUSH,result);
|
||||
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
|
||||
assertEquals(" quick brown fox",BufferUtil.toString(buffer));
|
||||
assertEquals(27,content1.remaining());
|
||||
body += BufferUtil.toString(buffer);
|
||||
BufferUtil.clear(buffer);
|
||||
|
||||
result=gen.prepareContent(null,buffer,content1);
|
||||
assertEquals(HttpGenerator.Result.FLUSH,result);
|
||||
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
|
||||
assertEquals(" jumped over the",BufferUtil.toString(buffer));
|
||||
assertEquals(11,content1.remaining());
|
||||
body += BufferUtil.toString(buffer);
|
||||
BufferUtil.clear(buffer);
|
||||
|
||||
result=gen.prepareContent(null,buffer,content1);
|
||||
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);
|
||||
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);
|
||||
assertEquals(HttpGenerator.Result.OK,result);
|
||||
assertEquals(HttpGenerator.State.END,gen.getState());
|
||||
assertEquals(0,buffer.remaining());
|
||||
|
||||
assertEquals(59,gen.getContentWritten());
|
||||
|
||||
// System.err.println(head+body);
|
||||
|
||||
assertThat(head,containsString("POST /index.html HTTP/1.1"));
|
||||
assertThat(head,containsString("Host: something"));
|
||||
assertThat(head,containsString("Content-Length: 59"));
|
||||
assertThat(head,not(containsString("chunked")));
|
||||
assertTrue(head.endsWith("\r\n\r\n"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHTTP() throws Exception
|
||||
public void testRequestWithKnownLargeContent() throws Exception
|
||||
{
|
||||
ByteBuffer bb=new ByteArrayBuffer(8096);
|
||||
ByteBuffer sb=new ByteArrayBuffer(1500);
|
||||
ByteBuffer header=BufferUtil.allocate(4096);
|
||||
ByteBuffer content0=BufferUtil.toBuffer("Hello World! ");
|
||||
ByteBuffer content1=BufferUtil.toBuffer("The quick brown fox jumped over the lazy dog. ");
|
||||
HttpFields fields = new HttpFields();
|
||||
ByteArrayEndPoint endp = new ByteArrayEndPoint(new byte[0],4096);
|
||||
HttpGenerator hb = new HttpGenerator(new SimpleBuffers(sb,bb),endp);
|
||||
Handler handler = new Handler();
|
||||
HttpParser parser=null;
|
||||
HttpGenerator gen = new HttpGenerator();
|
||||
gen.setLargeContent(8);
|
||||
|
||||
// For HTTP version
|
||||
for (int v=9;v<=11;v++)
|
||||
{
|
||||
// For each test result
|
||||
for (int r=0;r<tr.length;r++)
|
||||
{
|
||||
// chunks = 1 to 3
|
||||
for (int chunks=1;chunks<=6;chunks++)
|
||||
{
|
||||
// For none, keep-alive, close
|
||||
for (int c=0;c<connect.length;c++)
|
||||
{
|
||||
String t="v="+v+",r="+r+",chunks="+chunks+",c="+c+",tr="+tr[r];
|
||||
// System.err.println(t);
|
||||
gen.setVersion(HttpVersion.HTTP_1_1);
|
||||
gen.setRequest("POST","/index.html");
|
||||
fields.add("Host","something");
|
||||
fields.add("User-Agent","test");
|
||||
fields.add("Content-Length","59");
|
||||
gen.setContentLength(59);
|
||||
|
||||
hb.reset();
|
||||
endp.reset();
|
||||
fields.clear();
|
||||
HttpGenerator.Result
|
||||
|
||||
// System.out.println("TEST: "+t);
|
||||
result=gen.prepareContent(null,null,content0);
|
||||
assertEquals(HttpGenerator.Result.NEED_COMMIT,result);
|
||||
assertEquals(HttpGenerator.State.START,gen.getState());
|
||||
|
||||
try
|
||||
{
|
||||
tr[r].build(v,hb,connect[c],null,chunks, fields);
|
||||
}
|
||||
catch(IllegalStateException e)
|
||||
{
|
||||
if (v<10 || v==10 && chunks>2)
|
||||
continue;
|
||||
System.err.println(t);
|
||||
throw e;
|
||||
}
|
||||
String request=endp.getOut().toString();
|
||||
// System.out.println(request+(hb.isPersistent()?"...\n":"---\n"));
|
||||
result=gen.commit(fields,header,null,content0,false);
|
||||
assertEquals(HttpGenerator.Result.FLUSH_CONTENT,result);
|
||||
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
|
||||
assertTrue(!gen.isChunking());
|
||||
|
||||
assertTrue(t,hb.isPersistent());
|
||||
String head = BufferUtil.toString(header);
|
||||
BufferUtil.clear(header);
|
||||
String body = BufferUtil.toString(content0);
|
||||
BufferUtil.clear(content0);
|
||||
|
||||
if (v==9)
|
||||
{
|
||||
assertEquals(t,"GET /context/path/info\r\n", request);
|
||||
continue;
|
||||
result=gen.commit(fields,header,null,null,false);
|
||||
assertEquals(HttpGenerator.Result.OK,result);
|
||||
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
|
||||
|
||||
result=gen.prepareContent(null,null,content1);
|
||||
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);
|
||||
assertEquals(HttpGenerator.Result.OK,result);
|
||||
assertEquals(HttpGenerator.State.END,gen.getState());
|
||||
|
||||
assertEquals(59,gen.getContentWritten());
|
||||
|
||||
// System.err.println(head+body);
|
||||
|
||||
assertThat(head,containsString("POST /index.html HTTP/1.1"));
|
||||
assertThat(head,containsString("Host: something"));
|
||||
assertThat(head,containsString("Content-Length: 59"));
|
||||
assertThat(head,not(containsString("chunked")));
|
||||
assertTrue(head.endsWith("\r\n\r\n"));
|
||||
}
|
||||
|
||||
parser=new HttpParser(new ByteArrayBuffer(request.getBytes()), handler);
|
||||
try
|
||||
{
|
||||
parser.parse();
|
||||
}
|
||||
catch(IOException e)
|
||||
{
|
||||
if (tr[r].body!=null)
|
||||
throw e;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tr[r].body!=null)
|
||||
assertEquals(t,tr[r].body, this.content);
|
||||
if (v==10)
|
||||
assertTrue(t,hb.isPersistent() || tr[r].values[1]==null || c==2 || c==0);
|
||||
else
|
||||
assertTrue(t,hb.isPersistent() || c==2);
|
||||
|
||||
assertTrue(t,tr[r].values[1]==null || content.length()==Integer.parseInt(tr[r].values[1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final String[] headers= { "Content-Type","Content-Length","Connection","Transfer-Encoding","Other"};
|
||||
private static class TR
|
||||
{
|
||||
private String[] values=new String[headers.length];
|
||||
private String body;
|
||||
|
||||
private TR(String ct, String cl ,String content)
|
||||
{
|
||||
values[0]=ct;
|
||||
values[1]=cl;
|
||||
values[4]="value";
|
||||
this.body=content;
|
||||
}
|
||||
|
||||
private void build(int version,HttpGenerator hb, String connection, String te, int chunks, HttpFields fields)
|
||||
throws Exception
|
||||
{
|
||||
values[2]=connection;
|
||||
values[3]=te;
|
||||
|
||||
hb.setRequest(HttpMethod.GET,"/context/path/info");
|
||||
hb.setVersion(version);
|
||||
|
||||
for (int i=0;i<headers.length;i++)
|
||||
{
|
||||
if (values[i]==null)
|
||||
continue;
|
||||
fields.put(new ByteArrayBuffer(headers[i]),new ByteArrayBuffer(values[i]));
|
||||
}
|
||||
|
||||
if (body!=null)
|
||||
{
|
||||
int inc=1+body.length()/chunks;
|
||||
ByteBuffer buf=new ByteArrayBuffer(body);
|
||||
View view = new View(buf);
|
||||
for (int i=1;i<chunks;i++)
|
||||
{
|
||||
view.setPutIndex(i*inc);
|
||||
view.setGetIndex((i-1)*inc);
|
||||
hb.addContent(view,Generator.MORE);
|
||||
if (hb.isBufferFull() && hb.isState(AbstractGenerator.STATE_HEADER))
|
||||
hb.completeHeader(fields, Generator.MORE);
|
||||
if (i%2==0)
|
||||
{
|
||||
if (hb.isState(AbstractGenerator.STATE_HEADER))
|
||||
{
|
||||
if (version<11)
|
||||
fields.addLongField("Content-Length",body.length());
|
||||
hb.completeHeader(fields, Generator.MORE);
|
||||
}
|
||||
hb.flushBuffer();
|
||||
}
|
||||
}
|
||||
view.setPutIndex(buf.putIndex());
|
||||
view.setGetIndex((chunks-1)*inc);
|
||||
hb.addContent(view,Generator.LAST);
|
||||
if(hb.isState(AbstractGenerator.STATE_HEADER))
|
||||
hb.completeHeader(fields, Generator.LAST);
|
||||
}
|
||||
else
|
||||
{
|
||||
hb.completeHeader(fields, Generator.LAST);
|
||||
}
|
||||
hb.complete();
|
||||
while(!hb.isComplete())
|
||||
hb.flushBuffer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "["+values[0]+","+values[1]+","+(body==null?"none":"_content")+"]";
|
||||
}
|
||||
}
|
||||
|
||||
private final TR[] tr =
|
||||
{
|
||||
/* 0 */ new TR(null,null,null),
|
||||
/* 1 */ new TR(null,null,CONTENT),
|
||||
/* 3 */ new TR(null,""+CONTENT.length(),CONTENT),
|
||||
/* 4 */ new TR("text/html",null,null),
|
||||
/* 5 */ new TR("text/html",null,CONTENT),
|
||||
/* 7 */ new TR("text/html",""+CONTENT.length(),CONTENT),
|
||||
};
|
||||
|
||||
|
||||
private String content;
|
||||
private String f0;
|
||||
private String f1;
|
||||
private String f2;
|
||||
private String[] hdr;
|
||||
private String[] val;
|
||||
private int h;
|
||||
|
||||
private class Handler extends HttpParser.EventHandler
|
||||
{
|
||||
private int index=0;
|
||||
|
||||
@Override
|
||||
public void content(ByteBuffer ref)
|
||||
{
|
||||
if (index == 0)
|
||||
content= "";
|
||||
content= content.substring(0, index) + ref;
|
||||
index+=ref.length();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startRequest(ByteBuffer tok0, ByteBuffer tok1, ByteBuffer tok2)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/* (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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parsedHeader(ByteBuffer name,ByteBuffer value)
|
||||
{
|
||||
hdr[++h]= name.toString();
|
||||
val[h]= value.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void headerComplete()
|
||||
{
|
||||
content= null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void messageComplete(long contentLength)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,9 +13,12 @@
|
|||
|
||||
package org.eclipse.jetty.http;
|
||||
|
||||
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 java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
@ -38,8 +41,10 @@ public class HttpGeneratorTest
|
|||
public final static String CONTENT="The quick brown fox jumped over the lazy dog.\nNow is the time for all good men to come to the aid of the party\nThe moon is blue to a fish in love.\n";
|
||||
public final static String[] connect={null,"keep-alive","close","TE, close"};
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testRequest() throws Exception
|
||||
public void testResponseNoContent() throws Exception
|
||||
{
|
||||
ByteBuffer header=BufferUtil.allocate(8096);
|
||||
HttpFields fields = new HttpFields();
|
||||
|
@ -52,68 +57,411 @@ public class HttpGeneratorTest
|
|||
|
||||
HttpGenerator.Result
|
||||
result=gen.complete(null,null);
|
||||
assertEquals(HttpGenerator.State.COMPLETING_UNCOMMITTED,gen.getState());
|
||||
assertEquals(HttpGenerator.Result.NEED_COMMIT,result);
|
||||
|
||||
result=gen.commit(fields,header,null,null,true);
|
||||
String out = BufferUtil.toString(header);
|
||||
BufferUtil.clear(header);
|
||||
assertEquals(HttpGenerator.Result.NEED_COMPLETE,result);
|
||||
String head = BufferUtil.toString(header);
|
||||
BufferUtil.clear(header);
|
||||
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")));
|
||||
|
||||
result=gen.complete(null,null);
|
||||
assertEquals(HttpGenerator.Result.OK,result);
|
||||
|
||||
assertTrue(out.indexOf("GET /index.html HTTP/1.1")==0);
|
||||
assertTrue(out.indexOf("Content-Length")==-1);
|
||||
|
||||
assertEquals(HttpGenerator.State.END,gen.getState());
|
||||
assertEquals(0,gen.getContentWritten()); }
|
||||
assertEquals(0,gen.getContentWritten());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequestWithSmallContent() throws Exception
|
||||
public void testResponseWithSmallContent() throws Exception
|
||||
{
|
||||
ByteBuffer header=BufferUtil.allocate(8096);
|
||||
ByteBuffer header=BufferUtil.allocate(4096);
|
||||
ByteBuffer buffer=BufferUtil.allocate(8096);
|
||||
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();
|
||||
|
||||
gen.setVersion(HttpVersion.HTTP_1_1);
|
||||
gen.setRequest("POST","/index.html");
|
||||
fields.add("Host","something");
|
||||
fields.add("User-Agent","test");
|
||||
gen.setResponse(200,null);
|
||||
fields.add("Last-Modified",HttpFields.__01Jan1970);
|
||||
|
||||
HttpGenerator.Result
|
||||
|
||||
result=gen.prepareContent(null,null,content);
|
||||
assertEquals(HttpGenerator.Result.NEED_BUFFER,result);
|
||||
assertEquals(HttpGenerator.State.START,gen.getState());
|
||||
|
||||
result=gen.prepareContent(null,buffer,content);
|
||||
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);
|
||||
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));
|
||||
|
||||
result=gen.complete(null,buffer);
|
||||
assertEquals(HttpGenerator.Result.NEED_COMMIT,result);
|
||||
assertEquals(HttpGenerator.State.COMPLETING_UNCOMMITTED,gen.getState());
|
||||
|
||||
result=gen.commit(fields,header,buffer,content,true);
|
||||
assertEquals(HttpGenerator.Result.FLUSH,result);
|
||||
String out = BufferUtil.toString(header);
|
||||
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);
|
||||
assertEquals(HttpGenerator.Result.OK,result);
|
||||
assertEquals(HttpGenerator.State.END,gen.getState());
|
||||
|
||||
assertThat(head,containsString("HTTP/1.1 200 OK"));
|
||||
assertThat(head,containsString("Last-Modified: Thu, 01 Jan 1970 00?00?00 GMT"));
|
||||
assertThat(head,containsString("Content-Length: 58"));
|
||||
assertTrue(head.endsWith("\r\n\r\n"));
|
||||
|
||||
assertEquals("Hello World. The quick brown fox jumped over the lazy dog.",body);
|
||||
|
||||
assertEquals(58,gen.getContentWritten());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResponseWithChunkedContent() throws Exception
|
||||
{
|
||||
ByteBuffer header=BufferUtil.allocate(4096);
|
||||
ByteBuffer buffer=BufferUtil.allocate(16);
|
||||
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();
|
||||
|
||||
gen.setVersion(HttpVersion.HTTP_1_1);
|
||||
gen.setResponse(200,null);
|
||||
fields.add("Last-Modified",HttpFields.__01Jan1970);
|
||||
|
||||
HttpGenerator.Result
|
||||
|
||||
result=gen.prepareContent(null,null,content0);
|
||||
assertEquals(HttpGenerator.Result.NEED_BUFFER,result);
|
||||
assertEquals(HttpGenerator.State.START,gen.getState());
|
||||
|
||||
result=gen.prepareContent(null,buffer,content0);
|
||||
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());
|
||||
assertEquals("Hello World! The",BufferUtil.toString(buffer));
|
||||
assertEquals(43,content1.remaining());
|
||||
|
||||
result=gen.commit(fields,header,buffer,content1,false);
|
||||
assertEquals(HttpGenerator.Result.FLUSH,result);
|
||||
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
|
||||
assertEquals("Hello World! The",BufferUtil.toString(buffer));
|
||||
assertEquals(43,content1.remaining());
|
||||
assertTrue(gen.isChunking());
|
||||
|
||||
String head = BufferUtil.toString(header);
|
||||
BufferUtil.clear(header);
|
||||
String body = BufferUtil.toString(buffer);
|
||||
BufferUtil.clear(buffer);
|
||||
|
||||
result=gen.prepareContent(null,buffer,content1);
|
||||
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);
|
||||
assertEquals(HttpGenerator.Result.FLUSH,result);
|
||||
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
|
||||
assertEquals("\r\n10\r\n",BufferUtil.toString(chunk));
|
||||
assertEquals(" quick brown fox",BufferUtil.toString(buffer));
|
||||
assertEquals(27,content1.remaining());
|
||||
body += BufferUtil.toString(chunk)+BufferUtil.toString(buffer);
|
||||
BufferUtil.clear(chunk);
|
||||
BufferUtil.clear(buffer);
|
||||
|
||||
result=gen.prepareContent(chunk,buffer,content1);
|
||||
assertEquals(HttpGenerator.Result.FLUSH,result);
|
||||
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
|
||||
assertEquals("\r\n10\r\n",BufferUtil.toString(chunk));
|
||||
assertEquals(" jumped over the",BufferUtil.toString(buffer));
|
||||
assertEquals(11,content1.remaining());
|
||||
body += BufferUtil.toString(chunk)+BufferUtil.toString(buffer);
|
||||
BufferUtil.clear(chunk);
|
||||
BufferUtil.clear(buffer);
|
||||
|
||||
result=gen.prepareContent(chunk,buffer,content1);
|
||||
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);
|
||||
assertEquals(HttpGenerator.Result.FLUSH,result);
|
||||
assertEquals(HttpGenerator.State.COMPLETING,gen.getState());
|
||||
assertEquals("\r\nB\r\n",BufferUtil.toString(chunk));
|
||||
assertEquals(" lazy dog. ",BufferUtil.toString(buffer));
|
||||
body += BufferUtil.toString(chunk)+BufferUtil.toString(buffer);
|
||||
BufferUtil.clear(chunk);
|
||||
BufferUtil.clear(buffer);
|
||||
|
||||
result=gen.complete(chunk,buffer);
|
||||
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);
|
||||
assertEquals(HttpGenerator.Result.OK,result);
|
||||
assertEquals(HttpGenerator.State.END,gen.getState());
|
||||
|
||||
assertEquals(59,gen.getContentWritten());
|
||||
|
||||
// System.err.println(head+body);
|
||||
|
||||
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("Transfer-Encoding: chunked"));
|
||||
assertTrue(head.endsWith("\r\n\r\n10\r\n"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResponseWithLargeChunkedContent() throws Exception
|
||||
{
|
||||
ByteBuffer header=BufferUtil.allocate(4096);
|
||||
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();
|
||||
gen.setLargeContent(8);
|
||||
|
||||
gen.setVersion(HttpVersion.HTTP_1_1);
|
||||
gen.setResponse(200,null);
|
||||
fields.add("Last-Modified",HttpFields.__01Jan1970);
|
||||
|
||||
HttpGenerator.Result
|
||||
|
||||
result=gen.prepareContent(null,null,content0);
|
||||
assertEquals(HttpGenerator.Result.NEED_COMMIT,result);
|
||||
assertEquals(HttpGenerator.State.START,gen.getState());
|
||||
|
||||
result=gen.commit(fields,header,null,content0,false);
|
||||
assertEquals(HttpGenerator.Result.FLUSH_CONTENT,result);
|
||||
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
|
||||
assertTrue(gen.isChunking());
|
||||
|
||||
String head = BufferUtil.toString(header);
|
||||
BufferUtil.clear(header);
|
||||
String body = BufferUtil.toString(content0);
|
||||
BufferUtil.clear(content0);
|
||||
|
||||
result=gen.commit(fields,header,null,content0,false);
|
||||
assertEquals(HttpGenerator.Result.OK,result);
|
||||
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
|
||||
|
||||
result=gen.prepareContent(null,null,content1);
|
||||
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);
|
||||
assertEquals(HttpGenerator.Result.FLUSH_CONTENT,result);
|
||||
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
|
||||
assertEquals("\r\n2E\r\n",BufferUtil.toString(chunk));
|
||||
|
||||
body += BufferUtil.toString(chunk)+BufferUtil.toString(content1);
|
||||
BufferUtil.clear(content1);
|
||||
|
||||
result=gen.complete(chunk,null);
|
||||
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);
|
||||
assertEquals(HttpGenerator.Result.OK,result);
|
||||
assertEquals(HttpGenerator.State.END,gen.getState());
|
||||
|
||||
assertEquals(65,gen.getContentWritten());
|
||||
|
||||
// System.err.println(head+body);
|
||||
|
||||
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("Transfer-Encoding: chunked"));
|
||||
assertTrue(head.endsWith("\r\n\r\n13\r\n"));
|
||||
}
|
||||
|
||||
|
||||
result=gen.commit(fields,header,null,null,true);
|
||||
assertEquals(HttpGenerator.Result.NEED_COMPLETE,result);
|
||||
@Test
|
||||
public void testResponseWithKnownContent() throws Exception
|
||||
{
|
||||
ByteBuffer header=BufferUtil.allocate(4096);
|
||||
ByteBuffer buffer=BufferUtil.allocate(16);
|
||||
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();
|
||||
|
||||
gen.setVersion(HttpVersion.HTTP_1_1);
|
||||
gen.setResponse(200,null);
|
||||
fields.add("Last-Modified",HttpFields.__01Jan1970);
|
||||
fields.add("Content-Length","59");
|
||||
gen.setContentLength(59);
|
||||
|
||||
HttpGenerator.Result
|
||||
|
||||
result=gen.prepareContent(null,null,content0);
|
||||
assertEquals(HttpGenerator.Result.NEED_BUFFER,result);
|
||||
assertEquals(HttpGenerator.State.START,gen.getState());
|
||||
|
||||
result=gen.prepareContent(null,buffer,content0);
|
||||
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());
|
||||
assertEquals("Hello World! The",BufferUtil.toString(buffer));
|
||||
assertEquals(43,content1.remaining());
|
||||
|
||||
result=gen.commit(fields,header,buffer,content1,false);
|
||||
assertEquals(HttpGenerator.Result.FLUSH,result);
|
||||
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
|
||||
assertEquals("Hello World! The",BufferUtil.toString(buffer));
|
||||
assertEquals(43,content1.remaining());
|
||||
assertTrue(!gen.isChunking());
|
||||
|
||||
String head = BufferUtil.toString(header);
|
||||
BufferUtil.clear(header);
|
||||
String body = BufferUtil.toString(buffer);
|
||||
BufferUtil.clear(buffer);
|
||||
|
||||
result=gen.prepareContent(null,buffer,content1);
|
||||
assertEquals(HttpGenerator.Result.FLUSH,result);
|
||||
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
|
||||
assertEquals(" quick brown fox",BufferUtil.toString(buffer));
|
||||
assertEquals(27,content1.remaining());
|
||||
body += BufferUtil.toString(buffer);
|
||||
BufferUtil.clear(buffer);
|
||||
|
||||
result=gen.prepareContent(null,buffer,content1);
|
||||
assertEquals(HttpGenerator.Result.FLUSH,result);
|
||||
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
|
||||
assertEquals(" jumped over the",BufferUtil.toString(buffer));
|
||||
assertEquals(11,content1.remaining());
|
||||
body += BufferUtil.toString(buffer);
|
||||
BufferUtil.clear(buffer);
|
||||
|
||||
result=gen.prepareContent(null,buffer,content1);
|
||||
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);
|
||||
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);
|
||||
assertEquals(HttpGenerator.Result.OK,result);
|
||||
assertEquals(HttpGenerator.State.END,gen.getState());
|
||||
assertEquals(0,buffer.remaining());
|
||||
|
||||
assertEquals(59,gen.getContentWritten());
|
||||
|
||||
// System.err.println(head+body);
|
||||
|
||||
assertThat(head,containsString("HTTP/1.1 200 OK"));
|
||||
assertThat(head,containsString("Last-Modified: Thu, 01 Jan 1970 00?00?00 GMT"));
|
||||
assertThat(head,containsString("Content-Length: 59"));
|
||||
assertThat(head,not(containsString("chunked")));
|
||||
assertTrue(head.endsWith("\r\n\r\n"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResponseWithKnownLargeContent() throws Exception
|
||||
{
|
||||
ByteBuffer header=BufferUtil.allocate(4096);
|
||||
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();
|
||||
gen.setLargeContent(8);
|
||||
|
||||
gen.setVersion(HttpVersion.HTTP_1_1);
|
||||
gen.setResponse(200,null);
|
||||
fields.add("Last-Modified",HttpFields.__01Jan1970);
|
||||
fields.add("Content-Length","59");
|
||||
gen.setContentLength(59);
|
||||
|
||||
HttpGenerator.Result
|
||||
|
||||
result=gen.prepareContent(null,null,content0);
|
||||
assertEquals(HttpGenerator.Result.NEED_COMMIT,result);
|
||||
assertEquals(HttpGenerator.State.START,gen.getState());
|
||||
|
||||
result=gen.commit(fields,header,null,content0,false);
|
||||
assertEquals(HttpGenerator.Result.FLUSH_CONTENT,result);
|
||||
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
|
||||
assertTrue(!gen.isChunking());
|
||||
|
||||
String head = BufferUtil.toString(header);
|
||||
BufferUtil.clear(header);
|
||||
String body = BufferUtil.toString(content0);
|
||||
BufferUtil.clear(content0);
|
||||
|
||||
result=gen.commit(fields,header,null,null,false);
|
||||
assertEquals(HttpGenerator.Result.OK,result);
|
||||
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
|
||||
|
||||
result=gen.prepareContent(null,null,content1);
|
||||
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);
|
||||
|
||||
|
||||
assertTrue(out.indexOf("GET /index.html HTTP/1.1")==0);
|
||||
assertTrue(out.indexOf("Content-Length")==-1);
|
||||
|
||||
assertEquals(HttpGenerator.State.END,gen.getState());
|
||||
assertEquals(0,gen.getContentWritten());
|
||||
|
||||
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);
|
||||
|
||||
assertThat(head,containsString("HTTP/1.1 200 OK"));
|
||||
assertThat(head,containsString("Last-Modified: Thu, 01 Jan 1970 00?00?00 GMT"));
|
||||
assertThat(head,containsString("Content-Length: 59"));
|
||||
assertThat(head,not(containsString("chunked")));
|
||||
assertTrue(head.endsWith("\r\n\r\n"));
|
||||
}
|
||||
|
||||
|
||||
|
@ -122,14 +470,10 @@ public class HttpGeneratorTest
|
|||
@Test
|
||||
public void testHTTP() throws Exception
|
||||
{
|
||||
ByteBuffer bb=new ByteArrayBuffer(8096);
|
||||
ByteBuffer sb=new ByteArrayBuffer(1500);
|
||||
HttpFields fields = new HttpFields();
|
||||
ByteArrayEndPoint endp = new ByteArrayEndPoint(new byte[0],4096);
|
||||
HttpGenerator hb = new HttpGenerator(new SimpleBuffers(sb,bb),endp);
|
||||
Handler handler = new Handler();
|
||||
HttpParser parser=null;
|
||||
|
||||
HttpGenerator gen = new HttpGenerator();
|
||||
// Handler handler = new Handler();
|
||||
// HttpParser parser=null;
|
||||
|
||||
|
||||
// For HTTP version
|
||||
|
@ -147,22 +491,22 @@ public class HttpGeneratorTest
|
|||
String t="v="+v+",r="+r+",chunks="+chunks+",connect="+c+",tr="+tr[r];
|
||||
// System.err.println(t);
|
||||
|
||||
hb.reset();
|
||||
endp.reset();
|
||||
gen.reset();
|
||||
fields.clear();
|
||||
|
||||
tr[r].build(v,hb,"OK\r\nTest",connect[c],null,chunks, fields);
|
||||
String response=endp.getOut().toString();
|
||||
//System.out.println("RESPONSE: "+t+"\n"+response+(hb.isPersistent()?"...\n":"---\n"));
|
||||
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"));
|
||||
|
||||
if (v==9)
|
||||
{
|
||||
assertFalse(t,hb.isPersistent());
|
||||
assertFalse(t,gen.isPersistent());
|
||||
if (tr[r]._body!=null)
|
||||
assertEquals(t,tr[r]._body, response);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
parser=new HttpParser(new ByteArrayBuffer(response.getBytes()), handler);
|
||||
parser.setHeadResponse(tr[r]._head);
|
||||
|
||||
|
@ -192,6 +536,7 @@ public class HttpGeneratorTest
|
|||
assertTrue(t,tr[r]._body==null);
|
||||
else
|
||||
assertTrue(t,tr[r]._contentLength==null || content.length()==Integer.parseInt(tr[r]._contentLength));
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -220,58 +565,210 @@ public class HttpGeneratorTest
|
|||
_head=head;
|
||||
}
|
||||
|
||||
private void build(int version,HttpGenerator hb,String reason, String connection, String te, int chunks, HttpFields fields) throws Exception
|
||||
private String build(int version,HttpGenerator gen,String reason, String connection, String te, int chunks, HttpFields fields) throws Exception
|
||||
{
|
||||
String response="";
|
||||
_connection=connection;
|
||||
_te=te;
|
||||
hb.setVersion(version);
|
||||
hb.setResponse(_code,reason);
|
||||
hb.setHead(_head);
|
||||
gen.setVersion(HttpVersion.fromVersion(version));
|
||||
gen.setResponse(_code,reason);
|
||||
gen.setHead(_head);
|
||||
|
||||
if (_contentType!=null)
|
||||
fields.put(new ByteArrayBuffer("Content-Type"),new ByteArrayBuffer(_contentType));
|
||||
fields.put("Content-Type",_contentType);
|
||||
if (_contentLength!=null)
|
||||
fields.put(new ByteArrayBuffer("Content-Length"),new ByteArrayBuffer(_contentLength));
|
||||
{
|
||||
fields.put("Content-Length",_contentLength);
|
||||
gen.setContentLength(Long.parseLong(_contentLength));
|
||||
}
|
||||
if (_connection!=null)
|
||||
fields.put(new ByteArrayBuffer("Connection"),new ByteArrayBuffer(_connection));
|
||||
fields.put("Connection",_connection);
|
||||
if (_te!=null)
|
||||
fields.put(new ByteArrayBuffer("Transfer-Encoding"),new ByteArrayBuffer(_te));
|
||||
fields.put("Transfer-Encoding",_te);
|
||||
if (_other!=null)
|
||||
fields.put(new ByteArrayBuffer("Other"),new ByteArrayBuffer(_other));
|
||||
fields.put("Other",_other);
|
||||
|
||||
if (_body!=null)
|
||||
ByteBuffer content=_body==null?null:BufferUtil.toBuffer(_body);
|
||||
if (content!=null)
|
||||
content.limit(0);
|
||||
ByteBuffer chunk=null;
|
||||
ByteBuffer buffer=null;
|
||||
|
||||
|
||||
mainLoop: while(true)
|
||||
{
|
||||
int inc=1+_body.length()/chunks;
|
||||
ByteBuffer buf=new ByteArrayBuffer(_body);
|
||||
View view = new View(buf);
|
||||
for (int i=1;i<chunks;i++)
|
||||
// if we have unwritten content
|
||||
if (content!=null && content.position()<content.capacity())
|
||||
{
|
||||
view.setPutIndex(i*inc);
|
||||
view.setGetIndex((i-1)*inc);
|
||||
hb.addContent(view,Generator.MORE);
|
||||
if (hb.isBufferFull() && hb.isState(AbstractGenerator.STATE_HEADER))
|
||||
hb.completeHeader(fields, Generator.MORE);
|
||||
if (i%2==0)
|
||||
// if we need a new chunk
|
||||
if (content.remaining()==0)
|
||||
{
|
||||
if (hb.isState(AbstractGenerator.STATE_HEADER))
|
||||
hb.completeHeader(fields, Generator.MORE);
|
||||
hb.flushBuffer();
|
||||
}
|
||||
}
|
||||
view.setPutIndex(buf.putIndex());
|
||||
view.setGetIndex((chunks-1)*inc);
|
||||
hb.addContent(view,Generator.LAST);
|
||||
if(hb.isState(AbstractGenerator.STATE_HEADER))
|
||||
hb.completeHeader(fields, Generator.LAST);
|
||||
}
|
||||
if (chunks-->1)
|
||||
content.limit(content.position()+content.remaining()/2);
|
||||
else
|
||||
{
|
||||
hb.completeHeader(fields, Generator.LAST);
|
||||
content.limit(content.capacity());
|
||||
}
|
||||
hb.complete();
|
||||
|
||||
while(!hb.isComplete())
|
||||
hb.flushBuffer();
|
||||
|
||||
switch(gen.getState())
|
||||
{
|
||||
case START:
|
||||
case COMPLETING_UNCOMMITTED:
|
||||
case COMMITTED:
|
||||
case COMPLETING:
|
||||
case END:
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
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(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 mainLoop;
|
||||
|
||||
default:
|
||||
throw new IllegalStateException(gen.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -34,13 +34,6 @@ public class BufferUtil
|
|||
(byte)'E', (byte)'F' };
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public static void clear(ByteBuffer buffer)
|
||||
{
|
||||
buffer.position(0);
|
||||
buffer.limit(0);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Allocate ByteBuffer in output mode.
|
||||
* The position and limit will both be zero, indicating that the buffer is
|
||||
|
@ -70,10 +63,25 @@ public class BufferUtil
|
|||
}
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public static void clear(ByteBuffer buffer)
|
||||
{
|
||||
buffer.position(0);
|
||||
buffer.limit(0);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public static void clearToFill(ByteBuffer buffer)
|
||||
{
|
||||
buffer.position(0);
|
||||
buffer.limit(buffer.capacity());
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public static void flipToFill(ByteBuffer buffer)
|
||||
{
|
||||
buffer.position(buffer.limit());
|
||||
buffer.position(buffer.hasRemaining()?buffer.limit():0);
|
||||
buffer.limit(buffer.capacity());
|
||||
}
|
||||
|
||||
|
@ -128,7 +136,7 @@ public class BufferUtil
|
|||
/**
|
||||
* Put data from one buffer into another, avoiding over/under flows
|
||||
* @param from Buffer to take bytes from
|
||||
* @param to Buffer to put bytes to
|
||||
* @param to Buffer to put bytes to. The buffer is flipped before and after the put.
|
||||
* @return number of bytes moved
|
||||
*/
|
||||
public static int put(ByteBuffer from, ByteBuffer to, long maxBytes)
|
||||
|
@ -141,7 +149,7 @@ public class BufferUtil
|
|||
/**
|
||||
* Put data from one buffer into another, avoiding over/under flows
|
||||
* @param from Buffer to take bytes from
|
||||
* @param to Buffer to put bytes to
|
||||
* @param to Buffer to put bytes to. The buffer is flipped before and after the put.
|
||||
* @return number of bytes moved
|
||||
*/
|
||||
public static int put(ByteBuffer from, ByteBuffer to, int maxBytes)
|
||||
|
@ -191,7 +199,7 @@ public class BufferUtil
|
|||
/**
|
||||
* Put data from one buffer into another, avoiding over/under flows
|
||||
* @param from Buffer to take bytes from
|
||||
* @param to Buffer to put bytes to
|
||||
* @param to Buffer to put bytes to. The buffer is flipped before and after the put.
|
||||
* @return number of bytes moved
|
||||
*/
|
||||
public static int put(ByteBuffer from, ByteBuffer to)
|
||||
|
|
Loading…
Reference in New Issue