Fix for issue #434 to provide the ability to stop even if no CRLF is
provided since some clients as Adobe Flash will not finish the closing delimiter with a CRLF.
This commit is contained in:
parent
f16c7472de
commit
f74a96ca20
@ -894,7 +894,7 @@ public class HttpPostRequestDecoder {
|
||||
skipOneLine();
|
||||
String newline;
|
||||
try {
|
||||
newline = readLine();
|
||||
newline = readDelimiter(delimiter);
|
||||
} catch (NotEnoughDataDecoderException e) {
|
||||
undecodedChunk.readerIndex(readerIndex);
|
||||
return null;
|
||||
@ -1281,6 +1281,202 @@ public class HttpPostRequestDecoder {
|
||||
throw new NotEnoughDataDecoderException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Read one line up to --delimiter or --delimiter-- and if existing the CRLF or LF
|
||||
* Read one line up to --delimiter or --delimiter-- and if existing the CRLF or LF.
|
||||
* Note that CRLF or LF are mandatory for opening delimiter (--delimiter) but not for
|
||||
* closing delimiter (--delimiter--) since some clients does not include CRLF in this case.
|
||||
*
|
||||
* @param delimiter of the form --string, such that '--' is already included
|
||||
* @return the String from one line as the delimiter searched (opening or closing)
|
||||
* @throws NotEnoughDataDecoderException Need more chunks and
|
||||
* reset the readerInder to the previous value
|
||||
*/
|
||||
private String readDelimiterStandard(String delimiter) throws NotEnoughDataDecoderException {
|
||||
int readerIndex = undecodedChunk.readerIndex();
|
||||
try {
|
||||
StringBuilder sb = new StringBuilder(64);
|
||||
int delimiterPos = 0;
|
||||
int len = delimiter.length();
|
||||
while (undecodedChunk.readable() && delimiterPos < len) {
|
||||
byte nextByte = undecodedChunk.readByte();
|
||||
if (nextByte == delimiter.charAt(delimiterPos)) {
|
||||
delimiterPos++;
|
||||
sb.append((char) nextByte);
|
||||
} else {
|
||||
// delimiter not found so break here !
|
||||
undecodedChunk.readerIndex(readerIndex);
|
||||
throw new NotEnoughDataDecoderException();
|
||||
}
|
||||
}
|
||||
// Now check if either opening delimiter or closing delimiter
|
||||
if (undecodedChunk.readable()) {
|
||||
byte nextByte = undecodedChunk.readByte();
|
||||
// first check for opening delimiter
|
||||
if (nextByte == HttpConstants.CR) {
|
||||
nextByte = undecodedChunk.readByte();
|
||||
if (nextByte == HttpConstants.LF) {
|
||||
return sb.toString();
|
||||
} else {
|
||||
// error since CR must be followed by LF
|
||||
// delimiter not found so break here !
|
||||
undecodedChunk.readerIndex(readerIndex);
|
||||
throw new NotEnoughDataDecoderException();
|
||||
}
|
||||
} else if (nextByte == HttpConstants.LF) {
|
||||
return sb.toString();
|
||||
} else if (nextByte == '-') {
|
||||
sb.append((char) nextByte);
|
||||
// second check for closing delimiter
|
||||
nextByte = undecodedChunk.readByte();
|
||||
if (nextByte == '-') {
|
||||
sb.append((char) nextByte);
|
||||
// now try to find if CRLF or LF there
|
||||
if (undecodedChunk.readable()) {
|
||||
nextByte = undecodedChunk.readByte();
|
||||
if (nextByte == HttpConstants.CR) {
|
||||
nextByte = undecodedChunk.readByte();
|
||||
if (nextByte == HttpConstants.LF) {
|
||||
return sb.toString();
|
||||
} else {
|
||||
// error CR without LF
|
||||
// delimiter not found so break here !
|
||||
undecodedChunk.readerIndex(readerIndex);
|
||||
throw new NotEnoughDataDecoderException();
|
||||
}
|
||||
} else if (nextByte == HttpConstants.LF) {
|
||||
return sb.toString();
|
||||
} else {
|
||||
// No CRLF but ok however (Adobe Flash uploader)
|
||||
// minus 1 since we read one char ahead but should not
|
||||
undecodedChunk.readerIndex(undecodedChunk.readerIndex()-1);
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
// FIXME what do we do here?
|
||||
// either considering it is fine, either waiting for more data to come?
|
||||
// lets try considering it is fine...
|
||||
return sb.toString();
|
||||
}
|
||||
// only one '-' => not enough
|
||||
// whatever now => error since incomplete
|
||||
}
|
||||
}
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
undecodedChunk.readerIndex(readerIndex);
|
||||
throw new NotEnoughDataDecoderException(e);
|
||||
}
|
||||
undecodedChunk.readerIndex(readerIndex);
|
||||
throw new NotEnoughDataDecoderException();
|
||||
}
|
||||
/**
|
||||
* Read one line up to --delimiter or --delimiter-- and if existing the CRLF or LF.
|
||||
* Note that CRLF or LF are mandatory for opening delimiter (--delimiter) but not for
|
||||
* closing delimiter (--delimiter--) since some clients does not include CRLF in this case.
|
||||
*
|
||||
* @param delimiter of the form --string, such that '--' is already included
|
||||
* @return the String from one line as the delimiter searched (opening or closing)
|
||||
* @throws NotEnoughDataDecoderException Need more chunks and
|
||||
* reset the readerInder to the previous value
|
||||
*/
|
||||
private String readDelimiter(String delimiter) throws NotEnoughDataDecoderException {
|
||||
SeekAheadOptimize sao = null;
|
||||
try {
|
||||
sao = new SeekAheadOptimize(undecodedChunk);
|
||||
} catch (SeekAheadNoBackArrayException e1) {
|
||||
return readDelimiterStandard(delimiter);
|
||||
}
|
||||
int readerIndex = undecodedChunk.readerIndex();
|
||||
int delimiterPos = 0;
|
||||
int len = delimiter.length();
|
||||
try {
|
||||
StringBuilder sb = new StringBuilder(64);
|
||||
// check conformity with delimiter
|
||||
while (sao.pos < sao.limit && delimiterPos < len) {
|
||||
byte nextByte = sao.bytes[sao.pos ++];
|
||||
if (nextByte == delimiter.charAt(delimiterPos)) {
|
||||
delimiterPos++;
|
||||
sb.append((char) nextByte);
|
||||
} else {
|
||||
// delimiter not found so break here !
|
||||
undecodedChunk.readerIndex(readerIndex);
|
||||
throw new NotEnoughDataDecoderException();
|
||||
}
|
||||
}
|
||||
// Now check if either opening delimiter or closing delimiter
|
||||
if (sao.pos < sao.limit) {
|
||||
byte nextByte = sao.bytes[sao.pos ++];
|
||||
if (nextByte == HttpConstants.CR) {
|
||||
// first check for opening delimiter
|
||||
if (sao.pos < sao.limit) {
|
||||
nextByte = sao.bytes[sao.pos ++];
|
||||
if (nextByte == HttpConstants.LF) {
|
||||
sao.setReadPosition(0);
|
||||
return sb.toString();
|
||||
}
|
||||
} else {
|
||||
// error since CR must be followed by LF
|
||||
// delimiter not found so break here !
|
||||
undecodedChunk.readerIndex(readerIndex);
|
||||
throw new NotEnoughDataDecoderException();
|
||||
}
|
||||
} else if (nextByte == HttpConstants.LF) {
|
||||
// same first check for opening delimiter where LF used with no CR
|
||||
sao.setReadPosition(0);
|
||||
return sb.toString();
|
||||
} else if (nextByte == '-') {
|
||||
sb.append((char) nextByte);
|
||||
// second check for closing delimiter
|
||||
if (sao.pos < sao.limit) {
|
||||
nextByte = sao.bytes[sao.pos ++];
|
||||
if (nextByte == '-') {
|
||||
sb.append((char) nextByte);
|
||||
// now try to find if CRLF or LF there
|
||||
if (sao.pos < sao.limit) {
|
||||
nextByte = sao.bytes[sao.pos ++];
|
||||
if (nextByte == HttpConstants.CR) {
|
||||
if (sao.pos < sao.limit) {
|
||||
nextByte = sao.bytes[sao.pos ++];
|
||||
if (nextByte == HttpConstants.LF) {
|
||||
sao.setReadPosition(0);
|
||||
return sb.toString();
|
||||
}
|
||||
} else {
|
||||
// error CR without LF
|
||||
// delimiter not found so break here !
|
||||
undecodedChunk.readerIndex(readerIndex);
|
||||
throw new NotEnoughDataDecoderException();
|
||||
}
|
||||
} else if (nextByte == HttpConstants.LF) {
|
||||
sao.setReadPosition(0);
|
||||
return sb.toString();
|
||||
} else {
|
||||
// No CRLF but ok however (Adobe Flash uploader)
|
||||
// minus 1 since we read one char ahead but should not
|
||||
sao.setReadPosition(1);
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
// FIXME what do we do here?
|
||||
// either considering it is fine, either waiting for more data to come?
|
||||
// lets try considering it is fine...
|
||||
sao.setReadPosition(0);
|
||||
return sb.toString();
|
||||
}
|
||||
// whatever now => error since incomplete
|
||||
// only one '-' => not enough or whatever not enough element
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
undecodedChunk.readerIndex(readerIndex);
|
||||
throw new NotEnoughDataDecoderException(e);
|
||||
}
|
||||
undecodedChunk.readerIndex(readerIndex);
|
||||
throw new NotEnoughDataDecoderException();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read a FileUpload data as Byte (Binary) and add the bytes directly to the
|
||||
* FileUpload. If the delimiter is found, the FileUpload is completed.
|
||||
|
Loading…
Reference in New Issue
Block a user