Search in sources :

Example 6 with HeaderMap

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

the class SavedRequest method trySaveRequest.

public static void trySaveRequest(final HttpServerExchange exchange) {
    int maxSize = exchange.getConnection().getUndertowOptions().get(UndertowOptions.MAX_BUFFERED_REQUEST_SIZE, 16384);
    if (maxSize > 0) {
        //if this request has a body try and cache the response
        if (!exchange.isRequestComplete()) {
            final long requestContentLength = exchange.getRequestContentLength();
            if (requestContentLength > maxSize) {
                UndertowLogger.REQUEST_LOGGER.debugf("Request to %s was to large to save", exchange.getRequestURI());
                //failed to save the request, we just return
                return;
            }
            //TODO: we should really be used pooled buffers
            //TODO: we should probably limit the number of saved requests at any given time
            byte[] buffer = new byte[maxSize];
            int read = 0;
            int res = 0;
            InputStream in = exchange.getInputStream();
            try {
                while ((res = in.read(buffer, read, buffer.length - read)) > 0) {
                    read += res;
                    if (read == maxSize) {
                        UndertowLogger.REQUEST_LOGGER.debugf("Request to %s was to large to save", exchange.getRequestURI());
                        //failed to save the request, we just return
                        return;
                    }
                }
                HeaderMap headers = new HeaderMap();
                for (HeaderValues entry : exchange.getRequestHeaders()) {
                    if (entry.getHeaderName().equals(Headers.CONTENT_LENGTH) || entry.getHeaderName().equals(Headers.TRANSFER_ENCODING) || entry.getHeaderName().equals(Headers.CONNECTION)) {
                        continue;
                    }
                    headers.putAll(entry.getHeaderName(), entry);
                }
                SavedRequest request = new SavedRequest(buffer, read, exchange.getRequestMethod(), exchange.getRelativePath(), exchange.getRequestHeaders());
                final ServletRequestContext sc = exchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY);
                HttpSessionImpl session = sc.getCurrentServletContext().getSession(exchange, true);
                Session underlyingSession;
                if (System.getSecurityManager() == null) {
                    underlyingSession = session.getSession();
                } else {
                    underlyingSession = AccessController.doPrivileged(new HttpSessionImpl.UnwrapSessionAction(session));
                }
                underlyingSession.setAttribute(SESSION_KEY, request);
            } catch (IOException e) {
                UndertowLogger.REQUEST_IO_LOGGER.ioException(e);
            }
        }
    }
}
Also used : HeaderMap(io.undertow.util.HeaderMap) HttpSessionImpl(io.undertow.servlet.spec.HttpSessionImpl) InputStream(java.io.InputStream) HeaderValues(io.undertow.util.HeaderValues) ServletRequestContext(io.undertow.servlet.handlers.ServletRequestContext) IOException(java.io.IOException) HttpSession(javax.servlet.http.HttpSession) Session(io.undertow.server.session.Session)

Example 7 with HeaderMap

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

the class HttpRequestConduit method processWrite.

/**
     * Handles writing out the header data. It can also take a byte buffer of user
     * data, to enable both user data and headers to be written out in a single operation,
     * which has a noticeable performance impact.
     *
     * It is up to the caller to note the current position of this buffer before and after they
     * call this method, and use this to figure out how many bytes (if any) have been written.
     * @param state
     * @param userData
     * @return
     * @throws java.io.IOException
     */
private int processWrite(int state, final ByteBuffer userData) throws IOException {
    if (state == STATE_START) {
        pooledBuffer = pool.allocate();
    }
    ClientRequest request = this.request;
    ByteBuffer buffer = pooledBuffer.getBuffer();
    Iterator<HttpString> nameIterator = this.nameIterator;
    Iterator<String> valueIterator = this.valueIterator;
    int charIndex = this.charIndex;
    int length;
    String string = this.string;
    HttpString headerName = this.headerName;
    int res;
    // BUFFER IS FLIPPED COMING IN
    if (state != STATE_START && buffer.hasRemaining()) {
        log.trace("Flushing remaining buffer");
        do {
            res = next.write(buffer);
            if (res == 0) {
                return state;
            }
        } while (buffer.hasRemaining());
    }
    buffer.clear();
    // BUFFER IS NOW EMPTY FOR FILLING
    for (; ; ) {
        switch(state) {
            case STATE_BODY:
                {
                    // shouldn't be possible, but might as well do the right thing anyway
                    return state;
                }
            case STATE_START:
                {
                    log.trace("Starting request");
                    int len = request.getMethod().length() + request.getPath().length() + request.getProtocol().length() + 4;
                    // test that our buffer has enough space for the initial request line plus one more CR+LF
                    if (len <= buffer.remaining()) {
                        assert buffer.remaining() >= 50;
                        request.getMethod().appendTo(buffer);
                        buffer.put((byte) ' ');
                        string = request.getPath();
                        length = string.length();
                        for (charIndex = 0; charIndex < length; charIndex++) {
                            buffer.put((byte) string.charAt(charIndex));
                        }
                        buffer.put((byte) ' ');
                        request.getProtocol().appendTo(buffer);
                        buffer.put((byte) '\r').put((byte) '\n');
                    } else {
                        StringBuilder sb = new StringBuilder(len);
                        sb.append(request.getMethod().toString());
                        sb.append(" ");
                        sb.append(request.getPath());
                        sb.append(" ");
                        sb.append(request.getProtocol());
                        sb.append("\r\n");
                        string = sb.toString();
                        charIndex = 0;
                        state = STATE_URL;
                        break;
                    }
                    HeaderMap headers = request.getRequestHeaders();
                    nameIterator = headers.getHeaderNames().iterator();
                    if (!nameIterator.hasNext()) {
                        log.trace("No request headers");
                        buffer.put((byte) '\r').put((byte) '\n');
                        buffer.flip();
                        while (buffer.hasRemaining()) {
                            res = next.write(buffer);
                            if (res == 0) {
                                log.trace("Continuation");
                                return STATE_BUF_FLUSH;
                            }
                        }
                        pooledBuffer.close();
                        pooledBuffer = null;
                        log.trace("Body");
                        return STATE_BODY;
                    }
                    headerName = nameIterator.next();
                    charIndex = 0;
                // fall thru
                }
            case STATE_HDR_NAME:
                {
                    log.tracef("Processing header '%s'", headerName);
                    length = headerName.length();
                    while (charIndex < length) {
                        if (buffer.hasRemaining()) {
                            buffer.put(headerName.byteAt(charIndex++));
                        } else {
                            log.trace("Buffer flush");
                            buffer.flip();
                            do {
                                res = next.write(buffer);
                                if (res == 0) {
                                    this.string = string;
                                    this.headerName = headerName;
                                    this.charIndex = charIndex;
                                    this.valueIterator = valueIterator;
                                    this.nameIterator = nameIterator;
                                    log.trace("Continuation");
                                    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) {
                                log.trace("Continuation");
                                this.string = string;
                                this.headerName = headerName;
                                this.charIndex = charIndex;
                                this.valueIterator = valueIterator;
                                this.nameIterator = nameIterator;
                                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) {
                                log.trace("Continuation");
                                this.string = string;
                                this.headerName = headerName;
                                this.charIndex = charIndex;
                                this.valueIterator = valueIterator;
                                this.nameIterator = nameIterator;
                                return STATE_HDR_DS;
                            }
                        } while (buffer.hasRemaining());
                        buffer.clear();
                    }
                    buffer.put((byte) ' ');
                    if (valueIterator == null) {
                        valueIterator = request.getRequestHeaders().get(headerName).iterator();
                    }
                    assert valueIterator.hasNext();
                    string = valueIterator.next();
                    charIndex = 0;
                // fall thru
                }
            case STATE_HDR_VAL:
                {
                    log.tracef("Processing header value '%s'", string);
                    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.headerName = headerName;
                                    this.charIndex = charIndex;
                                    this.valueIterator = valueIterator;
                                    this.nameIterator = nameIterator;
                                    log.trace("Continuation");
                                    return STATE_HDR_VAL;
                                }
                            } while (buffer.hasRemaining());
                            buffer.clear();
                        }
                    }
                    charIndex = 0;
                    if (!valueIterator.hasNext()) {
                        if (!buffer.hasRemaining()) {
                            buffer.flip();
                            do {
                                res = next.write(buffer);
                                if (res == 0) {
                                    log.trace("Continuation");
                                    return STATE_HDR_EOL_CR;
                                }
                            } while (buffer.hasRemaining());
                            buffer.clear();
                        }
                        // CR
                        buffer.put((byte) 13);
                        if (!buffer.hasRemaining()) {
                            buffer.flip();
                            do {
                                res = next.write(buffer);
                                if (res == 0) {
                                    log.trace("Continuation");
                                    return STATE_HDR_EOL_LF;
                                }
                            } while (buffer.hasRemaining());
                            buffer.clear();
                        }
                        // LF
                        buffer.put((byte) 10);
                        if (nameIterator.hasNext()) {
                            headerName = nameIterator.next();
                            valueIterator = null;
                            state = STATE_HDR_NAME;
                            break;
                        } else {
                            if (!buffer.hasRemaining()) {
                                buffer.flip();
                                do {
                                    res = next.write(buffer);
                                    if (res == 0) {
                                        log.trace("Continuation");
                                        return STATE_HDR_FINAL_CR;
                                    }
                                } while (buffer.hasRemaining());
                                buffer.clear();
                            }
                            // CR
                            buffer.put((byte) 13);
                            if (!buffer.hasRemaining()) {
                                buffer.flip();
                                do {
                                    res = next.write(buffer);
                                    if (res == 0) {
                                        log.trace("Continuation");
                                        return STATE_HDR_FINAL_LF;
                                    }
                                } while (buffer.hasRemaining());
                                buffer.clear();
                            }
                            // LF
                            buffer.put((byte) 10);
                            this.nameIterator = null;
                            this.valueIterator = null;
                            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) {
                                        log.trace("Continuation");
                                        return STATE_BUF_FLUSH;
                                    }
                                } while (buffer.hasRemaining());
                            } else {
                                ByteBuffer[] b = { buffer, userData };
                                do {
                                    long r = next.write(b, 0, b.length);
                                    if (r == 0 && buffer.hasRemaining()) {
                                        log.trace("Continuation");
                                        return STATE_BUF_FLUSH;
                                    }
                                } while (buffer.hasRemaining());
                            }
                            pooledBuffer.close();
                            pooledBuffer = null;
                            log.trace("Body");
                            return STATE_BODY;
                        }
                    // not reached
                    }
                // fall thru
                }
            // Clean-up states
            case STATE_HDR_EOL_CR:
                {
                    if (!buffer.hasRemaining()) {
                        buffer.flip();
                        do {
                            res = next.write(buffer);
                            if (res == 0) {
                                log.trace("Continuation");
                                return STATE_HDR_EOL_CR;
                            }
                        } while (buffer.hasRemaining());
                        buffer.clear();
                    }
                    // CR
                    buffer.put((byte) 13);
                }
            case STATE_HDR_EOL_LF:
                {
                    if (!buffer.hasRemaining()) {
                        buffer.flip();
                        do {
                            res = next.write(buffer);
                            if (res == 0) {
                                log.trace("Continuation");
                                return STATE_HDR_EOL_LF;
                            }
                        } while (buffer.hasRemaining());
                        buffer.clear();
                    }
                    // LF
                    buffer.put((byte) 10);
                    if (valueIterator.hasNext()) {
                        state = STATE_HDR_NAME;
                        break;
                    } else if (nameIterator.hasNext()) {
                        headerName = nameIterator.next();
                        valueIterator = null;
                        state = STATE_HDR_NAME;
                        break;
                    }
                // fall thru
                }
            case STATE_HDR_FINAL_CR:
                {
                    if (!buffer.hasRemaining()) {
                        buffer.flip();
                        do {
                            res = next.write(buffer);
                            if (res == 0) {
                                log.trace("Continuation");
                                return STATE_HDR_FINAL_CR;
                            }
                        } while (buffer.hasRemaining());
                        buffer.clear();
                    }
                    // CR
                    buffer.put((byte) 13);
                // fall thru
                }
            case STATE_HDR_FINAL_LF:
                {
                    if (!buffer.hasRemaining()) {
                        buffer.flip();
                        do {
                            res = next.write(buffer);
                            if (res == 0) {
                                log.trace("Continuation");
                                return STATE_HDR_FINAL_LF;
                            }
                        } while (buffer.hasRemaining());
                        buffer.clear();
                    }
                    // LF
                    buffer.put((byte) 10);
                    this.nameIterator = null;
                    this.valueIterator = null;
                    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) {
                                log.trace("Continuation");
                                return STATE_BUF_FLUSH;
                            }
                        } while (buffer.hasRemaining());
                    } else {
                        ByteBuffer[] b = { buffer, userData };
                        do {
                            long r = next.write(b, 0, b.length);
                            if (r == 0 && buffer.hasRemaining()) {
                                log.trace("Continuation");
                                return STATE_BUF_FLUSH;
                            }
                        } while (buffer.hasRemaining());
                    }
                // fall thru
                }
            case STATE_BUF_FLUSH:
                {
                    // buffer was successfully flushed above
                    pooledBuffer.close();
                    pooledBuffer = null;
                    return STATE_BODY;
                }
            case STATE_URL:
                {
                    for (int i = charIndex; i < string.length(); ++i) {
                        if (!buffer.hasRemaining()) {
                            buffer.flip();
                            do {
                                res = next.write(buffer);
                                if (res == 0) {
                                    log.trace("Continuation");
                                    this.charIndex = i;
                                    this.string = string;
                                    this.state = STATE_URL;
                                    return STATE_URL;
                                }
                            } while (buffer.hasRemaining());
                            buffer.clear();
                        }
                        buffer.put((byte) string.charAt(i));
                    }
                    HeaderMap headers = request.getRequestHeaders();
                    nameIterator = headers.getHeaderNames().iterator();
                    state = STATE_HDR_NAME;
                    if (!nameIterator.hasNext()) {
                        log.trace("No request headers");
                        buffer.put((byte) '\r').put((byte) '\n');
                        buffer.flip();
                        while (buffer.hasRemaining()) {
                            res = next.write(buffer);
                            if (res == 0) {
                                log.trace("Continuation");
                                return STATE_BUF_FLUSH;
                            }
                        }
                        pooledBuffer.close();
                        pooledBuffer = null;
                        log.trace("Body");
                        return STATE_BODY;
                    }
                    headerName = nameIterator.next();
                    charIndex = 0;
                    break;
                }
            default:
                {
                    throw new IllegalStateException();
                }
        }
    }
}
Also used : HeaderMap(io.undertow.util.HeaderMap) HttpString(io.undertow.util.HttpString) ByteBuffer(java.nio.ByteBuffer) PooledByteBuffer(io.undertow.connector.PooledByteBuffer) ClientRequest(io.undertow.client.ClientRequest) HttpString(io.undertow.util.HttpString)

Example 8 with HeaderMap

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

the class HttpResponseConduit method processWrite.

/**
     * Handles writing out the header data. It can also take a byte buffer of user
     * data, to enable both user data and headers to be written out in a single operation,
     * which has a noticeable performance impact.
     * <p/>
     * It is up to the caller to note the current position of this buffer before and after they
     * call this method, and use this to figure out how many bytes (if any) have been written.
     *
     * @param state
     * @param userData
     * @return
     * @throws IOException
     */
private int processWrite(int state, final Object userData, int pos, int length) throws IOException {
    if (done || exchange == null) {
        throw new ClosedChannelException();
    }
    try {
        assert state != STATE_BODY;
        if (state == STATE_BUF_FLUSH) {
            final ByteBuffer byteBuffer = pooledBuffer.getBuffer();
            do {
                long res = 0;
                ByteBuffer[] data;
                if (userData == null || length == 0) {
                    res = next.write(byteBuffer);
                } else if (userData instanceof ByteBuffer) {
                    data = writevBuffer;
                    if (data == null) {
                        data = writevBuffer = new ByteBuffer[2];
                    }
                    data[0] = byteBuffer;
                    data[1] = (ByteBuffer) userData;
                    res = next.write(data, 0, 2);
                } else {
                    data = writevBuffer;
                    if (data == null || data.length < length + 1) {
                        data = writevBuffer = new ByteBuffer[length + 1];
                    }
                    data[0] = byteBuffer;
                    System.arraycopy(userData, pos, data, 1, length);
                    res = next.write(data, 0, data.length);
                }
                if (res == 0) {
                    return STATE_BUF_FLUSH;
                }
            } while (byteBuffer.hasRemaining());
            bufferDone();
            return STATE_BODY;
        } else if (state != STATE_START) {
            return processStatefulWrite(state, userData, pos, length);
        }
        //merge the cookies into the header map
        Connectors.flattenCookies(exchange);
        if (pooledBuffer == null) {
            pooledBuffer = pool.allocate();
        }
        ByteBuffer buffer = pooledBuffer.getBuffer();
        assert buffer.remaining() >= 50;
        exchange.getProtocol().appendTo(buffer);
        buffer.put((byte) ' ');
        int code = exchange.getStatusCode();
        assert 999 >= code && code >= 100;
        buffer.put((byte) (code / 100 + '0'));
        buffer.put((byte) (code / 10 % 10 + '0'));
        buffer.put((byte) (code % 10 + '0'));
        buffer.put((byte) ' ');
        String string = exchange.getReasonPhrase();
        if (string == null) {
            string = StatusCodes.getReason(code);
        }
        if (string.length() > buffer.remaining()) {
            pooledBuffer.close();
            pooledBuffer = null;
            truncateWrites();
            throw UndertowMessages.MESSAGES.reasonPhraseToLargeForBuffer(string);
        }
        writeString(buffer, string);
        buffer.put((byte) '\r').put((byte) '\n');
        int remaining = buffer.remaining();
        HeaderMap headers = exchange.getResponseHeaders();
        long fiCookie = headers.fastIterateNonEmpty();
        while (fiCookie != -1) {
            HeaderValues headerValues = headers.fiCurrent(fiCookie);
            HttpString header = headerValues.getHeaderName();
            int headerSize = header.length();
            int valueIdx = 0;
            while (valueIdx < headerValues.size()) {
                remaining -= (headerSize + 2);
                if (remaining < 0) {
                    this.fiCookie = fiCookie;
                    this.string = string;
                    this.headerValues = headerValues;
                    this.valueIdx = valueIdx;
                    this.charIndex = 0;
                    this.state = STATE_HDR_NAME;
                    buffer.flip();
                    return processStatefulWrite(STATE_HDR_NAME, userData, pos, length);
                }
                header.appendTo(buffer);
                buffer.put((byte) ':').put((byte) ' ');
                string = headerValues.get(valueIdx++);
                remaining -= (string.length() + 2);
                if (remaining < 2) {
                    //we use 2 here, to make sure we always have room for the final \r\n
                    this.fiCookie = fiCookie;
                    this.string = string;
                    this.headerValues = headerValues;
                    this.valueIdx = valueIdx;
                    this.charIndex = 0;
                    this.state = STATE_HDR_VAL;
                    buffer.flip();
                    return processStatefulWrite(STATE_HDR_VAL, userData, pos, length);
                }
                writeString(buffer, string);
                buffer.put((byte) '\r').put((byte) '\n');
            }
            fiCookie = headers.fiNextNonEmpty(fiCookie);
        }
        buffer.put((byte) '\r').put((byte) '\n');
        buffer.flip();
        do {
            long res = 0;
            ByteBuffer[] data;
            if (userData == null) {
                res = next.write(buffer);
            } else if (userData instanceof ByteBuffer) {
                data = writevBuffer;
                if (data == null) {
                    data = writevBuffer = new ByteBuffer[2];
                }
                data[0] = buffer;
                data[1] = (ByteBuffer) userData;
                res = next.write(data, 0, 2);
            } else {
                data = writevBuffer;
                if (data == null || data.length < length + 1) {
                    data = writevBuffer = new ByteBuffer[length + 1];
                }
                data[0] = buffer;
                System.arraycopy(userData, pos, data, 1, length);
                res = next.write(data, 0, length + 1);
            }
            if (res == 0) {
                return STATE_BUF_FLUSH;
            }
        } while (buffer.hasRemaining());
        bufferDone();
        return STATE_BODY;
    } catch (IOException | RuntimeException e) {
        //WFLY-4696, just to be safe
        if (pooledBuffer != null) {
            pooledBuffer.close();
            pooledBuffer = null;
        }
        throw e;
    }
}
Also used : ClosedChannelException(java.nio.channels.ClosedChannelException) HeaderMap(io.undertow.util.HeaderMap) HeaderValues(io.undertow.util.HeaderValues) HttpString(io.undertow.util.HttpString) IOException(java.io.IOException) ByteBuffer(java.nio.ByteBuffer) PooledByteBuffer(io.undertow.connector.PooledByteBuffer) HttpString(io.undertow.util.HttpString)

Example 9 with HeaderMap

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

the class HttpTransferEncoding method setupRequest.

public static void setupRequest(final HttpServerExchange exchange) {
    final HeaderMap requestHeaders = exchange.getRequestHeaders();
    final String connectionHeader = requestHeaders.getFirst(Headers.CONNECTION);
    final String transferEncodingHeader = requestHeaders.getLast(Headers.TRANSFER_ENCODING);
    final String contentLengthHeader = requestHeaders.getFirst(Headers.CONTENT_LENGTH);
    final HttpServerConnection connection = (HttpServerConnection) exchange.getConnection();
    //if we are already using the pipelineing buffer add it to the exchange
    PipeliningBufferingStreamSinkConduit pipeliningBuffer = connection.getPipelineBuffer();
    if (pipeliningBuffer != null) {
        pipeliningBuffer.setupPipelineBuffer(exchange);
    }
    ConduitStreamSourceChannel sourceChannel = connection.getChannel().getSourceChannel();
    sourceChannel.setConduit(connection.getReadDataStreamSourceConduit());
    boolean persistentConnection = persistentConnection(exchange, connectionHeader);
    if (transferEncodingHeader == null && contentLengthHeader == null) {
        if (persistentConnection && connection.getExtraBytes() != null && pipeliningBuffer == null && connection.getUndertowOptions().get(UndertowOptions.BUFFER_PIPELINED_DATA, false)) {
            pipeliningBuffer = new PipeliningBufferingStreamSinkConduit(connection.getOriginalSinkConduit(), connection.getByteBufferPool());
            connection.setPipelineBuffer(pipeliningBuffer);
            pipeliningBuffer.setupPipelineBuffer(exchange);
        }
        // no content - immediately start the next request, returning an empty stream for this one
        Connectors.terminateRequest(exchange);
    } else {
        persistentConnection = handleRequestEncoding(exchange, transferEncodingHeader, contentLengthHeader, connection, pipeliningBuffer, persistentConnection);
    }
    exchange.setPersistent(persistentConnection);
    if (!exchange.isRequestComplete() || connection.getExtraBytes() != null) {
        //if there is more data we suspend reads
        sourceChannel.setReadListener(null);
        sourceChannel.suspendReads();
    }
}
Also used : HeaderMap(io.undertow.util.HeaderMap) HttpString(io.undertow.util.HttpString) ConduitStreamSourceChannel(org.xnio.conduits.ConduitStreamSourceChannel)

Example 10 with HeaderMap

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

the class Http2ServerConnection method sendOutOfBandResponse.

@Override
public HttpServerExchange sendOutOfBandResponse(HttpServerExchange exchange) {
    if (exchange == null || !HttpContinue.requiresContinueResponse(exchange)) {
        throw UndertowMessages.MESSAGES.outOfBandResponseOnlyAllowedFor100Continue();
    }
    final HttpServerExchange newExchange = new HttpServerExchange(this);
    for (HttpString header : exchange.getRequestHeaders().getHeaderNames()) {
        newExchange.getRequestHeaders().putAll(header, exchange.getRequestHeaders().get(header));
    }
    newExchange.setProtocol(exchange.getProtocol());
    newExchange.setRequestMethod(exchange.getRequestMethod());
    exchange.setRequestURI(exchange.getRequestURI(), exchange.isHostIncludedInRequestURI());
    exchange.setRequestPath(exchange.getRequestPath());
    exchange.setRelativePath(exchange.getRelativePath());
    newExchange.setPersistent(true);
    Connectors.terminateRequest(newExchange);
    newExchange.addResponseWrapper(new ConduitWrapper<StreamSinkConduit>() {

        @Override
        public StreamSinkConduit wrap(ConduitFactory<StreamSinkConduit> factory, HttpServerExchange exchange) {
            HeaderMap headers = newExchange.getResponseHeaders();
            DateUtils.addDateHeaderIfRequired(exchange);
            headers.add(STATUS, exchange.getStatusCode());
            Connectors.flattenCookies(exchange);
            Http2HeadersStreamSinkChannel sink = new Http2HeadersStreamSinkChannel(channel, requestChannel.getStreamId(), headers);
            StreamSinkChannelWrappingConduit ret = new StreamSinkChannelWrappingConduit(sink);
            ret.setWriteReadyHandler(new WriteReadyHandler.ChannelListenerHandler(Connectors.getConduitSinkChannel(exchange)));
            return ret;
        }
    });
    continueSent = true;
    return newExchange;
}
Also used : HttpServerExchange(io.undertow.server.HttpServerExchange) Http2HeadersStreamSinkChannel(io.undertow.protocols.http2.Http2HeadersStreamSinkChannel) HeaderMap(io.undertow.util.HeaderMap) StreamSinkConduit(org.xnio.conduits.StreamSinkConduit) StreamSinkChannelWrappingConduit(org.xnio.conduits.StreamSinkChannelWrappingConduit) HttpString(io.undertow.util.HttpString)

Aggregations

HeaderMap (io.undertow.util.HeaderMap)31 HttpString (io.undertow.util.HttpString)18 HeaderValues (io.undertow.util.HeaderValues)9 ByteBuffer (java.nio.ByteBuffer)7 PooledByteBuffer (io.undertow.connector.PooledByteBuffer)6 HttpServerExchange (io.undertow.server.HttpServerExchange)6 IOException (java.io.IOException)6 Http2HeadersStreamSinkChannel (io.undertow.protocols.http2.Http2HeadersStreamSinkChannel)3 HttpHandler (io.undertow.server.HttpHandler)3 ArrayList (java.util.ArrayList)3 HashMap (java.util.HashMap)3 Map (java.util.Map)3 BeforeClass (org.junit.BeforeClass)3 ClientRequest (io.undertow.client.ClientRequest)2 DigestAlgorithm (io.undertow.security.idm.DigestAlgorithm)2 ImmediatePooledByteBuffer (io.undertow.util.ImmediatePooledByteBuffer)2 ParameterLimitException (io.undertow.util.ParameterLimitException)2 InputStream (java.io.InputStream)2 OutputStream (java.io.OutputStream)2 List (java.util.List)2