Some more progress in multipart

This commit is contained in:
Ziver Koc 2016-07-11 18:05:21 +02:00
parent a700cf2863
commit e4a5af69db
5 changed files with 153 additions and 69 deletions

View file

@ -29,25 +29,28 @@ import java.io.IOException;
import java.io.InputStream;
/**
* TODO: boundry
* A stream that is handled as a iterator. The stream will read
* until it gets to a boundary and will return -1 (end of stream).
* The stream will not return any data until the {@link #next()}
* method is called.
*
* @author Ziver
*
*/
public class BufferedBoundaryInputStream extends FilterInputStream{
/** The size of the buffer in bytes */
public static final int DEFAULT_BUF_SIZE = 8192;
private static final int DEFAULT_BUF_SIZE = 8192;
/** The raw buffer */
protected byte buffer[];
/** The end position of the buffer */
protected int buf_end = 0;
private byte buffer[];
/** The current position in the buffer */
protected int buf_pos = 0;
/** The boundary (the delimiter) */
protected byte[] boundary;
private int buf_pos = 0;
/** The end position of the buffer */
private int buf_end = 0;
/** Boundary position, 0< means no boundary found */
protected int bound_pos;
private int buf_bound_pos;
/** The boundary (the delimiter) */
private byte[] boundary;
/**
@ -67,10 +70,10 @@ public class BufferedBoundaryInputStream extends FilterInputStream{
*/
public BufferedBoundaryInputStream(InputStream in, int buf_size){
super(in);
buf_end = 0;
buf_pos = 0;
buf_end = 0;
buf_bound_pos = -1;
buffer = new byte[buf_size];
bound_pos = -1;
}
/**
@ -109,7 +112,7 @@ public class BufferedBoundaryInputStream extends FilterInputStream{
return -1; // EOF
}
if(bound_pos == buf_pos)
if(buf_bound_pos == buf_pos)
return -1; // boundary
return buffer[buf_pos++];
}
@ -137,7 +140,7 @@ public class BufferedBoundaryInputStream extends FilterInputStream{
if(fillBuffer() <= 0)
return -1; // EOF
}
if(bound_pos == buf_pos)
if(buf_bound_pos == buf_pos)
return -1; // boundary
// The request is larger then the buffer size
@ -146,8 +149,8 @@ public class BufferedBoundaryInputStream extends FilterInputStream{
len = leftover;
}
// the boundary is in the read range
if(buf_pos < bound_pos && bound_pos < buf_pos+len){
len = buf_pos - bound_pos;
if(buf_pos < buf_bound_pos && buf_bound_pos < buf_pos+len){
len = buf_bound_pos - buf_pos;
}
System.arraycopy(buffer, buf_pos, b, off, len);
@ -155,11 +158,19 @@ public class BufferedBoundaryInputStream extends FilterInputStream{
return len;
}
/**
* @return if there is more data to read
*/
public boolean isOnBoundary(){
return buf_bound_pos == buf_pos;
}
/**
* Skips over the boundary at the current position in the buffer
*/
public boolean next(){
if(bound_pos == buf_pos){
if(buf_bound_pos == buf_pos){
buf_pos += boundary.length;
searchNextBoundary();
return buf_end >= buf_pos;
@ -173,15 +184,15 @@ public class BufferedBoundaryInputStream extends FilterInputStream{
protected void searchNextBoundary(){
for(int i=buf_pos; i<buf_end; i++){
for(int b=0; b < boundary.length; b++){
if(buffer[i] != boundary[b])
if(buffer[i+b] != boundary[b])
break;
else if(b == boundary.length-1){
bound_pos = i;
buf_bound_pos = i;
return;
}
}
}
bound_pos = -1;
buf_bound_pos = -1;
}
/**
@ -216,13 +227,6 @@ public class BufferedBoundaryInputStream extends FilterInputStream{
System.arraycopy(b, 0, boundary, 0, b.length);
}
/**
* @return if there is more data to read
*/
public boolean isOnBoundary(){
return bound_pos == buf_pos;
}
/**
* @return an estimate of the number of bytes that can be read (or skipped
* over) from this buffered input stream without blocking.

View file

@ -75,7 +75,7 @@ public class IOUtil {
StringBuilder str = new StringBuilder();
BufferedReader in = null;
if(reader instanceof BufferedReader)
reader = (BufferedReader) reader;
in = (BufferedReader) reader;
else
in = new BufferedReader(reader);

View file

@ -120,7 +120,7 @@ public class MultipartParser implements Iterable<MultipartField>{
public boolean hasNext() {
try {
IOUtil.copyStream(buffIn, new NullWriter());
return boundaryIn.next();
return boundaryIn.isOnBoundary();
} catch (IOException e){
logger.log(Level.SEVERE, null, e);
}
@ -130,14 +130,13 @@ public class MultipartParser implements Iterable<MultipartField>{
@Override
public MultipartField next() {
if (!hasNext())
return null;
try {
HttpHeader header = parser.read();
boundaryIn.next();
String tmp = buffIn.readLine(); // read the new line after the delimiter
if (tmp == null && tmp.equals("--"))
if (tmp == null || tmp.equals("--"))
return null;
HttpHeader header = parser.read();
String disposition = header.getHeader(HEADER_CONTENT_DISPOSITION);
if (disposition != null){
HashMap<String,String> map = new HashMap<>();

View file

@ -17,7 +17,7 @@ public class MultipartStringField implements MultipartField {
protected MultipartStringField(Map<String,String> header, BufferedReader in) throws IOException {
this.name = header.get("name");
value = IOUtil.getContentAsString(in);
value = in.readLine();
}
@Override

View file

@ -29,6 +29,7 @@ import org.junit.Test;
import java.io.IOException;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@ -36,51 +37,117 @@ import static org.junit.Assert.assertTrue;
public class BufferedBoundaryInputStreamTest {
@Test
public void normal() throws IOException {
StringInputStream inin = new StringInputStream("aaa#aaaaaaaaaaaaaaaa#aaaaaaaaaaaaaaa#");
public void read_normal() throws IOException {
StringInputStream inin = new StringInputStream("aaa#a##aaaaaaa#");
BufferedBoundaryInputStream in = new BufferedBoundaryInputStream(inin);
in.setBoundary("#");
int n = 0;
for(n=0; in.read() != -1; n++);
assertEquals(3, n);
assertEquals('a', in.read());
assertEquals('a', in.read());
assertEquals('a', in.read());
assertEquals(-1, in.read());
assertTrue(in.isOnBoundary());
in.next();
n = 0;
for(n=0; in.read() != -1; n++);
assertEquals(16, n);
in.next();
n = 0;
for(n=0; in.read() != -1; n++);
assertEquals(15, n);
assertEquals('a', in.read());
assertEquals(-1, in.read());
assertTrue(in.isOnBoundary());
in.next();
assertEquals(-1, in.read());
assertTrue(in.isOnBoundary());
in.next();
assertEquals('a', in.read());
assertEquals('a', in.read());
assertEquals('a', in.read());
assertEquals('a', in.read());
assertEquals('a', in.read());
assertEquals('a', in.read());
assertEquals('a', in.read());
assertEquals(-1, in.read());
assertTrue(in.isOnBoundary());
in.next();
assertEquals(-1, in.read());
assertFalse(in.isOnBoundary());
}
@Test
public void readArr_normal() throws IOException {
StringInputStream inin = new StringInputStream("aaa#aaaaaaaaaaaaaaaa#aaaaaaaaaaaaaaa#");
BufferedBoundaryInputStream in = new BufferedBoundaryInputStream(inin);
in.setBoundary("#");
byte[] buff = new byte[100];
int n = in.read(buff);
assertEquals(3, n);
in.next();
n = in.read(buff);
assertEquals(16, n);
in.next();
n = in.read(buff);
assertEquals(15, n);
in.next();
n = in.read(buff);
assertEquals(-1, n);
}
@Test
public void startWithBound() throws IOException {
public void read_multiCharBoundary() throws IOException {
StringInputStream inin = new StringInputStream("aaa1234");
BufferedBoundaryInputStream in = new BufferedBoundaryInputStream(inin);
in.setBoundary("1234");
byte[] buff = new byte[100];
assertEquals(3, in.read(buff));
assertEquals(-1, in.read());
assertTrue(in.isOnBoundary());
in.next();
assertEquals(-1, in.read(buff));
assertFalse(in.isOnBoundary());
}
@Test
public void readArr_multiCharBoundary() throws IOException {
StringInputStream inin = new StringInputStream("aaa1234");
BufferedBoundaryInputStream in = new BufferedBoundaryInputStream(inin);
in.setBoundary("1234");
assertEquals('a', in.read());
assertEquals('a', in.read());
assertEquals('a', in.read());
assertEquals(-1, in.read());
assertTrue(in.isOnBoundary());
in.next();
assertEquals(-1, in.read());
assertFalse(in.isOnBoundary());
}
@Test
public void read_startWithBound() throws IOException {
StringInputStream inin = new StringInputStream("#aaa");
BufferedBoundaryInputStream in = new BufferedBoundaryInputStream(inin);
in.setBoundary("#");
assertEquals(-1, in.read());
inin = new StringInputStream("#aaa");
in = new BufferedBoundaryInputStream(inin);
}
@Test
public void readArr_startWithBound() throws IOException {
StringInputStream inin = new StringInputStream("#aaa");
BufferedBoundaryInputStream in = new BufferedBoundaryInputStream(inin);
in.setBoundary("#");
assertEquals(-1, in.read(new byte[10], 0, 10));
}
@Test
public void onlyBoundaries() throws IOException {
public void read_onlyBoundaries() throws IOException {
StringInputStream inin = new StringInputStream("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
BufferedBoundaryInputStream in = new BufferedBoundaryInputStream(inin);
in.setBoundary("a");
int n;
@ -93,9 +160,26 @@ public class BufferedBoundaryInputStreamTest {
}
assertEquals(35, n);
}
@Test
public void readArr_onlyBoundaries() throws IOException {
StringInputStream inin = new StringInputStream("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
BufferedBoundaryInputStream in = new BufferedBoundaryInputStream(inin);
in.setBoundary("a");
byte[] buff = new byte[100];
int n;
for(n=1; true; n++){
assertEquals(-1, in.read(buff));
assertEquals(-1, in.read(buff));
in.next();
if(!in.isOnBoundary())
break;
}
assertEquals(35, n);
}
@Test
public void noBounds() throws IOException {
public void read_noBounds() throws IOException {
String data = "1234567891011121314151617181920";
StringInputStream inin = new StringInputStream(data);
BufferedBoundaryInputStream in = new BufferedBoundaryInputStream(inin);
@ -108,18 +192,15 @@ public class BufferedBoundaryInputStreamTest {
}
assertEquals(data, output.toString());
}
@Test
public void next() throws IOException {
StringInputStream inin = new StringInputStream("a#a#");
public void readArr_noBounds() throws IOException {
String data = "1234567891011121314151617181920";
StringInputStream inin = new StringInputStream(data);
BufferedBoundaryInputStream in = new BufferedBoundaryInputStream(inin);
in.setBoundary("#");
assertEquals('a', in.read());
assertEquals(-1, in.read());
assertEquals(true, in.next());
assertEquals('a', in.read());
assertEquals(-1, in.read());
assertEquals(false, in.next());
byte[] buff = new byte[100];
assertEquals(data.length(), in.read(buff));
assertEquals(data, new String(buff, 0, data.length()));
}
}