*/
public synchronized void messageReceived(final NextFilter nextFilter,
final IoBuffer buf) throws ProxyAuthException {
logger.debug(" messageReceived()");
IoBufferDecoder decoder = (IoBufferDecoder) getSession().getAttribute(
DECODER);
if (decoder == null) {
decoder = new IoBufferDecoder(HTTP_DELIMITER);
getSession().setAttribute(DECODER, decoder);
}
try {
if (parsedResponse == null) {
responseData = decoder.decodeFully(buf);
if (responseData == null) {
return;
}
// Handle the response
String responseHeader = responseData
.getString(getProxyIoSession().getCharset()
.newDecoder());
entityBodyStartPosition = responseData.position();
logger.debug(" response header received:\n{}", responseHeader
.replace("\r", "\\r").replace("\n", "\\n\n"));
// Parse the response
parsedResponse = decodeResponse(responseHeader);
// Is handshake complete ?
if (parsedResponse.getStatusCode() == 200
|| (parsedResponse.getStatusCode() >= 300 && parsedResponse
.getStatusCode() <= 307)) {
buf.position(0);
setHandshakeComplete();
return;
}
String contentLengthHeader = StringUtilities
.getSingleValuedHeader(parsedResponse.getHeaders(),
"Content-Length");
if (contentLengthHeader == null) {
contentLength = 0;
} else {
contentLength = Integer
.parseInt(contentLengthHeader.trim());
decoder.setContentLength(contentLength, true);
}
}
if (!hasChunkedData) {
if (contentLength > 0) {
IoBuffer tmp = decoder.decodeFully(buf);
if (tmp == null) {
return;
}
responseData.setAutoExpand(true);
responseData.put(tmp);
contentLength = 0;
}
if ("chunked".equalsIgnoreCase(StringUtilities
.getSingleValuedHeader(parsedResponse.getHeaders(),
"Transfer-Encoding"))) {
// Handle Transfer-Encoding: Chunked
logger.debug("Retrieving additional http response chunks");
hasChunkedData = true;
waitingChunkedData = true;
}
}
if (hasChunkedData) {
// Read chunks
while (waitingChunkedData) {
if (contentLength == 0) {
decoder.setDelimiter(CRLF_DELIMITER, false);
IoBuffer tmp = decoder.decodeFully(buf);
if (tmp == null) {
return;
}
String chunkSize = tmp.getString(getProxyIoSession()
.getCharset().newDecoder());
int pos = chunkSize.indexOf(';');
if (pos >= 0) {
chunkSize = chunkSize.substring(0, pos);
} else {
chunkSize = chunkSize.substring(0, chunkSize
.length() - 2);
}
contentLength = Integer.decode("0x" + chunkSize);
if (contentLength > 0) {
contentLength += 2; // also read chunk's trailing CRLF
decoder.setContentLength(contentLength, true);
}
}
if (contentLength == 0) {
waitingChunkedData = false;
waitingFooters = true;
entityBodyLimitPosition = responseData.position();
break;
}
IoBuffer tmp = decoder.decodeFully(buf);
if (tmp == null) {
return;
}
contentLength = 0;
responseData.put(tmp);
buf.position(buf.position());
}
// Read footers
while (waitingFooters) {
decoder.setDelimiter(CRLF_DELIMITER, false);
IoBuffer tmp = decoder.decodeFully(buf);
if (tmp == null) {
return;
}
if (tmp.remaining() == 2) {
waitingFooters = false;
break;
}
// add footer to headers
String footer = tmp.getString(getProxyIoSession()
.getCharset().newDecoder());
String[] f = footer.split(":\\s?", 2);
StringUtilities.addValueToHeader(parsedResponse
.getHeaders(), f[0], f[1], false);
responseData.put(tmp);
responseData.put(CRLF_DELIMITER);
}
}
responseData.flip();
logger.debug(" end of response received:\n{}",
responseData.getString(getProxyIoSession().getCharset()
.newDecoder()));
// Retrieve entity body content
responseData.position(entityBodyStartPosition);
responseData.limit(entityBodyLimitPosition);
parsedResponse.setBody(responseData.getString(getProxyIoSession()
.getCharset().newDecoder()));
// Free the response buffer
responseData.free();
responseData = null;
handleResponse(parsedResponse);
parsedResponse = null;
hasChunkedData = false;
contentLength = -1;
decoder.setDelimiter(HTTP_DELIMITER, true);
if (!isHandshakeComplete()) {
doHandshake(nextFilter);
}
} catch (Exception ex) {