private void writeData(ByteBuffer chunk) throws IOException { boolean blocking = (response.getWriteListener() == null); int len = chunk.remaining(); int off = 0; // Write this chunk while (len > 0) { int thisTime = Math.min(len, outputMaxChunkSize); responseMessage.reset(); responseMessage.appendByte(Constants.JK_AJP13_SEND_BODY_CHUNK); chunk.limit(chunk.position() + thisTime); responseMessage.appendBytes(chunk); responseMessage.end(); socketWrapper.write(blocking, responseMessage.getBuffer(), 0, responseMessage.getLen()); socketWrapper.flush(blocking); len -= thisTime; off += thisTime; } bytesWritten += off; }
public AbstractAjpProcessor(int packetSize, AbstractEndpoint endpoint) { super(endpoint); this.packetSize = packetSize; request.setInputBuffer(new SocketInputBuffer()); requestHeaderMessage = new AjpMessage(packetSize); responseMessage = new AjpMessage(packetSize); bodyMessage = new AjpMessage(packetSize); // Set the getBody message buffer AjpMessage getBodyMessage = new AjpMessage(16); getBodyMessage.reset(); getBodyMessage.appendByte(Constants.JK_AJP13_GET_BODY_CHUNK); // Adjust read size if packetSize != default (Constants.MAX_PACKET_SIZE) getBodyMessage.appendInt(Constants.MAX_READ_SIZE + packetSize - Constants.MAX_PACKET_SIZE); getBodyMessage.end(); getBodyMessageArray = new byte[getBodyMessage.getLen()]; System.arraycopy(getBodyMessage.getBuffer(), 0, getBodyMessageArray, 0, getBodyMessage.getLen()); }
/** * Write a MessageBytes out at the current write position. * A null MessageBytes is encoded as a string with length 0. */ public void appendBytes(MessageBytes mb) { if (mb == null) { CoyoteLogger.AJP_LOGGER.cannotAppendNull(); appendInt(0); appendByte(0); return; } if (mb.getType() == MessageBytes.T_BYTES) { ByteChunk bc = mb.getByteChunk(); appendByteChunk(bc); } else if (mb.getType() == MessageBytes.T_CHARS) { CharChunk cc = mb.getCharChunk(); appendCharChunk(cc); } else { appendString(mb.toString()); } }
private void transferToResponseMsg(ByteBuffer buffer) { int thisTime = buffer.remaining(); if (thisTime > outputMaxChunkSize) { thisTime = outputMaxChunkSize; } responseMessage.reset(); responseMessage.appendByte(Constants.JK_AJP13_SEND_BODY_CHUNK); buffer.get(responseMessage.getBuffer(), responseMessage.pos, thisTime); responseMessage.end(); }
/** * Copy a chunk of bytes into the packet, starting at the current * write position. The chunk of bytes is encoded with the length * in two bytes first, then the data itself, and finally a * terminating \0 (which is <B>not</B> included in the encoded * length). * * @param b The array from which to copy bytes. * @param off The offset into the array at which to start copying * @param numBytes The number of bytes to copy. */ public void appendBytes(byte[] b, int off, int numBytes) { if (checkOverflow(numBytes)) { return; } appendInt(numBytes); System.arraycopy(b, off, buf, pos, numBytes); pos += numBytes; appendByte(0); }
/** Receive a chunk of data. Called to implement the * 'special' packet in ajp13 and to receive the data * after we send a GET_BODY packet */ public boolean receive() throws IOException { first = false; bodyMessage.reset(); readMessage(bodyMessage, false, false); // No data received. if (bodyMessage.getLen() == 0) { // just the header // Don't mark 'end of stream' for the first chunk. return false; } int blen = bodyMessage.peekInt(); if (blen == 0) { return false; } bodyMessage.getBytes(bodyBytes); empty = false; return true; }
byte methodCode = requestHeaderMessage.getByte(); if (methodCode != Constants.SC_M_JK_STORED) { String methodName = Constants.methodTransArray[(int)methodCode - 1]; requestHeaderMessage.getBytes(request.protocol()); requestHeaderMessage.getBytes(request.requestURI()); requestHeaderMessage.getBytes(request.remoteAddr()); requestHeaderMessage.getBytes(request.remoteHost()); requestHeaderMessage.getBytes(request.localName()); request.setLocalPort(requestHeaderMessage.getInt()); boolean isSSL = requestHeaderMessage.getByte() != 0; if (isSSL) { request.scheme().setString("https"); int hCount = requestHeaderMessage.getInt(); for(int i = 0 ; i < hCount ; i++) { String hName = null; int isc = requestHeaderMessage.peekInt(); int hId = isc & 0xFF; isc &= 0xFF00; if(0xA000 == isc) { requestHeaderMessage.getInt(); // To advance the read position hName = Constants.headerTransArray[hId - 1]; vMB = headers.addValue(hName);
/** * Read an AJP message. * * @return true if the message has been read, false if the short read * didn't return anything * @throws IOException any other failure, including incomplete reads */ protected boolean readMessage(AjpMessage message) throws IOException { byte[] buf = message.getBuffer(); read(buf, 0, message.getHeaderLength()); message.processHeader(); read(buf, message.getHeaderLength(), message.getLen()); return true; }
/** * Write a ByteChunk out at the current write position. * A null ByteChunk is encoded as a string with length 0. */ public void appendByteChunk(ByteChunk bc) { if (bc == null) { CoyoteLogger.AJP_LOGGER.cannotAppendNull(); appendInt(0); appendByte(0); return; } appendBytes(bc.getBytes(), bc.getStart(), bc.getLength()); }
/** * Copy a chunk of bytes into the packet, starting at the current * write position. The chunk of bytes is encoded with the length * in two bytes first, then the data itself, and finally a * terminating \0 (which is <B>not</B> included in the encoded * length). * * @param b The array from which to copy bytes. * @param off The offset into the array at which to start copying * @param numBytes The number of bytes to copy. */ public void appendBytes(byte[] b, int off, int numBytes) { if (pos + numBytes + 3 > buf.length) { CoyoteLogger.AJP_LOGGER.ajpMessageOverflow(numBytes, pos); if (log.isDebugEnabled()) { dump("Overflow/coBytes"); } return; } appendInt(numBytes); System.arraycopy(b, off, buf, pos, numBytes); pos += numBytes; appendByte(0); }
/** Receive a chunk of data. Called to implement the * 'special' packet in ajp13 and to receive the data * after we send a GET_BODY packet */ @Override public boolean receive() throws IOException { first = false; bodyMessage.reset(); readMessage(bodyMessage, true); // No data received. if (bodyMessage.getLen() == 0) { // just the header // Don't mark 'end of stream' for the first chunk. return false; } int blen = bodyMessage.peekInt(); if (blen == 0) { return false; } bodyMessage.getBodyBytes(bodyBytes); empty = false; return true; }
public int processHeader() { pos = 0; int mark = getInt(); len = getInt(); // Verify message signature if ((mark != 0x1234) && (mark != 0x4142)) { CoyoteLogger.AJP_LOGGER.invalidAjpMessage(mark); if (log.isDebugEnabled()) { dump("In: "); } len = 0; return -1; } if (log.isDebugEnabled()) { log.debug("Received " + len + " " + buf[0]); } return len; }
private void writeData(ByteChunk chunk) throws IOException { // Prevent timeout socketWrapper.access(); boolean blocking = (response.getWriteListener() == null); if (!blocking) { flushBufferedData(); } int len = chunk.getLength(); int off = 0; // Write this chunk while (responseMsgPos == -1 && len > 0) { int thisTime = len; if (thisTime > outputMaxChunkSize) { thisTime = outputMaxChunkSize; } responseMessage.reset(); responseMessage.appendByte(Constants.JK_AJP13_SEND_BODY_CHUNK); responseMessage.appendBytes(chunk.getBytes(), chunk.getOffset() + off, thisTime); responseMessage.end(); writeResponseMessage(blocking); len -= thisTime; off += thisTime; } bytesWritten += off; if (len > 0) { // Add this chunk to the buffer addToBuffers(chunk.getBuffer(), off, len); } }
int type = requestHeaderMessage.getByte(); if (type == Constants.JK_AJP13_CPING_REQUEST) { try {
/** * Read an AJP message. * * @return true if the message has been read, false if the short read * didn't return anything * @throws IOException any other failure, including incomplete reads */ protected boolean readMessage(AjpMessage message) throws IOException { byte[] buf = message.getBuffer(); int headerLength = message.getHeaderLength(); read(buf, 0, headerLength); int messageLength = message.processHeader(); if (messageLength < 0) { // Invalid AJP header signature // TODO: Throw some exception and close the connection to frontend. return false; } else if (messageLength == 0) { // Zero length message. return true; } else { read(buf, headerLength, messageLength); return true; } }
log.error(sm.getString("ajpmessage.null"), new NullPointerException()); appendInt(0); appendByte(0); return; appendByteChunk(mb.getByteChunk());
private void writeResponseMessage(boolean block) throws IOException { int len = responseMessage.getLen(); int written = 1; if (responseMsgPos == -1) { // New message. Advance the write position to the beginning responseMsgPos = 0; } while (written > 0 && responseMsgPos < len) { written = output( responseMessage.getBuffer(), responseMsgPos, len, block); responseMsgPos += written; } // Message fully written, reset the position for a new message. if (responseMsgPos == len) { responseMsgPos = -1; } }
@Override public void reset() { super.reset(); headers.clear(); }
private boolean checkOverflow(int numBytes) { if (pos + numBytes + 3 > buf.length) { log.error(sm.getString("ajpmessage.overflow", "" + numBytes, "" + pos), new ArrayIndexOutOfBoundsException()); if (log.isDebugEnabled()) { dump("Overflow/coBytes"); } return true; } return false; }
/** Receive a chunk of data. Called to implement the * 'special' packet in ajp13 and to receive the data * after we send a GET_BODY packet */ public boolean receive() throws IOException { first = false; bodyMessage.reset(); readMessage(bodyMessage, false, false); // No data received. if (bodyMessage.getLen() == 0) { // just the header // Don't mark 'end of stream' for the first chunk. return false; } int blen = bodyMessage.peekInt(); if (blen == 0) { return false; } bodyMessage.getBytes(bodyBytes); empty = false; return true; }