use of io.undertow.util.HttpString in project undertow by undertow-io.
the class AjpServerResponseConduit method processAJPHeader.
/**
* Handles generating the header if required, and adding it to the frame queue.
*
* No attempt is made to actually flush this, so a gathering write can be used to actually flush the data
*/
private void processAJPHeader() {
int oldState = this.state;
if (anyAreSet(oldState, FLAG_START)) {
PooledByteBuffer[] byteBuffers = null;
//merge the cookies into the header map
Connectors.flattenCookies(exchange);
PooledByteBuffer pooled = pool.allocate();
ByteBuffer buffer = pooled.getBuffer();
buffer.put((byte) 'A');
buffer.put((byte) 'B');
//we fill the size in later
buffer.put((byte) 0);
buffer.put((byte) 0);
buffer.put((byte) 4);
putInt(buffer, exchange.getStatusCode());
String reason = exchange.getReasonPhrase();
if (reason == null) {
reason = StatusCodes.getReason(exchange.getStatusCode());
}
if (reason.length() + 4 > buffer.remaining()) {
pooled.close();
throw UndertowMessages.MESSAGES.reasonPhraseToLargeForBuffer(reason);
}
putString(buffer, reason);
int headers = 0;
//we need to count the headers
final HeaderMap responseHeaders = exchange.getResponseHeaders();
for (HttpString name : responseHeaders.getHeaderNames()) {
headers += responseHeaders.get(name).size();
}
putInt(buffer, headers);
for (final HttpString header : responseHeaders.getHeaderNames()) {
for (String headerValue : responseHeaders.get(header)) {
if (buffer.remaining() < header.length() + headerValue.length() + 6) {
//if there is not enough room in the buffer we need to allocate more
buffer.flip();
if (byteBuffers == null) {
byteBuffers = new PooledByteBuffer[2];
byteBuffers[0] = pooled;
} else {
PooledByteBuffer[] old = byteBuffers;
byteBuffers = new PooledByteBuffer[old.length + 1];
System.arraycopy(old, 0, byteBuffers, 0, old.length);
}
pooled = pool.allocate();
byteBuffers[byteBuffers.length - 1] = pooled;
buffer = pooled.getBuffer();
}
Integer headerCode = HEADER_MAP.get(header);
if (headerCode != null) {
putInt(buffer, headerCode);
} else {
putHttpString(buffer, header);
}
putString(buffer, headerValue);
}
}
if (byteBuffers == null) {
int dataLength = buffer.position() - 4;
buffer.put(2, (byte) ((dataLength >> 8) & 0xFF));
buffer.put(3, (byte) (dataLength & 0xFF));
buffer.flip();
queueFrame(new PooledBufferFrameCallback(pooled), buffer);
} else {
ByteBuffer[] bufs = new ByteBuffer[byteBuffers.length];
for (int i = 0; i < bufs.length; ++i) {
bufs[i] = byteBuffers[i].getBuffer();
}
int dataLength = (int) (Buffers.remaining(bufs) - 4);
bufs[0].put(2, (byte) ((dataLength >> 8) & 0xFF));
bufs[0].put(3, (byte) (dataLength & 0xFF));
buffer.flip();
queueFrame(new PooledBuffersFrameCallback(byteBuffers), bufs);
}
state &= ~FLAG_START;
}
}
use of io.undertow.util.HttpString in project undertow by undertow-io.
the class HttpRequestParser method handleHeaderValue.
/**
* Parses a header value. This is called from the generated bytecode.
*
* @param buffer The buffer
* @param state The current state
* @param builder The exchange builder
* @return The number of bytes remaining
*/
@SuppressWarnings("unused")
final void handleHeaderValue(ByteBuffer buffer, ParseState state, HttpServerExchange builder) throws BadRequestException {
HttpString headerName = state.nextHeader;
StringBuilder stringBuilder = state.stringBuilder;
HashMap<HttpString, String> headerValuesCache = state.headerValuesCache;
if (stringBuilder.length() == 0) {
String existing = headerValuesCache.get(headerName);
if (existing != null) {
if (handleCachedHeader(existing, buffer, state, builder)) {
return;
}
}
}
handleHeaderValueCacheMiss(buffer, state, builder, headerName, headerValuesCache, stringBuilder);
}
use of io.undertow.util.HttpString in project undertow by undertow-io.
the class HttpResponseConduit method processStatefulWrite.
/**
* Handles writing out the header data in the case where is is too big to fit into a buffer. This is a much slower code path.
*/
private int processStatefulWrite(int state, final Object userData, int pos, int len) throws IOException {
ByteBuffer buffer = pooledBuffer.getBuffer();
long fiCookie = this.fiCookie;
int valueIdx = this.valueIdx;
int charIndex = this.charIndex;
int length;
String string = this.string;
HeaderValues headerValues = this.headerValues;
int res;
// BUFFER IS FLIPPED COMING IN
if (buffer.hasRemaining()) {
do {
res = next.write(buffer);
if (res == 0) {
return state;
}
} while (buffer.hasRemaining());
}
buffer.clear();
HeaderMap headers = exchange.getResponseHeaders();
// BUFFER IS NOW EMPTY FOR FILLING
for (; ; ) {
switch(state) {
case STATE_HDR_NAME:
{
final HttpString headerName = headerValues.getHeaderName();
length = headerName.length();
while (charIndex < length) {
if (buffer.hasRemaining()) {
buffer.put(headerName.byteAt(charIndex++));
} else {
buffer.flip();
do {
res = next.write(buffer);
if (res == 0) {
this.string = string;
this.headerValues = headerValues;
this.charIndex = charIndex;
this.fiCookie = fiCookie;
this.valueIdx = valueIdx;
return STATE_HDR_NAME;
}
} while (buffer.hasRemaining());
buffer.clear();
}
}
// fall thru
}
case STATE_HDR_D:
{
if (!buffer.hasRemaining()) {
buffer.flip();
do {
res = next.write(buffer);
if (res == 0) {
this.string = string;
this.headerValues = headerValues;
this.charIndex = charIndex;
this.fiCookie = fiCookie;
this.valueIdx = valueIdx;
return STATE_HDR_D;
}
} while (buffer.hasRemaining());
buffer.clear();
}
buffer.put((byte) ':');
// fall thru
}
case STATE_HDR_DS:
{
if (!buffer.hasRemaining()) {
buffer.flip();
do {
res = next.write(buffer);
if (res == 0) {
this.string = string;
this.headerValues = headerValues;
this.charIndex = charIndex;
this.fiCookie = fiCookie;
this.valueIdx = valueIdx;
return STATE_HDR_DS;
}
} while (buffer.hasRemaining());
buffer.clear();
}
buffer.put((byte) ' ');
//if (valueIterator == null) {
// valueIterator = exchange.getResponseHeaders().get(headerName).iterator();
//}
string = headerValues.get(valueIdx++);
charIndex = 0;
// fall thru
}
case STATE_HDR_VAL:
{
length = string.length();
while (charIndex < length) {
if (buffer.hasRemaining()) {
buffer.put((byte) string.charAt(charIndex++));
} else {
buffer.flip();
do {
res = next.write(buffer);
if (res == 0) {
this.string = string;
this.headerValues = headerValues;
this.charIndex = charIndex;
this.fiCookie = fiCookie;
this.valueIdx = valueIdx;
return STATE_HDR_VAL;
}
} while (buffer.hasRemaining());
buffer.clear();
}
}
charIndex = 0;
if (valueIdx == headerValues.size()) {
if (!buffer.hasRemaining()) {
if (flushHeaderBuffer(buffer, string, headerValues, charIndex, fiCookie, valueIdx))
return STATE_HDR_EOL_CR;
}
// CR
buffer.put((byte) 13);
if (!buffer.hasRemaining()) {
if (flushHeaderBuffer(buffer, string, headerValues, charIndex, fiCookie, valueIdx))
return STATE_HDR_EOL_LF;
}
// LF
buffer.put((byte) 10);
if ((fiCookie = headers.fiNextNonEmpty(fiCookie)) != -1L) {
headerValues = headers.fiCurrent(fiCookie);
valueIdx = 0;
state = STATE_HDR_NAME;
break;
} else {
if (!buffer.hasRemaining()) {
if (flushHeaderBuffer(buffer, string, headerValues, charIndex, fiCookie, valueIdx))
return STATE_HDR_FINAL_CR;
}
// CR
buffer.put((byte) 13);
if (!buffer.hasRemaining()) {
if (flushHeaderBuffer(buffer, string, headerValues, charIndex, fiCookie, valueIdx))
return STATE_HDR_FINAL_LF;
}
// LF
buffer.put((byte) 10);
this.fiCookie = -1;
this.valueIdx = 0;
this.string = null;
buffer.flip();
//for performance reasons we use a gather write if there is user data
if (userData == null) {
do {
res = next.write(buffer);
if (res == 0) {
return STATE_BUF_FLUSH;
}
} while (buffer.hasRemaining());
} else if (userData instanceof ByteBuffer) {
ByteBuffer[] b = { buffer, (ByteBuffer) userData };
do {
long r = next.write(b, 0, b.length);
if (r == 0 && buffer.hasRemaining()) {
return STATE_BUF_FLUSH;
}
} while (buffer.hasRemaining());
} else {
ByteBuffer[] b = new ByteBuffer[1 + len];
b[0] = buffer;
System.arraycopy(userData, pos, b, 1, len);
do {
long r = next.write(b, 0, b.length);
if (r == 0 && buffer.hasRemaining()) {
return STATE_BUF_FLUSH;
}
} while (buffer.hasRemaining());
}
bufferDone();
return STATE_BODY;
}
// not reached
}
// fall thru
}
// Clean-up states
case STATE_HDR_EOL_CR:
{
if (!buffer.hasRemaining()) {
if (flushHeaderBuffer(buffer, string, headerValues, charIndex, fiCookie, valueIdx))
return STATE_HDR_EOL_CR;
}
// CR
buffer.put((byte) 13);
}
case STATE_HDR_EOL_LF:
{
if (!buffer.hasRemaining()) {
if (flushHeaderBuffer(buffer, string, headerValues, charIndex, fiCookie, valueIdx))
return STATE_HDR_EOL_LF;
}
// LF
buffer.put((byte) 10);
if (valueIdx < headerValues.size()) {
state = STATE_HDR_NAME;
break;
} else if ((fiCookie = headers.fiNextNonEmpty(fiCookie)) != -1L) {
headerValues = headers.fiCurrent(fiCookie);
valueIdx = 0;
state = STATE_HDR_NAME;
break;
}
// fall thru
}
case STATE_HDR_FINAL_CR:
{
if (!buffer.hasRemaining()) {
if (flushHeaderBuffer(buffer, string, headerValues, charIndex, fiCookie, valueIdx))
return STATE_HDR_FINAL_CR;
}
// CR
buffer.put((byte) 13);
// fall thru
}
case STATE_HDR_FINAL_LF:
{
if (!buffer.hasRemaining()) {
if (flushHeaderBuffer(buffer, string, headerValues, charIndex, fiCookie, valueIdx))
return STATE_HDR_FINAL_LF;
}
// LF
buffer.put((byte) 10);
this.fiCookie = -1L;
this.valueIdx = 0;
this.string = null;
buffer.flip();
//for performance reasons we use a gather write if there is user data
if (userData == null) {
do {
res = next.write(buffer);
if (res == 0) {
return STATE_BUF_FLUSH;
}
} while (buffer.hasRemaining());
} else if (userData instanceof ByteBuffer) {
ByteBuffer[] b = { buffer, (ByteBuffer) userData };
do {
long r = next.write(b, 0, b.length);
if (r == 0 && buffer.hasRemaining()) {
return STATE_BUF_FLUSH;
}
} while (buffer.hasRemaining());
} else {
ByteBuffer[] b = new ByteBuffer[1 + len];
b[0] = buffer;
System.arraycopy(userData, pos, b, 1, len);
do {
long r = next.write(b, 0, b.length);
if (r == 0 && buffer.hasRemaining()) {
return STATE_BUF_FLUSH;
}
} while (buffer.hasRemaining());
}
// fall thru
}
case STATE_BUF_FLUSH:
{
// buffer was successfully flushed above
bufferDone();
return STATE_BODY;
}
default:
{
throw new IllegalStateException();
}
}
}
}
use of io.undertow.util.HttpString in project undertow by undertow-io.
the class MCMPHandler method processError.
/**
* Send an error message.
*
* @param type the error type
* @param errString the error string
* @param exchange the http server exchange
*/
static void processError(String type, String errString, HttpServerExchange exchange) {
exchange.setStatusCode(StatusCodes.INTERNAL_SERVER_ERROR);
exchange.getResponseHeaders().add(Headers.CONTENT_TYPE, CONTENT_TYPE);
exchange.getResponseHeaders().add(new HttpString("Version"), VERSION_PROTOCOL);
exchange.getResponseHeaders().add(new HttpString("Type"), type);
exchange.getResponseHeaders().add(new HttpString("Mess"), errString);
exchange.endExchange();
UndertowLogger.ROOT_LOGGER.mcmpProcessingError(type, errString);
}
use of io.undertow.util.HttpString in project undertow by undertow-io.
the class MCMPWebManager method buildRequestData.
static RequestData buildRequestData(final HttpServerExchange exchange, Map<String, Deque<String>> params) {
final RequestData data = new RequestData();
for (final Map.Entry<String, Deque<String>> entry : params.entrySet()) {
final HttpString name = new HttpString(entry.getKey());
data.addValues(name, entry.getValue());
}
return data;
}
Aggregations