Completed the split test.

Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
This commit is contained in:
Lachlan Roberts 2018-03-14 14:27:03 +11:00
parent 20c9fb45f8
commit 4dce09c067
2 changed files with 195 additions and 8 deletions

View File

@ -175,6 +175,14 @@ public class MultiPartParser
_delimiterSearch = SearchPattern.compile(_patternBuffer.array());
}
public void reset()
{
_state = State.PREAMBLE;
_fieldState = FieldState.FIELD;
_partialBoundary = 2; // No CRLF if no preamble
}
/* ------------------------------------------------------------------------------- */
public Handler getHandler()
{
@ -346,16 +354,20 @@ public class MultiPartParser
}
}
if(last && _state == State.EPILOGUE)
if(last)
{
if(_state == State.EPILOGUE)
{
_state = State.END;
_handler.messageComplete();
return _handler.messageComplete();
}
else
else if(BufferUtil.isEmpty(buffer))
{
_handler.earlyEOF();
return true;
}
}
return handle;
}

View File

@ -28,6 +28,7 @@ import java.util.List;
import org.eclipse.jetty.http.MultiPartParser.State;
import org.eclipse.jetty.util.BufferUtil;
import org.hamcrest.Matchers;
import org.junit.Ignore;
import org.junit.Test;
public class MultiPartParserTest
@ -320,6 +321,32 @@ public class MultiPartParserTest
+ "The quick brown fox jumped over the lazy dog.\r\n","<<LAST>>"));
}
@Test
public void testFirstPartLongContentNoCarriageReturn()
{
TestHandler handler = new TestHandler();
MultiPartParser parser = new MultiPartParser(handler,"BOUNDARY");
ByteBuffer data = BufferUtil.toBuffer("");
//boundary still requires carriage return
data = BufferUtil.toBuffer("--BOUNDARY\n"
+ "name: value\n"
+ "\n"
+ "Now is the time for all good men to come to the aid of the party.\n"
+ "How now brown cow.\n"
+ "The quick brown fox jumped over the lazy dog.\n"
+ "\r\n"
+ "--BOUNDARY");
parser.parse(data,false);
assertThat(parser.getState(), is(State.DELIMITER));
assertThat(data.remaining(),is(0));
assertThat(handler.fields,Matchers.contains("name: value", "<<COMPLETE>>"));
assertThat(handler.content,Matchers.contains("Now is the time for all good men to come to the aid of the party.\n"
+ "How now brown cow.\n"
+ "The quick brown fox jumped over the lazy dog.\n","<<LAST>>"));
}
@Test
public void testEpilogue() {
@ -396,6 +423,141 @@ public class MultiPartParserTest
assertThat(data.remaining(),is(0));
}
@Test
public void splitTest()
{
TestHandler handler = new TestHandler()
{
@Override
public boolean messageComplete()
{
return true;
}
@Override
public boolean content(ByteBuffer buffer, boolean last)
{
super.content(buffer,last);
return false;
}
};
MultiPartParser parser = new MultiPartParser(handler,"---------------------------9051914041544843365972754266");
ByteBuffer data = BufferUtil.toBuffer(""+
"POST / HTTP/1.1\n" +
"Host: localhost:8000\n" +
"User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:29.0) Gecko/20100101 Firefox/29.0\n" +
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\n" +
"Accept-Language: en-US,en;q=0.5\n" +
"Accept-Encoding: gzip, deflate\n" +
"Cookie: __atuvc=34%7C7; permanent=0; _gitlab_session=226ad8a0be43681acf38c2fab9497240; __profilin=p%3Dt; request_method=GET\n" +
"Connection: keep-alive\n" +
"Content-Type: multipart/form-data; boundary=---------------------------9051914041544843365972754266\n" +
"Content-Length: 554\n" +
"\r\n" +
"-----------------------------9051914041544843365972754266\n" +
"Content-Disposition: form-data; name=\"text\"\n" +
"\n" +
"text default\r\n" +
"-----------------------------9051914041544843365972754266\n" +
"Content-Disposition: form-data; name=\"file1\"; filename=\"a.txt\"\n" +
"Content-Type: text/plain\n" +
"\n" +
"Content of a.txt.\n" +
"\r\n" +
"-----------------------------9051914041544843365972754266\n" +
"Content-Disposition: form-data; name=\"file2\"; filename=\"a.html\"\n" +
"Content-Type: text/html\n" +
"\n" +
"<!DOCTYPE html><title>Content of a.html.</title>\n" +
"\r\n" +
"-----------------------------9051914041544843365972754266\n" +
"Field1: value1\n" +
"Field2: value2\n" +
"Field3: value3\n" +
"Field4: value4\n" +
"Field5: value5\n" +
"Field6: value6\n" +
"Field7: value7\n" +
"Field8: value8\n" +
"Field9: value\n" +
" 9\n" +
"\r\n" +
"-----------------------------9051914041544843365972754266\n" +
"Field1: value1\n" +
"\r\n"+
"But the amount of denudation which the strata have\n" +
"in many places suffered, independently of the rate\n" +
"of accumulation of the degraded matter, probably\n" +
"offers the best evidence of the lapse of time. I remember\n" +
"having been much struck with the evidence of\n" +
"denudation, when viewing volcanic islands, which\n" +
"have been worn by the waves and pared all round\n" +
"into perpendicular cliffs of one or two thousand feet\n" +
"in height; for the gentle slope of the lava-streams,\n" +
"due to their formerly liquid state, showed at a glance\n" +
"how far the hard, rocky beds had once extended into\n" +
"the open ocean.\n" +
"\r\n" +
"-----------------------------9051914041544843365972754266--" +
"===== ajlkfja;lkdj;lakjd;lkjf ==== epilogue here ==== kajflajdfl;kjafl;kjl;dkfja ====\n\r\n\r\r\r\n\n\n");
int length = data.remaining();
for(int i = 0; i<length; i++){
//partition 0 to i
ByteBuffer dataSeg = data.slice();
dataSeg.position(0);
dataSeg.limit(i);
assertThat("First "+i,parser.parse(dataSeg,false),is(false));
//partition i
dataSeg = data.slice();
dataSeg.position(i);
dataSeg.limit(i+1);
assertThat("Second "+i,parser.parse(dataSeg,false),is(false));
//partition i to length
dataSeg = data.slice();
dataSeg.position(i+1);
dataSeg.limit(length);
assertThat("Third "+i,parser.parse(dataSeg,true),is(true));
assertThat(handler.fields, Matchers.contains( "Content-Disposition: form-data; name=\"text\"","<<COMPLETE>>"
, "Content-Disposition: form-data; name=\"file1\"; filename=\"a.txt\""
, "Content-Type: text/plain","<<COMPLETE>>"
, "Content-Disposition: form-data; name=\"file2\"; filename=\"a.html\""
, "Content-Type: text/html","<<COMPLETE>>"
, "Field1: value1", "Field2: value2", "Field3: value3"
, "Field4: value4", "Field5: value5", "Field6: value6"
, "Field7: value7", "Field8: value8", "Field9: value 9", "<<COMPLETE>>"
, "Field1: value1","<<COMPLETE>>"));
System.out.println("iteration "+i);
System.out.println(handler.content);
assertThat(handler.contentString(), is(new String("text default"+"<<LAST>>"
+ "Content of a.txt.\n"+"<<LAST>>"
+ "<!DOCTYPE html><title>Content of a.html.</title>\n"+"<<LAST>>"
+ "<<LAST>>"
+ "But the amount of denudation which the strata have\n" +
"in many places suffered, independently of the rate\n" +
"of accumulation of the degraded matter, probably\n" +
"offers the best evidence of the lapse of time. I remember\n" +
"having been much struck with the evidence of\n" +
"denudation, when viewing volcanic islands, which\n" +
"have been worn by the waves and pared all round\n" +
"into perpendicular cliffs of one or two thousand feet\n" +
"in height; for the gentle slope of the lava-streams,\n" +
"due to their formerly liquid state, showed at a glance\n" +
"how far the hard, rocky beds had once extended into\n" +
"the open ocean.\n"+ "<<LAST>>")));
handler.clear();
parser.reset();
}
}
static class TestHandler implements MultiPartParser.Handler
{
@ -408,6 +570,13 @@ public class MultiPartParserTest
fields.add(name+": "+value);
}
public String contentString()
{
StringBuilder sb = new StringBuilder();
for(String s : content) sb.append(s);
return sb.toString();
}
@Override
public boolean headerComplete()
{
@ -424,6 +593,12 @@ public class MultiPartParserTest
content.add("<<LAST>>");
return last;
}
public void clear() {
fields.clear();
content.clear();
}
}
}