}
public boolean parseRequest() {
byte[] boundaryMarker = getBoundaryMarker(super.getContentType());
if (boundaryMarker == null) {
throw new FileUploadException("The request was rejected because "
+ "no multipart boundary was found");
}
encoding = getCharacterEncoding();
parameters = new HashMap<String, Param>();
int loopCounter = 20; // 20 attempts to read not-readable data
this.percentMap = getProgressData();
try {
byte[] buffer = new byte[BUFFER_SIZE];
Map<String, String> headers = new HashMap<String, String>();
ReadState readState = ReadState.BOUNDARY;
InputStream input = getInputStream();
if (!shouldStop) {
int read = input.read(buffer);
int pos = 0;
Param p = null;
while (read > 0 && loopCounter > 0) {
for (int i = 0; i < read; i++) {
switch (readState) {
case BOUNDARY: {
if (checkSequence(buffer, i, boundaryMarker)
&& checkSequence(buffer, i + 2, CR_LF)) {
readState = ReadState.HEADERS;
i += 2;
pos = i + 1;
}
break;
}
case HEADERS: {
if (checkSequence(buffer, i, CR_LF)) {
String param = (encoding == null) ? new String(
buffer, pos, i - pos - 1) : new String(
buffer, pos, i - pos - 1, encoding);
parseParams(param, "; ", headers);
if (checkSequence(buffer, i + CR_LF.length,
CR_LF)) {
readState = ReadState.DATA;
i += CR_LF.length;
pos = i + 1;
String paramName = headers.get(PARAM_NAME);
if (paramName != null) {
if (headers.containsKey(PARAM_FILENAME)) {
FileParam fp = new FileParam(
paramName);
if (createTempFiles)
fp.createTempFile();
fp.setContentType(headers
.get(PARAM_CONTENT_TYPE));
fp
.setFilename(decodeFileName(headers
.get(PARAM_FILENAME)));
p = fp;
} else {
if (parameters
.containsKey(paramName)) {
p = parameters.get(paramName);
} else {
p = new ValueParam(paramName);
}
}
if (!parameters.containsKey(paramName)) {
parameters.put(paramName, p);
}
}
headers.clear();
} else {
pos = i + 1;
}
}
break;
}
case DATA: {
// If we've encountered another boundary...
if (checkSequence(buffer, i - boundaryMarker.length
- CR_LF.length, CR_LF)
&& checkSequence(buffer, i, boundaryMarker)) {
// Write any data before the boundary (that
// hasn't
// already been written) to the param
if (pos < i - boundaryMarker.length
- CR_LF.length - 1) {
p.appendData(buffer, pos, i - pos
- boundaryMarker.length
- CR_LF.length - 1);
}
if (p instanceof ValueParam)
((ValueParam) p).complete();
if (checkSequence(buffer, i + CR_LF.length,
CR_LF)) {
i += CR_LF.length;
pos = i + 1;
} else {
pos = i;
}
readState = ReadState.HEADERS;
}
// Otherwise write whatever data we have to the
// param
else if (i > (pos + boundaryMarker.length
+ CHUNK_SIZE + CR_LF.length)) {
p.appendData(buffer, pos, CHUNK_SIZE);
pos += CHUNK_SIZE;
}
break;
}
}
}
if (!shouldStop) {
if (pos < read) {
// move the bytes that weren't read to the start of
// the
// buffer
int bytesNotRead = read - pos;
System.arraycopy(buffer, pos, buffer, 0,
bytesNotRead);
read = input.read(buffer, bytesNotRead,
buffer.length - bytesNotRead);
if (read <= 0) {
loopCounter--;
}
read += bytesNotRead;
} else {
read = input.read(buffer);
}
this.read += pos;
pos = 0;
fillProgressInfo();
} else {
cancel();
return false;
}
}
return true;
} else {
cancel();
return false;
}
} catch (IOException ex) {
throw new FileUploadException("IO Error parsing multipart request",
ex);
}
}