jetty-9 work in progress

This commit is contained in:
Greg Wilkins 2012-03-07 17:26:33 +11:00
parent a4bee5b12d
commit 3d12ef7075
6 changed files with 1518 additions and 879 deletions

View File

@ -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));
}

View File

@ -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();
}
}
}

View File

@ -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);
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);
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();
generator.addContent(new ByteArrayBuffer(content),true);
generator.flushBuffer();
generator.complete();
generator.flushBuffer();
gen.setVersion(HttpVersion.HTTP_1_1);
gen.setRequest("POST","/index.html");
fields.add("Host","something");
fields.add("User-Agent","test");
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);
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
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());
generator.flushBuffer();
generator.complete();
generator.flushBuffer();
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 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);
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
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);
generator.addContent(new ByteArrayBuffer(content),false);
generator.flushBuffer();
generator.complete();
generator.flushBuffer();
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());
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);
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);
HttpGenerator.Result
result=gen.prepareContent(null,null,content0);
assertEquals(HttpGenerator.Result.NEED_COMMIT,result);
assertEquals(HttpGenerator.State.START,gen.getState());
hb.reset();
endp.reset();
fields.clear();
result=gen.commit(fields,header,null,content0,false);
assertEquals(HttpGenerator.Result.FLUSH_CONTENT,result);
assertEquals(HttpGenerator.State.COMMITTED,gen.getState());
assertTrue(!gen.isChunking());
// System.out.println("TEST: "+t);
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);
assertEquals(HttpGenerator.State.END,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.complete(null,null);
assertEquals(HttpGenerator.Result.OK,result);
assertEquals(HttpGenerator.State.END,gen.getState());
assertEquals(59,gen.getContentWritten());
// System.err.println(head+body);
assertTrue(t,hb.isPersistent());
if (v==9)
{
assertEquals(t,"GET /context/path/info\r\n", request);
continue;
}
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)
{
}
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"));
}
}

View File

@ -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,86 +57,425 @@ 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);
result=gen.commit(fields,header,null,null,true);
assertEquals(HttpGenerator.Result.NEED_COMPLETE,result);
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());
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"));
}
@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);
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("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 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
for (int v=9;v<=11;v++)
{
@ -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));
if (_connection!=null)
fields.put(new ByteArrayBuffer("Connection"),new ByteArrayBuffer(_connection));
if (_te!=null)
fields.put(new ByteArrayBuffer("Transfer-Encoding"),new ByteArrayBuffer(_te));
if (_other!=null)
fields.put(new ByteArrayBuffer("Other"),new ByteArrayBuffer(_other));
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++)
fields.put("Content-Length",_contentLength);
gen.setContentLength(Long.parseLong(_contentLength));
}
if (_connection!=null)
fields.put("Connection",_connection);
if (_te!=null)
fields.put("Transfer-Encoding",_te);
if (_other!=null)
fields.put("Other",_other);
ByteBuffer content=_body==null?null:BufferUtil.toBuffer(_body);
if (content!=null)
content.limit(0);
ByteBuffer chunk=null;
ByteBuffer buffer=null;
mainLoop: while(true)
{
// 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();
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:
}
}
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());
}
}
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();
return response;
}
@Override

View File

@ -33,13 +33,6 @@ public class BufferUtil
{ (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'A', (byte)'B', (byte)'C', (byte)'D',
(byte)'E', (byte)'F' };
/* ------------------------------------------------------------ */
public static void clear(ByteBuffer buffer)
{
buffer.position(0);
buffer.limit(0);
}
/* ------------------------------------------------------------ */
/** Allocate ByteBuffer in output mode.
@ -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)