Search in sources :

Example 41 with HttpString

use of io.undertow.util.HttpString in project undertow by undertow-io.

the class HpackDecoder method readHeaderName.

private HttpString readHeaderName(ByteBuffer buffer, int prefixLength) throws HpackException {
    //unget the byte
    buffer.position(buffer.position() - 1);
    int index = Hpack.decodeInteger(buffer, prefixLength);
    if (index == -1) {
        return null;
    } else if (index != 0) {
        return handleIndexedHeaderName(index);
    } else {
        String string = readHpackString(buffer);
        if (string == null) {
            return null;
        }
        return new HttpString(string);
    }
}
Also used : HttpString(io.undertow.util.HttpString) HttpString(io.undertow.util.HttpString)

Example 42 with HttpString

use of io.undertow.util.HttpString in project undertow by undertow-io.

the class HpackEncoder method encode.

/**
     * Encodes the headers into a buffer.
     *
     * @param headers
     * @param target
     */
public State encode(HeaderMap headers, ByteBuffer target) {
    if (overflowData != null) {
        for (int i = overflowPos; i < overflowLength; ++i) {
            if (!target.hasRemaining()) {
                overflowPos = i;
                return State.OVERFLOW;
            }
            target.put(overflowData[i]);
        }
        overflowData = null;
    }
    long it = headersIterator;
    if (headersIterator == -1) {
        handleTableSizeChange(target);
        //new headers map
        it = headers.fastIterate();
        currentHeaders = headers;
    } else {
        if (headers != currentHeaders) {
            throw new IllegalStateException();
        }
    }
    while (it != -1) {
        HeaderValues values = headers.fiCurrent(it);
        boolean skip = false;
        if (firstPass) {
            if (values.getHeaderName().byteAt(0) != ':') {
                skip = true;
            }
        } else {
            if (values.getHeaderName().byteAt(0) == ':') {
                skip = true;
            }
        }
        if (SKIP.contains(values.getHeaderName())) {
            //ignore connection specific headers
            skip = true;
        }
        if (!skip) {
            for (int i = 0; i < values.size(); ++i) {
                HttpString headerName = values.getHeaderName();
                //we use 11 to make sure we have enough room for the variable length itegers
                int required = 11 + headerName.length();
                String val = values.get(i);
                for (int v = 0; v < val.length(); ++v) {
                    char c = val.charAt(v);
                    if (c == '\r' || c == '\n') {
                        val = val.replace('\r', ' ').replace('\n', ' ');
                        break;
                    }
                }
                TableEntry tableEntry = findInTable(headerName, val);
                required += (1 + val.length());
                boolean overflowing = false;
                ByteBuffer current = target;
                if (current.remaining() < required) {
                    overflowing = true;
                    current = ByteBuffer.wrap(overflowData = new byte[required]);
                    overflowPos = 0;
                }
                //only index if it will fit
                boolean canIndex = hpackHeaderFunction.shouldUseIndexing(headerName, val) && (headerName.length() + val.length() + 32) < maxTableSize;
                if (tableEntry == null && canIndex) {
                    //add the entry to the dynamic table
                    current.put((byte) (1 << 6));
                    writeHuffmanEncodableName(current, headerName);
                    writeHuffmanEncodableValue(current, headerName, val);
                    addToDynamicTable(headerName, val);
                } else if (tableEntry == null) {
                    //literal never indexed
                    current.put((byte) (1 << 4));
                    writeHuffmanEncodableName(current, headerName);
                    writeHuffmanEncodableValue(current, headerName, val);
                } else {
                    //so we know something is already in the table
                    if (val.equals(tableEntry.value)) {
                        //the whole thing is in the table
                        current.put((byte) (1 << 7));
                        encodeInteger(current, tableEntry.getPosition(), 7);
                    } else {
                        if (canIndex) {
                            //add the entry to the dynamic table
                            current.put((byte) (1 << 6));
                            encodeInteger(current, tableEntry.getPosition(), 6);
                            writeHuffmanEncodableValue(current, headerName, val);
                            addToDynamicTable(headerName, val);
                        } else {
                            current.put((byte) (1 << 4));
                            encodeInteger(current, tableEntry.getPosition(), 4);
                            writeHuffmanEncodableValue(current, headerName, val);
                        }
                    }
                }
                if (overflowing) {
                    it = headers.fiNext(it);
                    this.headersIterator = it;
                    this.overflowLength = current.position();
                    return State.OVERFLOW;
                }
            }
        }
        it = headers.fiNext(it);
        if (it == -1 && firstPass) {
            firstPass = false;
            it = headers.fastIterate();
        }
    }
    headersIterator = -1;
    firstPass = true;
    return State.COMPLETE;
}
Also used : HeaderValues(io.undertow.util.HeaderValues) HttpString(io.undertow.util.HttpString) ByteBuffer(java.nio.ByteBuffer) HttpString(io.undertow.util.HttpString)

Example 43 with HttpString

use of io.undertow.util.HttpString in project undertow by undertow-io.

the class AjpClientRequestClientStreamSinkChannel method createFrameHeaderImpl.

private SendFrameHeader createFrameHeaderImpl() {
    if (discardMode) {
        getBuffer().clear();
        getBuffer().flip();
        return new SendFrameHeader(new ImmediatePooledByteBuffer(ByteBuffer.wrap(new byte[0])));
    }
    PooledByteBuffer pooledHeaderBuffer = getChannel().getBufferPool().allocate();
    try {
        final ByteBuffer buffer = pooledHeaderBuffer.getBuffer();
        ByteBuffer dataBuffer = getBuffer();
        int dataInBuffer = dataBuffer.remaining();
        if (!firstFrameWritten && requestedChunkSize == 0) {
            //we are waiting on a read body chunk
            return new SendFrameHeader(dataInBuffer, null);
        }
        int maxData = getChannel().getSettings().get(UndertowOptions.MAX_AJP_PACKET_SIZE, DEFAULT_MAX_DATA_SIZE) - 6;
        if (!firstFrameWritten) {
            String contentLength = headers.getFirst(Headers.CONTENT_LENGTH);
            if (contentLength != null) {
                dataSize = Long.parseLong(contentLength);
                requestedChunkSize = maxData;
                if (dataInBuffer > dataSize) {
                    throw UndertowMessages.MESSAGES.fixedLengthOverflow();
                }
            } else if (isWritesShutdown() && !headers.contains(Headers.TRANSFER_ENCODING)) {
                //writes are shut down, go to fixed length
                headers.put(Headers.CONTENT_LENGTH, dataInBuffer);
                dataSize = dataInBuffer;
                requestedChunkSize = maxData;
            } else {
                headers.put(Headers.TRANSFER_ENCODING, Headers.CHUNKED.toString());
                dataSize = -1;
                requestedChunkSize = 0;
            }
            firstFrameWritten = true;
            final String path;
            final String queryString;
            int qsIndex = this.path.indexOf('?');
            if (qsIndex == -1) {
                path = this.path;
                queryString = null;
            } else {
                path = this.path.substring(0, qsIndex);
                queryString = this.path.substring(qsIndex + 1);
            }
            buffer.put((byte) 0x12);
            buffer.put((byte) 0x34);
            //we fill the size in later
            buffer.put((byte) 0);
            buffer.put((byte) 0);
            buffer.put((byte) 2);
            boolean storeMethod = false;
            Integer methodNp = AjpConstants.HTTP_METHODS_MAP.get(method);
            if (methodNp == null) {
                methodNp = 0xFF;
                storeMethod = true;
            }
            buffer.put((byte) (int) methodNp);
            AjpUtils.putHttpString(buffer, protocol);
            putString(buffer, path);
            putString(buffer, notNull(attachable.getAttachment(ProxiedRequestAttachments.REMOTE_ADDRESS)));
            putString(buffer, notNull(attachable.getAttachment(ProxiedRequestAttachments.REMOTE_HOST)));
            putString(buffer, notNull(attachable.getAttachment(ProxiedRequestAttachments.SERVER_NAME)));
            AjpUtils.putInt(buffer, notNull(attachable.getAttachment(ProxiedRequestAttachments.SERVER_PORT)));
            buffer.put((byte) (notNull(attachable.getAttachment(ProxiedRequestAttachments.IS_SSL)) ? 1 : 0));
            int headers = 0;
            //we need to count the headers
            final HeaderMap responseHeaders = this.headers;
            for (HttpString name : responseHeaders.getHeaderNames()) {
                headers += responseHeaders.get(name).size();
            }
            AjpUtils.putInt(buffer, headers);
            for (final HttpString header : responseHeaders.getHeaderNames()) {
                for (String headerValue : responseHeaders.get(header)) {
                    Integer headerCode = AjpConstants.HEADER_MAP.get(header);
                    if (headerCode != null) {
                        AjpUtils.putInt(buffer, headerCode);
                    } else {
                        AjpUtils.putHttpString(buffer, header);
                    }
                    putString(buffer, headerValue);
                }
            }
            if (queryString != null) {
                //query_string
                buffer.put((byte) ATTR_QUERY_STRING);
                putString(buffer, queryString);
            }
            String remoteUser = attachable.getAttachment(ProxiedRequestAttachments.REMOTE_USER);
            if (remoteUser != null) {
                buffer.put((byte) ATTR_REMOTE_USER);
                putString(buffer, remoteUser);
            }
            String authType = attachable.getAttachment(ProxiedRequestAttachments.AUTH_TYPE);
            if (authType != null) {
                buffer.put((byte) ATTR_AUTH_TYPE);
                putString(buffer, authType);
            }
            String route = attachable.getAttachment(ProxiedRequestAttachments.ROUTE);
            if (route != null) {
                buffer.put((byte) ATTR_ROUTE);
                putString(buffer, route);
            }
            String sslCert = attachable.getAttachment(ProxiedRequestAttachments.SSL_CERT);
            if (sslCert != null) {
                buffer.put((byte) ATTR_SSL_CERT);
                putString(buffer, sslCert);
            }
            String sslCypher = attachable.getAttachment(ProxiedRequestAttachments.SSL_CYPHER);
            if (sslCypher != null) {
                buffer.put((byte) ATTR_SSL_CIPHER);
                putString(buffer, sslCypher);
            }
            byte[] sslSession = attachable.getAttachment(ProxiedRequestAttachments.SSL_SESSION_ID);
            if (sslSession != null) {
                buffer.put((byte) ATTR_SSL_SESSION);
                putString(buffer, FlexBase64.encodeString(sslSession, false));
            }
            Integer sslKeySize = attachable.getAttachment(ProxiedRequestAttachments.SSL_KEY_SIZE);
            if (sslKeySize != null) {
                buffer.put((byte) ATTR_SSL_KEY_SIZE);
                putString(buffer, sslKeySize.toString());
            }
            String secret = attachable.getAttachment(ProxiedRequestAttachments.SECRET);
            if (secret != null) {
                buffer.put((byte) ATTR_SECRET);
                putString(buffer, secret);
            }
            if (storeMethod) {
                buffer.put((byte) ATTR_STORED_METHOD);
                putString(buffer, method.toString());
            }
            buffer.put((byte) 0xFF);
            int dataLength = buffer.position() - 4;
            buffer.put(2, (byte) ((dataLength >> 8) & 0xFF));
            buffer.put(3, (byte) (dataLength & 0xFF));
        }
        if (dataSize == 0) {
            //no data, just write out this frame and we are done
            buffer.flip();
            return new SendFrameHeader(pooledHeaderBuffer);
        } else if (requestedChunkSize > 0) {
            if (isWritesShutdown() && dataInBuffer == 0) {
                buffer.put((byte) 0x12);
                buffer.put((byte) 0x34);
                buffer.put((byte) 0x00);
                buffer.put((byte) 0x02);
                buffer.put((byte) 0x00);
                buffer.put((byte) 0x00);
                buffer.flip();
                return new SendFrameHeader(pooledHeaderBuffer);
            }
            int remaining = dataInBuffer;
            remaining = Math.min(remaining, maxData);
            remaining = Math.min(remaining, requestedChunkSize);
            int bodySize = remaining + 2;
            buffer.put((byte) 0x12);
            buffer.put((byte) 0x34);
            buffer.put((byte) ((bodySize >> 8) & 0xFF));
            buffer.put((byte) (bodySize & 0xFF));
            buffer.put((byte) ((remaining >> 8) & 0xFF));
            buffer.put((byte) (remaining & 0xFF));
            requestedChunkSize = 0;
            if (remaining < dataInBuffer) {
                dataBuffer.limit(getBuffer().position() + remaining);
                buffer.flip();
                return new SendFrameHeader(dataInBuffer - remaining, pooledHeaderBuffer, dataSize < 0);
            } else {
                buffer.flip();
                return new SendFrameHeader(0, pooledHeaderBuffer, dataSize < 0);
            }
        } else {
            //chunked. We just write the headers, and leave all the data in the buffer
            //they need to send us a read body chunk in order to get any data
            buffer.flip();
            if (buffer.remaining() == 0) {
                pooledHeaderBuffer.close();
                return new SendFrameHeader(dataInBuffer, null, true);
            }
            dataBuffer.limit(dataBuffer.position());
            return new SendFrameHeader(dataInBuffer, pooledHeaderBuffer, true);
        }
    } catch (BufferOverflowException e) {
        //TODO: UNDERTOW-901
        pooledHeaderBuffer.close();
        markBroken();
        throw e;
    }
}
Also used : HeaderMap(io.undertow.util.HeaderMap) ImmediatePooledByteBuffer(io.undertow.util.ImmediatePooledByteBuffer) PooledByteBuffer(io.undertow.connector.PooledByteBuffer) AjpUtils.putString(io.undertow.protocols.ajp.AjpUtils.putString) HttpString(io.undertow.util.HttpString) BufferOverflowException(java.nio.BufferOverflowException) SendFrameHeader(io.undertow.server.protocol.framed.SendFrameHeader) ByteBuffer(java.nio.ByteBuffer) ImmediatePooledByteBuffer(io.undertow.util.ImmediatePooledByteBuffer) PooledByteBuffer(io.undertow.connector.PooledByteBuffer) ImmediatePooledByteBuffer(io.undertow.util.ImmediatePooledByteBuffer) HttpString(io.undertow.util.HttpString)

Example 44 with HttpString

use of io.undertow.util.HttpString in project undertow by undertow-io.

the class RoutingHandler method addAll.

public synchronized RoutingHandler addAll(RoutingHandler routingHandler) {
    for (Entry<HttpString, PathTemplateMatcher<RoutingMatch>> entry : routingHandler.getMatches().entrySet()) {
        HttpString method = entry.getKey();
        PathTemplateMatcher<RoutingMatch> matcher = matches.get(method);
        if (matcher == null) {
            matches.put(method, matcher = new PathTemplateMatcher<>());
        }
        matcher.addAll(entry.getValue());
        // PathTemplates which we want to ignore here so it does not crash.
        for (PathTemplate template : entry.getValue().getPathTemplates()) {
            if (allMethodsMatcher.get(template.getTemplateString()) == null) {
                allMethodsMatcher.add(template, new RoutingMatch());
            }
        }
    }
    return this;
}
Also used : PathTemplateMatcher(io.undertow.util.PathTemplateMatcher) PathTemplate(io.undertow.util.PathTemplate) HttpString(io.undertow.util.HttpString)

Example 45 with HttpString

use of io.undertow.util.HttpString in project undertow by undertow-io.

the class MCMPHandler method parseFormData.

/**
     * Transform the form data into an intermediate request data which can me used
     * by the web manager
     *
     * @param exchange    the http server exchange
     * @return
     * @throws IOException
     */
RequestData parseFormData(final HttpServerExchange exchange) throws IOException {
    // Read post parameters
    final FormDataParser parser = parserFactory.createParser(exchange);
    final FormData formData = parser.parseBlocking();
    final RequestData data = new RequestData();
    for (String name : formData) {
        final HttpString key = new HttpString(name);
        data.add(key, formData.get(name));
    }
    return data;
}
Also used : FormData(io.undertow.server.handlers.form.FormData) FormDataParser(io.undertow.server.handlers.form.FormDataParser) HttpString(io.undertow.util.HttpString) HttpString(io.undertow.util.HttpString)

Aggregations

HttpString (io.undertow.util.HttpString)59 IOException (java.io.IOException)18 HttpServerExchange (io.undertow.server.HttpServerExchange)16 HeaderMap (io.undertow.util.HeaderMap)15 HttpHandler (io.undertow.server.HttpHandler)9 ByteBuffer (java.nio.ByteBuffer)9 Map (java.util.Map)8 HashMap (java.util.HashMap)7 PooledByteBuffer (io.undertow.connector.PooledByteBuffer)6 HeaderValues (io.undertow.util.HeaderValues)6 ClientRequest (io.undertow.client.ClientRequest)5 Session (io.undertow.server.session.Session)5 URISyntaxException (java.net.URISyntaxException)5 ArrayList (java.util.ArrayList)5 Test (org.junit.Test)5 InMemorySessionManager (io.undertow.server.session.InMemorySessionManager)4 SessionAttachmentHandler (io.undertow.server.session.SessionAttachmentHandler)4 SessionManager (io.undertow.server.session.SessionManager)4 List (java.util.List)4 TypeConverter (org.apache.camel.TypeConverter)4