OW2 Consortium odis/

Compare Revisions

Ignore whitespace Rev 148 → Rev 149

/trunk/Odis/OdisConnectionNio/standalone/src/main/java/org/ow2/odis/nio/HTTP/HttpMessageDecoder.java
12,6 → 12,9
import org.apache.mina.filter.codec.ProtocolDecoderOutput;
import org.apache.mina.filter.codec.demux.MessageDecoderAdapter;
import org.apache.mina.filter.codec.demux.MessageDecoderResult;
import org.objectweb.util.monolog.Monolog;
import org.objectweb.util.monolog.api.BasicLevel;
import org.objectweb.util.monolog.api.Logger;
import org.ow2.odis.encoder.GenericEncoder;
import org.ow2.odis.nio.Constant;
 
19,642 → 22,621
* The Class HttpMessageDecoder.
*/
public class HttpMessageDecoder extends MessageDecoderAdapter {
/** The Constant CONTENT_LENGTH. */
private static final byte[] CONTENT_LENGTH = (HttpMessage.CONTENT_LENGTH + ":")
.getBytes();
 
/** The Constant COOKIE_COMMENT. */
/** Logger for this class. */
static final Logger LOGGER = Monolog.initialize().getLogger(HttpMessageDecoder.class.getName());
 
public static final String COOKIE_COMMENT = "comment";
/** The Constant CONTENT_LENGTH. */
private static final byte[] CONTENT_LENGTH = (HttpMessage.CONTENT_LENGTH + ":").getBytes();
 
/** The Constant COOKIE_DOMAIN. */
public static final String COOKIE_DOMAIN = "domain";
/** The Constant COOKIE_COMMENT. */
 
/** The Constant COOKIE_EXPIRES. */
public static final String COOKIE_EXPIRES = "expires";
public static final String COOKIE_COMMENT = "comment";
 
/** The Constant COOKIE_MAX_AGE. */
public static final String COOKIE_MAX_AGE = "max-age";
/** The Constant COOKIE_DOMAIN. */
public static final String COOKIE_DOMAIN = "domain";
 
/** The Constant COOKIE_PATH. */
public static final String COOKIE_PATH = "path";
/** The Constant COOKIE_EXPIRES. */
public static final String COOKIE_EXPIRES = "expires";
 
/** The Constant COOKIE_SECURE. */
public static final String COOKIE_SECURE = "secure";
/** The Constant COOKIE_MAX_AGE. */
public static final String COOKIE_MAX_AGE = "max-age";
 
/** The Constant COOKIE_VERSION. */
public static final String COOKIE_VERSION = "version";
/** The Constant COOKIE_PATH. */
public static final String COOKIE_PATH = "path";
 
/** The Constant SET_COOKIE. */
public static final String SET_COOKIE = "Set-Cookie";
/** The Constant COOKIE_SECURE. */
public static final String COOKIE_SECURE = "secure";
 
/** The Constant CURRENT_MESSAGE. */
private static final String CURRENT_MESSAGE = "CURRENT_MESSAGE";
/** The Constant COOKIE_VERSION. */
public static final String COOKIE_VERSION = "version";
 
/** The Constant INCOMPLETE_LINE. */
private static final String INCOMPLETE_LINE = "INCOMPLETE_LINE";
/** The Constant SET_COOKIE. */
public static final String SET_COOKIE = "Set-Cookie";
 
/** The Constant TRANSFER_ENCODING. */
public static final String TRANSFER_ENCODING = "Transfer-Encoding";
/** The Constant CURRENT_MESSAGE. */
private static final String CURRENT_MESSAGE = "CURRENT_MESSAGE";
 
/** The Constant CHUNKED. */
public static final String CHUNKED = "chunked";
/** The Constant INCOMPLETE_LINE. */
private static final String INCOMPLETE_LINE = "INCOMPLETE_LINE";
 
/** The decoder. */
private final CharsetDecoder decoder = Charset.defaultCharset()
.newDecoder();
/** The Constant TRANSFER_ENCODING. */
public static final String TRANSFER_ENCODING = "Transfer-Encoding";
 
/** The generic encoder. */
private GenericEncoder genericEncoder = new GenericEncoder();
/** The Constant CHUNKED. */
public static final String CHUNKED = "chunked";
 
/** The Constant CRLF. */
private static final String CRLF = "\r\n";
/** The decoder. */
private final CharsetDecoder decoder = Charset.defaultCharset().newDecoder();
 
/** The is client synchrony. */
private boolean isClientSynchrone = false;
/** The generic encoder. */
private GenericEncoder genericEncoder = new GenericEncoder();
 
/**
* Instantiates a new http message decoder.
*/
public HttpMessageDecoder() {
}
/** The Constant CRLF. */
private static final String CRLF = "\r\n";
 
/*
* (non-Javadoc)
*
* @see
* org.apache.mina.filter.codec.demux.MessageDecoder#decodable(org.apache
* .mina.common.IoSession, org.apache.mina.common.ByteBuffer)
*/
public MessageDecoderResult decodable(IoSession session, ByteBuffer in) {
// Return NEED_DATA if the whole header is not read yet.
try {
if (isClientSynchrone) {
return messageComplete(in) ? MessageDecoderResult.OK
: MessageDecoderResult.NEED_DATA;
} else {
return ExistsAtLeastOneMessageComplete(in) ? MessageDecoderResult.OK
: MessageDecoderResult.NEED_DATA;
}
} catch (Exception ex) {
ex.printStackTrace();
}
return MessageDecoderResult.NOT_OK;
}
/** The is client synchrony. */
private boolean isClientSynchrone = false;
 
/*
* (non-Javadoc)
*
* @see
* org.apache.mina.filter.codec.demux.MessageDecoder#decode(org.apache.mina
* .common.IoSession, org.apache.mina.common.ByteBuffer,
* org.apache.mina.filter.codec.ProtocolDecoderOutput)
*/
public MessageDecoderResult decode(IoSession session, ByteBuffer in,
ProtocolDecoderOutput out) throws Exception {
MessageDecoderResult result = MessageDecoderResult.NEED_DATA;
List allLines = null;
String buffer = null;
/**
* Instantiates a new http message decoder.
*/
public HttpMessageDecoder() {
}
 
if (isClientSynchrone) {
allLines = getAllLines(in, 0, in.limit());
result = writeMessage(allLines, session, out);
} else {
// saving limit value before managing in buffer
int limit = in.limit();
List positions = MinaHelper.getPositions(in,
HttpMessageEncoder.STX, HttpMessageEncoder.ETX);
for (int i = 0; i < positions.size(); i++) {
int[] position = ((int[]) positions.get(i));
int start = position[0];
int end = position[1];
if ((start != -1) && (end == -1)) {
buffer = getBuffer(in, start + 1, limit);
saveIncompleteLine(buffer, session);
// allLines = getAllLines(in, start + 1, limit);
//saveIncompleteLine(toString(allLines), session);
result = MessageDecoderResult.NEED_DATA;
} else if ((start == -1) && (end == -1)) {
buffer = (String) session.getAttribute(INCOMPLETE_LINE);
buffer += getBuffer(in, 0, limit);
saveIncompleteLine(buffer, session);
// allLines = getAllLines(in, 0, limit);
// allLines = appendLine(allLines, (String) session
// .getAttribute(INCOMPLETE_LINE), 0);
// saveIncompleteLine(toString(allLines), session);
result = MessageDecoderResult.NEED_DATA;
} else if ((start == -1) && (end != -1)) {
buffer = (String) session.getAttribute(INCOMPLETE_LINE);
buffer += getBuffer(in, 0, end-1);
allLines = getAllLines(buffer);
// allLines = getAllLines(in, 0, end);
// allLines = appendLine(allLines, (String) session
// .getAttribute(INCOMPLETE_LINE), 0);
result = writeMessage(allLines, session, out);
} else {
allLines = getAllLines(in, start + 1, end-1);
result = writeMessage(allLines, session, out);
}
}
}
return result;
}
/*
* (non-Javadoc)
*
* @see org.apache.mina.filter.codec.demux.MessageDecoder#decodable(org.apache
* .mina.common.IoSession, org.apache.mina.common.ByteBuffer)
*/
public MessageDecoderResult decodable(IoSession session, ByteBuffer in) {
// Return NEED_DATA if the whole header is not read yet.
try {
if (isClientSynchrone) {
return messageComplete(in) ? MessageDecoderResult.OK : MessageDecoderResult.NEED_DATA;
} else {
return ExistsAtLeastOneMessageComplete(in) ? MessageDecoderResult.OK : MessageDecoderResult.NEED_DATA;
}
} catch (Exception ex) {
ex.printStackTrace();
}
return MessageDecoderResult.NOT_OK;
}
 
/**
* Write message.
*
* @param lines
* the lines
* @param session
* the session
* @param out
* the out
*
* @return the message decoder result
*
* @throws Exception
* the exception
*/
private MessageDecoderResult writeMessage(List lines, IoSession session,
ProtocolDecoderOutput out) throws Exception {
HttpMessage message = getHttpMessage(lines, (HttpMessage) session
.getAttribute(CURRENT_MESSAGE), session);
session.removeAttribute(CURRENT_MESSAGE);
out.write(genericEncoder.encode(message));
return MessageDecoderResult.OK;
}
/*
* (non-Javadoc)
*
* @see
* org.apache.mina.filter.codec.demux.MessageDecoder#decode(org.apache.mina
* .common.IoSession, org.apache.mina.common.ByteBuffer,
* org.apache.mina.filter.codec.ProtocolDecoderOutput)
*/
public MessageDecoderResult decode(IoSession session, ByteBuffer in, ProtocolDecoderOutput out) throws Exception {
MessageDecoderResult result = MessageDecoderResult.NEED_DATA;
List allLines = null;
String buffer = null;
 
/**
* Save incomplete line.
*
* @param line
* the line
* @param session
* the session
*/
private void saveIncompleteLine(String line, IoSession session) {
session.removeAttribute(INCOMPLETE_LINE);
session.setAttribute(INCOMPLETE_LINE, line.substring(0,
line.length() )); // remove
// carriage
// return added by toString
if (isClientSynchrone) {
allLines = getAllLines(in, 0, in.limit());
result = writeMessage(allLines, session, out);
} else {
// saving limit value before managing in buffer
int limit = in.limit();
List positions = MinaHelper.getPositions(in, HttpMessageEncoder.STX, HttpMessageEncoder.ETX);
for (int i = 0; i < positions.size(); i++) {
int[] position = ((int[]) positions.get(i));
int start = position[0];
int end = position[1];
LOGGER.log(BasicLevel.DEBUG, "decode() start=" + start + " end=" + end + " in" + in);
if ((start != -1) && (end == -1)) {
buffer = getBuffer(in, start + 1, limit);
saveIncompleteLine(buffer, session);
// allLines = getAllLines(in, start + 1, limit);
// saveIncompleteLine(toString(allLines), session);
result = MessageDecoderResult.NEED_DATA;
} else if ((start == -1) && (end == -1)) {
buffer = (String) session.getAttribute(INCOMPLETE_LINE);
buffer += getBuffer(in, 0, limit);
saveIncompleteLine(buffer, session);
// allLines = getAllLines(in, 0, limit);
// allLines = appendLine(allLines, (String) session
// .getAttribute(INCOMPLETE_LINE), 0);
// saveIncompleteLine(toString(allLines), session);
result = MessageDecoderResult.NEED_DATA;
} else if ((start == -1) && (end != -1)) {
buffer = (String) session.getAttribute(INCOMPLETE_LINE);
buffer += getBuffer(in, 0, end - 1);
allLines = getAllLines(buffer);
// allLines = getAllLines(in, 0, end);
// allLines = appendLine(allLines, (String) session
// .getAttribute(INCOMPLETE_LINE), 0);
result = writeMessage(allLines, session, out);
} else {
allLines = getAllLines(in, start + 1, end - 1);
result = writeMessage(allLines, session, out);
}
}
}
return result;
}
 
}
/**
* Write message.
*
* @param lines
* the lines
* @param session
* the session
* @param out
* the out
*
* @return the message decoder result
*
* @throws Exception
* the exception
*/
private MessageDecoderResult writeMessage(List lines, IoSession session, ProtocolDecoderOutput out) throws Exception {
HttpMessage message = getHttpMessage(lines, (HttpMessage) session.getAttribute(CURRENT_MESSAGE), session);
session.removeAttribute(CURRENT_MESSAGE);
out.write(genericEncoder.encode(message));
return MessageDecoderResult.OK;
}
 
/**
* Save incomplete line.
*
* @param line
* the line
* @param session
* the session
*/
private void saveIncompleteLine(String line, IoSession session) {
session.removeAttribute(INCOMPLETE_LINE);
session.setAttribute(INCOMPLETE_LINE, line.substring(0, line.length())); // remove
// carriage
// return added by toString
 
/**
* Gets the all lines.
*
* @param in
* the in
* @param start
* the start
* @param end
* the end
*
* @return the all lines
*
* @throws Exception
* the exception
*/
private List getAllLines(ByteBuffer in, int start, int end)
throws Exception {
return getAllLines(getBuffer(in, start, end));
}
/**
* Split buffer in list of line
* @param buffer
* @return
*/
private List getAllLines(String buffer) {
List allLines = new ArrayList();
String[] tabLines = buffer.split(CRLF, -1);
for (int i = 0; i < tabLines.length; i++) {
// Remove CR and LF if persist in line
String line = tabLines[i].replaceAll("\n", "").replaceAll("\r", "");
allLines.add(line);
}
tabLines = null;
return allLines;
}
/**
* Get buffer part of buffer in from start to end
* @param in
* @param start
* @param end
* @return The part of buffer
* @throws CharacterCodingException
*/
private String getBuffer(ByteBuffer in, int start, int end) throws CharacterCodingException {
in.rewind();
in.limit(end);
in.position(start);
}
 
return in.getString(decoder);
}
/**
* Gets the all lines.
*
* @param in
* the in
* @param start
* the start
* @param end
* the end
*
* @return the all lines
*
* @throws Exception
* the exception
*/
private List getAllLines(ByteBuffer in, int start, int end) throws Exception {
return getAllLines(getBuffer(in, start, end));
}
 
/**
* Gets the http messages.
*
* @param lines
* the lines
* @param currentHttpMessage
* the current http message
* @param session
* the session
*
* @return the http messages
*
* @throws Exception
* the exception
*/
/*
* private List getHttpMessages(List lines, HttpMessage currentHttpMessage,
* IoSession session) throws Exception { List result = new ArrayList();
* HttpMessage message = currentHttpMessage; boolean isHeaderCompletelyRead
* = false; StringBuffer body = new StringBuffer(); for (int i = 0; i <
* lines.size(); i++) { String line = (String) lines.get(i); if ((i==0) &&
* (session.getAttribute(INCOMPLETE_LINE) != null)) { line =
* session.getAttribute(INCOMPLETE_LINE) + line;
* session.removeAttribute(INCOMPLETE_LINE); } if (!"".equals(line)) { if
* (isFirstLineOfNewHTTPMessage(line, message)) { if (body.length() != 0) {
* message.setBody(body.toString()); result.add(message);
*
* // init for the next message body = new StringBuffer();
* isHeaderCompletelyRead = false; } message = getHttpMessage(line,
* session); if (message == null) { break; } } else { if
* (!isHeaderCompletelyRead) { setHeader(message, line); } else {
* body.append(line); } } } else { if (!isHeaderCompletelyRead) {
* isHeaderCompletelyRead = true; } else if (i != lines.size()) {
* body.append(line); } else { message.setBody(body.toString());
* result.add(message);
*
* // init for the next message body = new StringBuffer();
* isHeaderCompletelyRead = false; } } } if (message != null) {
* message.setBody(body.toString()); result.add(message); }
*
* return result; }
*/
/**
* Split buffer in list of line
*
* @param buffer
* @return
*/
private List getAllLines(String buffer) {
List allLines = new ArrayList();
 
private HttpMessage getHttpMessage(List lines,
HttpMessage currentHttpMessage, IoSession session) throws Exception {
HttpMessage message = getHttpMessage((String) lines.get(0), session);
boolean isHeaderCompletelyRead = false;
StringBuffer body = new StringBuffer();
if (message != null) {
for (int i = 1; i < lines.size(); i++) {
String line = (String) lines.get(i);
if (!Constant.EMPTY.equals(line)) {
if (!isHeaderCompletelyRead) {
setHeader(message, line);
} else {
body.append(line);
}
} else {
if (!isHeaderCompletelyRead) {
isHeaderCompletelyRead = true;
} else if (i != lines.size()) {
body.append(line);
}
}
}
message.setBody(body.toString());
}
body = null;
return message;
}
String[] tabLines = buffer.split(CRLF, -1);
for (int i = 0; i < tabLines.length; i++) {
// Remove CR and LF if persist in line
String line = tabLines[i].replaceAll("\n", "").replaceAll("\r", "");
allLines.add(line);
}
tabLines = null;
return allLines;
}
 
/**
* Sets the header.
*
* @param httpMessage
* the http message
* @param line
* the line
*
* @throws Exception
* the exception
*/
private void setHeader(HttpMessage httpMessage, String line)
throws Exception {
String key = null;
String value = Constant.EMPTY;
String[] tokens = line.split(": ");
key = (String) tokens[0];
if (tokens.length == 2)
value = tokens[1];
if (key.equalsIgnoreCase(SET_COOKIE)) {
Cookie cookie = decodeCookie(value);
if (cookie != null) {
httpMessage.addCookie(cookie);
}
} else if (key.equalsIgnoreCase(HttpMessage.CONTENT_TYPE)) {
httpMessage.setContentType(value);
} else if (key.equalsIgnoreCase(HttpMessage.CONTENT_LENGTH)) {
httpMessage.setContentLength(Integer.parseInt(value));
} else if (key.equalsIgnoreCase(TRANSFER_ENCODING) && value != null
&& value.equalsIgnoreCase(CHUNKED)) {
httpMessage.setChunked(true);
} else if (key.equalsIgnoreCase(HttpMessage.CONNECTION)
&& value != null
&& value.equalsIgnoreCase(HttpMessage.CONNECTION_CLOSE)) {
httpMessage.setDecodeOnlyAfterCloseConnection(true);
} else {
httpMessage.getHeaders().put(key, value);
}
/**
* Get buffer part of buffer in from start to end
*
* @param in
* @param start
* @param end
* @return The part of buffer
* @throws CharacterCodingException
*/
private String getBuffer(ByteBuffer in, int start, int end) throws CharacterCodingException {
in.rewind();
in.limit(end);
in.position(start);
if (LOGGER.isLoggable(BasicLevel.DEBUG)) {
// debug log for debug this stupid encoding system !
LOGGER.log(BasicLevel.DEBUG, "getBuffer() start=" + start + " end=" + end + " in=" + in);
 
}
String msg = "";
for (int i = start; i < end; i++) {
msg += String.valueOf((char) in.get(i));
}
LOGGER.log(BasicLevel.DEBUG, "getBuffer() start=" + start + " end=" + end + " msg=" + msg);
}
return in.getString(decoder);
}
 
/**
* Decode body.
*
* @param in
* the in
*
* @return true, if message complete
*
* @throws Exception
* the exception
*/
/*
* public void decodeBody(BufferedReader reader, HttpMessage message,
* IoSession session) throws Exception { if (message instanceof
* HttpResponseMessage) { int code = ((HttpResponseMessage)
* message).getStatusCode(); if (code < 200 || code == 204 || code == 304) {
* message.setBody("status of msg " + code);
* session.removeAttribute(CURRENT_MESSAGE); } else {
* message.setBody(getContent(reader, session)); } } else {
* message.setBody(getContent(reader, session)); } }
*/
/**
* Gets the http messages.
*
* @param lines
* the lines
* @param currentHttpMessage
* the current http message
* @param session
* the session
*
* @return the http messages
*
* @throws Exception
* the exception
*/
/*
* private List getHttpMessages(List lines, HttpMessage currentHttpMessage,
* IoSession session) throws Exception { List result = new ArrayList();
* HttpMessage message = currentHttpMessage; boolean isHeaderCompletelyRead =
* false; StringBuffer body = new StringBuffer(); for (int i = 0; i <
* lines.size(); i++) { String line = (String) lines.get(i); if ((i==0) &&
* (session.getAttribute(INCOMPLETE_LINE) != null)) { line =
* session.getAttribute(INCOMPLETE_LINE) + line;
* session.removeAttribute(INCOMPLETE_LINE); } if (!"".equals(line)) { if
* (isFirstLineOfNewHTTPMessage(line, message)) { if (body.length() != 0) {
* message.setBody(body.toString()); result.add(message);
*
* // init for the next message body = new StringBuffer();
* isHeaderCompletelyRead = false; } message = getHttpMessage(line, session);
* if (message == null) { break; } } else { if (!isHeaderCompletelyRead) {
* setHeader(message, line); } else { body.append(line); } } } else { if
* (!isHeaderCompletelyRead) { isHeaderCompletelyRead = true; } else if (i !=
* lines.size()) { body.append(line); } else {
* message.setBody(body.toString()); result.add(message);
*
* // init for the next message body = new StringBuffer();
* isHeaderCompletelyRead = false; } } } if (message != null) {
* message.setBody(body.toString()); result.add(message); }
*
* return result; }
*/
 
/**
* Gets the content.
*
* @param reader
* the reader
* @param session
* the session
*
* @return the content
*
* @throws Exception
* the exception
*/
/*
* public String getContent(BufferedReader reader, IoSession session) throws
* Exception { StringBuffer result = new StringBuffer(); String line =
* reader.readLine(); boolean isAnotherMessagePresents = false; while (line
* != null) { if (isFirstLineOfNewHTTPMessage(line)) {
* session.removeAttribute(CURRENT_MESSAGE);
* session.setAttribute(CURRENT_MESSAGE, getHttpMessage(line));
* isAnotherMessagePresents = true; break; } else { result.append(line);
* line = reader.readLine(); } } if (!isAnotherMessagePresents)
* session.removeAttribute(CURRENT_MESSAGE); return result.toString(); }
*/
private HttpMessage getHttpMessage(List lines, HttpMessage currentHttpMessage, IoSession session) throws Exception {
HttpMessage message = getHttpMessage((String) lines.get(0), session);
boolean isHeaderCompletelyRead = false;
StringBuffer body = new StringBuffer();
if (message != null) {
for (int i = 1; i < lines.size(); i++) {
String line = (String) lines.get(i);
if (!Constant.EMPTY.equals(line)) {
if (!isHeaderCompletelyRead) {
setHeader(message, line);
} else {
body.append(line);
}
} else {
if (!isHeaderCompletelyRead) {
isHeaderCompletelyRead = true;
} else if (i != lines.size()) {
body.append(line);
}
}
}
message.setBody(body.toString());
}
body = null;
return message;
}
 
/**
* Message complete.
*
* @param in
* the in
*
* @return true, if successful
*
* @throws Exception
* the exception
*/
private boolean messageComplete(ByteBuffer in) throws Exception {
int last = in.remaining() - 1;
if (in.remaining() < 4) {
return false;
}
/**
* Sets the header.
*
* @param httpMessage
* the http message
* @param line
* the line
*
* @throws Exception
* the exception
*/
private void setHeader(HttpMessage httpMessage, String line) throws Exception {
String key = null;
String value = Constant.EMPTY;
String[] tokens = line.split(": ");
key = (String) tokens[0];
if (tokens.length == 2)
value = tokens[1];
if (key.equalsIgnoreCase(SET_COOKIE)) {
Cookie cookie = decodeCookie(value);
if (cookie != null) {
httpMessage.addCookie(cookie);
}
} else if (key.equalsIgnoreCase(HttpMessage.CONTENT_TYPE)) {
httpMessage.setContentType(value);
} else if (key.equalsIgnoreCase(HttpMessage.CONTENT_LENGTH)) {
httpMessage.setContentLength(Integer.parseInt(value));
} else if (key.equalsIgnoreCase(TRANSFER_ENCODING) && value != null && value.equalsIgnoreCase(CHUNKED)) {
httpMessage.setChunked(true);
} else if (key.equalsIgnoreCase(HttpMessage.CONNECTION) && value != null
&& value.equalsIgnoreCase(HttpMessage.CONNECTION_CLOSE)) {
httpMessage.setDecodeOnlyAfterCloseConnection(true);
} else {
httpMessage.getHeaders().put(key, value);
}
 
// to speed up things we check if the Http request is a GET or POST
if (in.get(0) == (byte) 'G' && in.get(1) == (byte) 'E'
&& in.get(2) == (byte) 'T') {
// Http GET request therefore the last 4 bytes should be 0x0D 0x0A
// 0x0D 0x0A
return in.get(last) == (byte) 0x0A
&& in.get(last - 1) == (byte) 0x0D
&& in.get(last - 2) == (byte) 0x0A
&& in.get(last - 3) == (byte) 0x0D;
} else if (in.get(0) == (byte) 'P' && in.get(1) == (byte) 'O'
&& in.get(2) == (byte) 'S' && in.get(3) == (byte) 'T') {
// Http POST request
// first the position of the 0x0D 0x0A 0x0D 0x0A bytes
int eoh = -1;
for (int i = last; i > 2; i--) {
if (in.get(i) == (byte) 0x0A && in.get(i - 1) == (byte) 0x0D
&& in.get(i - 2) == (byte) 0x0A
&& in.get(i - 3) == (byte) 0x0D) {
eoh = i + 1;
break;
}
}
if (eoh == -1) {
return false;
}
for (int i = 0; i < last; i++) {
boolean found = false;
for (int j = 0; j < CONTENT_LENGTH.length; j++) {
if (in.get(i + j) != CONTENT_LENGTH[j]) {
found = false;
break;
}
found = true;
}
if (found) {
// retrieve value from this position till next 0x0D 0x0A
StringBuilder contentLength = new StringBuilder();
for (int j = i + CONTENT_LENGTH.length; j < last; j++) {
if (in.get(j) == 0x0D) {
break;
}
contentLength.append(new String(
new byte[] { in.get(j) }));
}
// if content-length worth of data has been received then
// the message is complete
return Integer.parseInt(contentLength.toString().trim())
+ eoh == in.remaining();
}
}
}
}
 
// the message is not complete and we need more data
return false;
}
/**
* Decode body.
*
* @param in
* the in
*
* @return true, if message complete
*
* @throws Exception
* the exception
*/
/*
* public void decodeBody(BufferedReader reader, HttpMessage message,
* IoSession session) throws Exception { if (message instanceof
* HttpResponseMessage) { int code = ((HttpResponseMessage)
* message).getStatusCode(); if (code < 200 || code == 204 || code == 304) {
* message.setBody("status of msg " + code);
* session.removeAttribute(CURRENT_MESSAGE); } else {
* message.setBody(getContent(reader, session)); } } else {
* message.setBody(getContent(reader, session)); } }
*/
 
/**
* Exists at least one message complete.
*
* @param in
* the in
*
* @return true, if successful
*
* @throws Exception
* the exception
*/
private boolean ExistsAtLeastOneMessageComplete(ByteBuffer in)
throws Exception {
int last = in.remaining() - 1;
boolean foundStart = false;
boolean foundEnd = false;
if ((in.get(0) == HttpMessageEncoder.STX)
&& (in.get(0) == HttpMessageEncoder.ETX)) {
foundStart = true;
}
for (int i = 0; i < last; i++) {
if (in.get(i) == HttpMessageEncoder.ETX) {
foundEnd = true;
break;
}
}
return (foundStart && foundEnd);
}
/**
* Gets the content.
*
* @param reader
* the reader
* @param session
* the session
*
* @return the content
*
* @throws Exception
* the exception
*/
/*
* public String getContent(BufferedReader reader, IoSession session) throws
* Exception { StringBuffer result = new StringBuffer(); String line =
* reader.readLine(); boolean isAnotherMessagePresents = false; while (line !=
* null) { if (isFirstLineOfNewHTTPMessage(line)) {
* session.removeAttribute(CURRENT_MESSAGE);
* session.setAttribute(CURRENT_MESSAGE, getHttpMessage(line));
* isAnotherMessagePresents = true; break; } else { result.append(line); line
* = reader.readLine(); } } if (!isAnotherMessagePresents)
* session.removeAttribute(CURRENT_MESSAGE); return result.toString(); }
*/
 
/**
* Decode cookie.
*
* @param cookieStr
* the cookie str
*
* @return the cookie
*
* @throws Exception
* the exception
*/
public Cookie decodeCookie(String cookieStr) throws Exception {
/**
* Message complete.
*
* @param in
* the in
*
* @return true, if successful
*
* @throws Exception
* the exception
*/
private boolean messageComplete(ByteBuffer in) throws Exception {
int last = in.remaining() - 1;
if (in.remaining() < 4) {
return false;
}
 
Cookie cookie = null;
// to speed up things we check if the Http request is a GET or POST
if (in.get(0) == (byte) 'G' && in.get(1) == (byte) 'E' && in.get(2) == (byte) 'T') {
// Http GET request therefore the last 4 bytes should be 0x0D 0x0A
// 0x0D 0x0A
return in.get(last) == (byte) 0x0A && in.get(last - 1) == (byte) 0x0D && in.get(last - 2) == (byte) 0x0A
&& in.get(last - 3) == (byte) 0x0D;
} else if (in.get(0) == (byte) 'P' && in.get(1) == (byte) 'O' && in.get(2) == (byte) 'S' && in.get(3) == (byte) 'T') {
// Http POST request
// first the position of the 0x0D 0x0A 0x0D 0x0A bytes
int eoh = -1;
for (int i = last; i > 2; i--) {
if (in.get(i) == (byte) 0x0A && in.get(i - 1) == (byte) 0x0D && in.get(i - 2) == (byte) 0x0A
&& in.get(i - 3) == (byte) 0x0D) {
eoh = i + 1;
break;
}
}
if (eoh == -1) {
return false;
}
for (int i = 0; i < last; i++) {
boolean found = false;
for (int j = 0; j < CONTENT_LENGTH.length; j++) {
if (in.get(i + j) != CONTENT_LENGTH[j]) {
found = false;
break;
}
found = true;
}
if (found) {
// retrieve value from this position till next 0x0D 0x0A
StringBuilder contentLength = new StringBuilder();
for (int j = i + CONTENT_LENGTH.length; j < last; j++) {
if (in.get(j) == 0x0D) {
break;
}
contentLength.append(new String(new byte[] { in.get(j) }));
}
// if content-length worth of data has been received then
// the message is complete
return Integer.parseInt(contentLength.toString().trim()) + eoh == in.remaining();
}
}
}
 
String pairs[] = cookieStr.split(";");
for (int i = 0; i < pairs.length; i++) {
String nameValue[] = pairs[i].trim().split("=");
String name = nameValue[0].trim();
// the message is not complete and we need more data
return false;
}
 
// First one is the cookie name/value pair
if (i == 0) {
cookie = new Cookie(name, nameValue[1].trim());
continue;
}
/**
* Exists at least one message complete.
*
* @param in
* the in
*
* @return true, if successful
*
* @throws Exception
* the exception
*/
private boolean ExistsAtLeastOneMessageComplete(ByteBuffer in) throws Exception {
int last = in.remaining() - 1;
boolean foundStart = false;
boolean foundEnd = false;
if ((in.get(0) == HttpMessageEncoder.STX) && (in.get(0) == HttpMessageEncoder.ETX)) {
foundStart = true;
}
for (int i = 0; i < last; i++) {
if (in.get(i) == HttpMessageEncoder.ETX) {
foundEnd = true;
break;
}
}
return (foundStart && foundEnd);
}
 
if (name.equalsIgnoreCase(COOKIE_COMMENT)) {
cookie.setComment(nameValue[1].trim());
continue;
}
/**
* Decode cookie.
*
* @param cookieStr
* the cookie str
*
* @return the cookie
*
* @throws Exception
* the exception
*/
public Cookie decodeCookie(String cookieStr) throws Exception {
 
if (name.equalsIgnoreCase(COOKIE_PATH)) {
cookie.setPath(nameValue[1].trim());
}
Cookie cookie = null;
 
if (name.equalsIgnoreCase(COOKIE_SECURE)) {
cookie.setSecure(true);
}
String pairs[] = cookieStr.split(";");
for (int i = 0; i < pairs.length; i++) {
String nameValue[] = pairs[i].trim().split("=");
String name = nameValue[0].trim();
 
if (name.equalsIgnoreCase(COOKIE_VERSION)) {
cookie.setVersion(Integer.parseInt(nameValue[1]));
}
// First one is the cookie name/value pair
if (i == 0) {
cookie = new Cookie(name, nameValue[1].trim());
continue;
}
 
if (name.equalsIgnoreCase(COOKIE_MAX_AGE)) {
int age = Integer.parseInt(nameValue[1]);
cookie.setExpires(new Date(System.currentTimeMillis() + age
* 1000L));
}
if (name.equalsIgnoreCase(COOKIE_COMMENT)) {
cookie.setComment(nameValue[1].trim());
continue;
}
 
if (name.equalsIgnoreCase(COOKIE_EXPIRES)) {
// TODO
// cookie.setExpires( DateUtil.parseDate( nameValue[1] ) );
}
if (name.equalsIgnoreCase(COOKIE_PATH)) {
cookie.setPath(nameValue[1].trim());
}
 
if (name.equalsIgnoreCase(COOKIE_DOMAIN)) {
cookie.setDomain(nameValue[1]);
}
}
return cookie;
}
if (name.equalsIgnoreCase(COOKIE_SECURE)) {
cookie.setSecure(true);
}
 
/**
* Gets the http message.
*
* @param firstLine
* the first line
* @param session
* the session
*
* @return the http message
*
* @throws Exception
* the exception
*/
private HttpMessage getHttpMessage(String firstLine, IoSession session)
throws Exception {
HttpMessage result = null;
if (firstLine != null) {
boolean isRequest = isMethodPresents(firstLine);
if (isRequest) {
if (!isHttpProtocolPresents(firstLine)) {
session.setAttribute(INCOMPLETE_LINE, firstLine);
} else {
result = new HttpRequestMessage();
String[] url = firstLine.split(Constant.SPACE);
if (url.length < 3) {
return null;
}
((HttpRequestMessage) result).setMethod(url[0]
.toUpperCase());
((HttpRequestMessage) result).setRequestLine(url[1]);
((HttpRequestMessage) result).setHttpProtocol(url[2]);
}
} else {
// This is a response message
if (!isHttpProtocolPresents(firstLine)) {
session.setAttribute(INCOMPLETE_LINE, firstLine);
} else {
result = new HttpResponseMessage();
((HttpResponseMessage) result).setHttpProtocol(firstLine
.substring(0, 8));
((HttpResponseMessage) result).setStatusCode(Integer
.parseInt(firstLine.substring(9, 12)));
((HttpResponseMessage) result).setStatusMessage(firstLine
.substring(13));
}
}
if (name.equalsIgnoreCase(COOKIE_VERSION)) {
cookie.setVersion(Integer.parseInt(nameValue[1]));
}
 
}
return result;
}
if (name.equalsIgnoreCase(COOKIE_MAX_AGE)) {
int age = Integer.parseInt(nameValue[1]);
cookie.setExpires(new Date(System.currentTimeMillis() + age * 1000L));
}
 
/**
* Checks if is http protocol presents.
*
* @param line
* the line
*
* @return true, if is http protocol presents
*/
private boolean isHttpProtocolPresents(String line) {
return (line.contains(HttpMessage.PROTOCOL_HTTP_1_1) || line
.contains(HttpMessage.PROTOCOL_HTTP_1_0));
}
if (name.equalsIgnoreCase(COOKIE_EXPIRES)) {
// TODO
// cookie.setExpires( DateUtil.parseDate( nameValue[1] ) );
}
 
/**
* Checks if is method presents.
*
* @param line
* the line
*
* @return true, if is method presents
*/
private boolean isMethodPresents(String line) {
return (line.contains(HttpRequestMessage.GET_METHOD) || line
.contains(HttpRequestMessage.POST_METHOD));
}
if (name.equalsIgnoreCase(COOKIE_DOMAIN)) {
cookie.setDomain(nameValue[1]);
}
}
return cookie;
}
 
/**
* Gets the http message.
*
* @param firstLine
* the first line
* @param session
* the session
*
* @return the http message
*
* @throws Exception
* the exception
*/
private HttpMessage getHttpMessage(String firstLine, IoSession session) throws Exception {
HttpMessage result = null;
if (firstLine != null) {
boolean isRequest = isMethodPresents(firstLine);
if (isRequest) {
if (!isHttpProtocolPresents(firstLine)) {
session.setAttribute(INCOMPLETE_LINE, firstLine);
} else {
result = new HttpRequestMessage();
String[] url = firstLine.split(Constant.SPACE);
if (url.length < 3) {
return null;
}
((HttpRequestMessage) result).setMethod(url[0].toUpperCase());
((HttpRequestMessage) result).setRequestLine(url[1]);
((HttpRequestMessage) result).setHttpProtocol(url[2]);
}
} else {
// This is a response message
if (!isHttpProtocolPresents(firstLine)) {
session.setAttribute(INCOMPLETE_LINE, firstLine);
} else {
result = new HttpResponseMessage();
((HttpResponseMessage) result).setHttpProtocol(firstLine.substring(0, 8));
((HttpResponseMessage) result).setStatusCode(Integer.parseInt(firstLine.substring(9, 12)));
((HttpResponseMessage) result).setStatusMessage(firstLine.substring(13));
}
}
 
}
return result;
}
 
/**
* Checks if is http protocol presents.
*
* @param line
* the line
*
* @return true, if is http protocol presents
*/
private boolean isHttpProtocolPresents(String line) {
return (line.contains(HttpMessage.PROTOCOL_HTTP_1_1) || line.contains(HttpMessage.PROTOCOL_HTTP_1_0));
}
 
/**
* Checks if is method presents.
*
* @param line
* the line
*
* @return true, if is method presents
*/
private boolean isMethodPresents(String line) {
return (line.contains(HttpRequestMessage.GET_METHOD) || line.contains(HttpRequestMessage.POST_METHOD));
}
}
/trunk/Odis/OdisConnectionNio/standalone/src/main/java/org/ow2/odis/nio/HTTP/HttpRequestMessage.java
3,6 → 3,7
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
 
import org.ow2.odis.nio.Constant;
 
21,7 → 22,7
public static final String GET_METHOD = "GET";
 
/** The format. */
private static final SimpleDateFormat format = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z");
private static final SimpleDateFormat format = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z",Locale.US);
 
/** The method. */
private String method;
/trunk/Odis/OdisConnectionNio/standalone/src/main/java/org/ow2/odis/nio/NioClientConnection.java
555,7 → 555,7
} catch (OdisContextException e) {
LOGGER.log(BasicLevel.FATAL,
"NioClient : context-session map is wacky !");
e.printStackTrace();
// e.printStackTrace();
return false;
}
} else {