use of io.netty.handler.codec.http.multipart.HttpPostBodyUtil.SeekAheadNoBackArrayException in project netty by netty.
the class HttpPostMultipartRequestDecoder method loadFieldMultipart.
/**
* Load the field value from a Multipart request
*
* @throws NotEnoughDataDecoderException
* Need more chunks
* @throws ErrorDataDecoderException
*/
private void loadFieldMultipart(String delimiter) {
SeekAheadOptimize sao;
try {
sao = new SeekAheadOptimize(undecodedChunk);
} catch (SeekAheadNoBackArrayException ignored) {
loadFieldMultipartStandard(delimiter);
return;
}
int readerIndex = undecodedChunk.readerIndex();
try {
// found the decoder limit
boolean newLine = true;
int index = 0;
int lastPosition;
int lastrealpos = sao.pos;
boolean found = false;
while (sao.pos < sao.limit) {
byte nextByte = sao.bytes[sao.pos++];
if (newLine) {
// Check the delimiter
if (nextByte == delimiter.codePointAt(index)) {
index++;
if (delimiter.length() == index) {
found = true;
break;
}
} else {
newLine = false;
index = 0;
// continue until end of line
if (nextByte == HttpConstants.CR) {
if (sao.pos < sao.limit) {
nextByte = sao.bytes[sao.pos++];
if (nextByte == HttpConstants.LF) {
newLine = true;
index = 0;
lastrealpos = sao.pos - 2;
} else {
// Unread last nextByte
sao.pos--;
lastrealpos = sao.pos;
}
}
} else if (nextByte == HttpConstants.LF) {
newLine = true;
index = 0;
lastrealpos = sao.pos - 1;
} else {
lastrealpos = sao.pos;
}
}
} else {
// continue until end of line
if (nextByte == HttpConstants.CR) {
if (sao.pos < sao.limit) {
nextByte = sao.bytes[sao.pos++];
if (nextByte == HttpConstants.LF) {
newLine = true;
index = 0;
lastrealpos = sao.pos - 2;
} else {
// Unread last nextByte
sao.pos--;
lastrealpos = sao.pos;
}
}
} else if (nextByte == HttpConstants.LF) {
newLine = true;
index = 0;
lastrealpos = sao.pos - 1;
} else {
lastrealpos = sao.pos;
}
}
}
lastPosition = sao.getReadPosition(lastrealpos);
if (found) {
// so go back of delimiter size
try {
currentAttribute.addContent(undecodedChunk.copy(readerIndex, lastPosition - readerIndex), true);
} catch (IOException e) {
throw new ErrorDataDecoderException(e);
}
undecodedChunk.readerIndex(lastPosition);
} else {
try {
currentAttribute.addContent(undecodedChunk.copy(readerIndex, lastPosition - readerIndex), false);
} catch (IOException e) {
throw new ErrorDataDecoderException(e);
}
undecodedChunk.readerIndex(lastPosition);
throw new NotEnoughDataDecoderException();
}
} catch (IndexOutOfBoundsException e) {
undecodedChunk.readerIndex(readerIndex);
throw new NotEnoughDataDecoderException(e);
}
}
use of io.netty.handler.codec.http.multipart.HttpPostBodyUtil.SeekAheadNoBackArrayException in project netty by netty.
the class HttpPostMultipartRequestDecoder method readLine.
/**
* Read one line up to the CRLF or LF
*
* @return the String from one line
* @throws NotEnoughDataDecoderException
* Need more chunks and reset the readerInder to the previous
* value
*/
private String readLine() {
SeekAheadOptimize sao;
try {
sao = new SeekAheadOptimize(undecodedChunk);
} catch (SeekAheadNoBackArrayException ignored) {
return readLineStandard();
}
int readerIndex = undecodedChunk.readerIndex();
try {
ByteBuf line = buffer(64);
while (sao.pos < sao.limit) {
byte 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 line.toString(charset);
} else {
// Write CR (not followed by LF)
sao.pos--;
line.writeByte(HttpConstants.CR);
}
} else {
line.writeByte(nextByte);
}
} else if (nextByte == HttpConstants.LF) {
sao.setReadPosition(0);
return line.toString(charset);
} else {
line.writeByte(nextByte);
}
}
} catch (IndexOutOfBoundsException e) {
undecodedChunk.readerIndex(readerIndex);
throw new NotEnoughDataDecoderException(e);
}
undecodedChunk.readerIndex(readerIndex);
throw new NotEnoughDataDecoderException();
}
use of io.netty.handler.codec.http.multipart.HttpPostBodyUtil.SeekAheadNoBackArrayException in project netty by netty.
the class HttpPostMultipartRequestDecoder method readDelimiter.
/**
* 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) {
SeekAheadOptimize sao;
try {
sao = new SeekAheadOptimize(undecodedChunk);
} catch (SeekAheadNoBackArrayException ignored) {
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 CR without LF
// delimiter not found so break here !
undecodedChunk.readerIndex(readerIndex);
throw new NotEnoughDataDecoderException();
}
} 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('-');
// second check for closing delimiter
if (sao.pos < sao.limit) {
nextByte = sao.bytes[sao.pos++];
if (nextByte == '-') {
sb.append('-');
// 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 {
// 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();
}
use of io.netty.handler.codec.http.multipart.HttpPostBodyUtil.SeekAheadNoBackArrayException in project netty by netty.
the class HttpPostStandardRequestDecoder method parseBodyAttributes.
/**
* This getMethod fill the map and list with as much Attribute as possible from
* Body in not Multipart mode.
*
* @throws ErrorDataDecoderException
* if there is a problem with the charset decoding or other
* errors
*/
private void parseBodyAttributes() {
SeekAheadOptimize sao;
try {
sao = new SeekAheadOptimize(undecodedChunk);
} catch (SeekAheadNoBackArrayException ignored) {
parseBodyAttributesStandard();
return;
}
int firstpos = undecodedChunk.readerIndex();
int currentpos = firstpos;
int equalpos;
int ampersandpos;
if (currentStatus == MultiPartStatus.NOTSTARTED) {
currentStatus = MultiPartStatus.DISPOSITION;
}
boolean contRead = true;
try {
loop: while (sao.pos < sao.limit) {
char read = (char) (sao.bytes[sao.pos++] & 0xFF);
currentpos++;
switch(currentStatus) {
case // search '='
DISPOSITION:
if (read == '=') {
currentStatus = MultiPartStatus.FIELD;
equalpos = currentpos - 1;
String key = decodeAttribute(undecodedChunk.toString(firstpos, equalpos - firstpos, charset), charset);
currentAttribute = factory.createAttribute(request, key);
firstpos = currentpos;
} else if (read == '&') {
// special empty FIELD
currentStatus = MultiPartStatus.DISPOSITION;
ampersandpos = currentpos - 1;
String key = decodeAttribute(undecodedChunk.toString(firstpos, ampersandpos - firstpos, charset), charset);
currentAttribute = factory.createAttribute(request, key);
// empty
currentAttribute.setValue("");
addHttpData(currentAttribute);
currentAttribute = null;
firstpos = currentpos;
contRead = true;
}
break;
case // search '&' or end of line
FIELD:
if (read == '&') {
currentStatus = MultiPartStatus.DISPOSITION;
ampersandpos = currentpos - 1;
setFinalBuffer(undecodedChunk.copy(firstpos, ampersandpos - firstpos));
firstpos = currentpos;
contRead = true;
} else if (read == HttpConstants.CR) {
if (sao.pos < sao.limit) {
read = (char) (sao.bytes[sao.pos++] & 0xFF);
currentpos++;
if (read == HttpConstants.LF) {
currentStatus = MultiPartStatus.PREEPILOGUE;
ampersandpos = currentpos - 2;
sao.setReadPosition(0);
setFinalBuffer(undecodedChunk.copy(firstpos, ampersandpos - firstpos));
firstpos = currentpos;
contRead = false;
break loop;
} else {
// Error
sao.setReadPosition(0);
throw new ErrorDataDecoderException("Bad end of line");
}
} else {
if (sao.limit > 0) {
currentpos--;
}
}
} else if (read == HttpConstants.LF) {
currentStatus = MultiPartStatus.PREEPILOGUE;
ampersandpos = currentpos - 1;
sao.setReadPosition(0);
setFinalBuffer(undecodedChunk.copy(firstpos, ampersandpos - firstpos));
firstpos = currentpos;
contRead = false;
break loop;
}
break;
default:
// just stop
sao.setReadPosition(0);
contRead = false;
break loop;
}
}
if (isLastChunk && currentAttribute != null) {
// special case
ampersandpos = currentpos;
if (ampersandpos > firstpos) {
setFinalBuffer(undecodedChunk.copy(firstpos, ampersandpos - firstpos));
} else if (!currentAttribute.isCompleted()) {
setFinalBuffer(EMPTY_BUFFER);
}
firstpos = currentpos;
currentStatus = MultiPartStatus.EPILOGUE;
undecodedChunk.readerIndex(firstpos);
return;
}
if (contRead && currentAttribute != null) {
// reset index except if to continue in case of FIELD getStatus
if (currentStatus == MultiPartStatus.FIELD) {
currentAttribute.addContent(undecodedChunk.copy(firstpos, currentpos - firstpos), false);
firstpos = currentpos;
}
undecodedChunk.readerIndex(firstpos);
} else {
// end of line or end of block so keep index to last valid position
undecodedChunk.readerIndex(firstpos);
}
} catch (ErrorDataDecoderException e) {
// error while decoding
undecodedChunk.readerIndex(firstpos);
throw e;
} catch (IOException e) {
// error while decoding
undecodedChunk.readerIndex(firstpos);
throw new ErrorDataDecoderException(e);
} catch (IllegalArgumentException e) {
// error while decoding
undecodedChunk.readerIndex(firstpos);
throw new ErrorDataDecoderException(e);
}
}
use of io.netty.handler.codec.http.multipart.HttpPostBodyUtil.SeekAheadNoBackArrayException in project netty by netty.
the class HttpPostMultipartRequestDecoder method readFileUploadByteMultipart.
/**
* Read a FileUpload data as Byte (Binary) and add the bytes directly to the
* FileUpload. If the delimiter is found, the FileUpload is completed.
*
* @throws NotEnoughDataDecoderException
* Need more chunks but do not reset the readerInder since some
* values will be already added to the FileOutput
* @throws ErrorDataDecoderException
* write IO error occurs with the FileUpload
*/
private void readFileUploadByteMultipart(String delimiter) {
SeekAheadOptimize sao;
try {
sao = new SeekAheadOptimize(undecodedChunk);
} catch (SeekAheadNoBackArrayException ignored) {
readFileUploadByteMultipartStandard(delimiter);
return;
}
int readerIndex = undecodedChunk.readerIndex();
// found the decoder limit
boolean newLine = true;
int index = 0;
int lastrealpos = sao.pos;
int lastPosition;
boolean found = false;
while (sao.pos < sao.limit) {
byte nextByte = sao.bytes[sao.pos++];
if (newLine) {
// Check the delimiter
if (nextByte == delimiter.codePointAt(index)) {
index++;
if (delimiter.length() == index) {
found = true;
break;
}
} else {
newLine = false;
index = 0;
// continue until end of line
if (nextByte == HttpConstants.CR) {
if (sao.pos < sao.limit) {
nextByte = sao.bytes[sao.pos++];
if (nextByte == HttpConstants.LF) {
newLine = true;
index = 0;
lastrealpos = sao.pos - 2;
} else {
// unread next byte
sao.pos--;
// save last valid position
lastrealpos = sao.pos;
}
}
} else if (nextByte == HttpConstants.LF) {
newLine = true;
index = 0;
lastrealpos = sao.pos - 1;
} else {
// save last valid position
lastrealpos = sao.pos;
}
}
} else {
// continue until end of line
if (nextByte == HttpConstants.CR) {
if (sao.pos < sao.limit) {
nextByte = sao.bytes[sao.pos++];
if (nextByte == HttpConstants.LF) {
newLine = true;
index = 0;
lastrealpos = sao.pos - 2;
} else {
// unread next byte
sao.pos--;
// save last valid position
lastrealpos = sao.pos;
}
}
} else if (nextByte == HttpConstants.LF) {
newLine = true;
index = 0;
lastrealpos = sao.pos - 1;
} else {
// save last valid position
lastrealpos = sao.pos;
}
}
}
lastPosition = sao.getReadPosition(lastrealpos);
ByteBuf buffer = undecodedChunk.copy(readerIndex, lastPosition - readerIndex);
if (found) {
// found so lastPosition is correct and final
try {
currentFileUpload.addContent(buffer, true);
// just before the CRLF and delimiter
undecodedChunk.readerIndex(lastPosition);
} catch (IOException e) {
throw new ErrorDataDecoderException(e);
}
} else {
// position is OK
try {
currentFileUpload.addContent(buffer, false);
// last valid char (not CR, not LF, not beginning of delimiter)
undecodedChunk.readerIndex(lastPosition);
throw new NotEnoughDataDecoderException();
} catch (IOException e) {
throw new ErrorDataDecoderException(e);
}
}
}
Aggregations