// ======================================================================== // Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd. // ------------------------------------------------------------------------ // All rights reserved. This program and the accompanying materials // are made available under the terms of the Eclipse Public License v1.0 // and Apache License v2.0 which accompanies this distribution. // The Eclipse Public License is available at // http://www.eclipse.org/legal/epl-v10.html // The Apache License v2.0 is available at // http://www.opensource.org/licenses/apache2.0.php // You may elect to redistribute this code under either of these licenses. // ======================================================================== package org.eclipse.jetty.http; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.io.IOException; import org.eclipse.jetty.io.Buffer; import org.eclipse.jetty.io.ByteArrayBuffer; import org.eclipse.jetty.io.ByteArrayEndPoint; import org.eclipse.jetty.io.SimpleBuffers; import org.eclipse.jetty.io.View; import org.junit.Test; /** * * * To change the template for this generated type comment go to * Window - Preferences - Java - Code Generation - Code and Comments */ 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 { Buffer bb=new ByteArrayBuffer(8096); Buffer sb=new ByteArrayBuffer(1500); HttpFields fields = new HttpFields(); ByteArrayEndPoint endp = new ByteArrayEndPoint(new byte[0],4096); HttpGenerator hg = new HttpGenerator(new SimpleBuffers(sb,bb),endp); fields.add("Host","something"); fields.add("User-Agent","test"); hg.setRequest("GET","/index.html"); hg.setVersion(11); hg.completeHeader(fields,true); hg.complete(); assertTrue(endp.getOut().toString().indexOf("GET /index.html HTTP/1.1")==0); assertTrue(endp.getOut().toString().indexOf("Content-Length")==-1); } @Test public void testHTTP() throws Exception { Buffer bb=new ByteArrayBuffer(8096); Buffer 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; // 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<(v==11?connect.length:(connect.length-1));c++) { String t="v="+v+",r="+r+",chunks="+chunks+",connect="+c+",tr="+tr[r]; // System.err.println(t); hb.reset(); endp.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")); if (v==9) { assertFalse(t,hb.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); try { parser.parse(); } catch(IOException e) { if (tr[r]._body!=null) throw new Exception(t,e); continue; } if (tr[r]._body!=null) assertEquals(t,tr[r]._body, this.content); if (v==10) assertTrue(t,hb.isPersistent() || tr[r]._contentLength==null || c==2 || c==0); else assertTrue(t,hb.isPersistent() || c==2 || c==3); if (v>9) assertEquals("OK Test",f2); if (content==null) assertTrue(t,tr[r]._body==null); else assertTrue(t,tr[r]._contentLength==null || content.length()==Integer.parseInt(tr[r]._contentLength)); } } } } } private static final String[] headers= { "Content-Type","Content-Length","Connection","Transfer-Encoding","Other"}; private static class TR { private int _code; private String _body; private boolean _head; String _contentType; String _contentLength; String _connection; String _te; String _other; private TR(int code,String contentType, String contentLength ,String content,boolean head) { _code=code; _contentType=contentType; _contentLength=contentLength; _other="value"; _body=content; _head=head; } private void build(int version,HttpGenerator hb,String reason, String connection, String te, int chunks, HttpFields fields) throws Exception { _connection=connection; _te=te; hb.setVersion(version); hb.setResponse(_code,reason); hb.setHead(_head); if (_contentType!=null) fields.put(new ByteArrayBuffer("Content-Type"),new ByteArrayBuffer(_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; Buffer 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)) 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 "["+_code+","+_contentType+","+_contentLength+","+(_body==null?"null":"content")+"]"; } } private final TR[] tr = { /* 0 */ new TR(200,null,null,null,false), /* 1 */ new TR(200,null,null,CONTENT,false), /* 2 */ new TR(200,null,""+CONTENT.length(),null,true), /* 3 */ new TR(200,null,""+CONTENT.length(),CONTENT,false), /* 4 */ new TR(200,"text/html",null,null,true), /* 5 */ new TR(200,"text/html",null,CONTENT,false), /* 6 */ new TR(200,"text/html",""+CONTENT.length(),null,true), /* 7 */ new TR(200,"text/html",""+CONTENT.length(),CONTENT,false), }; 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(Buffer ref) { if (index == 0) content= ""; content= content.substring(0, index) + ref; index+=ref.length(); } @Override public void startRequest(Buffer tok0, Buffer tok1, Buffer 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(Buffer version, int status, Buffer 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(Buffer name,Buffer value) { hdr[++h]= name.toString(); val[h]= value.toString(); } @Override public void headerComplete() { content= null; } @Override public void messageComplete(long contentLength) { } } }