Search in sources :

Example 1 with HttpString

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

the class HttpRequestParser method handleHeaderValueCacheMiss.

private void handleHeaderValueCacheMiss(ByteBuffer buffer, ParseState state, HttpServerExchange builder, HttpString headerName, HashMap<HttpString, String> headerValuesCache, StringBuilder stringBuilder) throws BadRequestException {
    int parseState = state.parseState;
    while (buffer.hasRemaining() && parseState == NORMAL) {
        final byte next = buffer.get();
        if (next == '\r') {
            parseState = BEGIN_LINE_END;
        } else if (next == '\n') {
            parseState = LINE_END;
        } else if (next == ' ' || next == '\t') {
            parseState = WHITESPACE;
        } else {
            stringBuilder.append((char) (next & 0xFF));
        }
    }
    while (buffer.hasRemaining()) {
        final byte next = buffer.get();
        switch(parseState) {
            case NORMAL:
                {
                    if (next == '\r') {
                        parseState = BEGIN_LINE_END;
                    } else if (next == '\n') {
                        parseState = LINE_END;
                    } else if (next == ' ' || next == '\t') {
                        parseState = WHITESPACE;
                    } else {
                        stringBuilder.append((char) (next & 0xFF));
                    }
                    break;
                }
            case WHITESPACE:
                {
                    if (next == '\r') {
                        parseState = BEGIN_LINE_END;
                    } else if (next == '\n') {
                        parseState = LINE_END;
                    } else if (next == ' ' || next == '\t') {
                    } else {
                        if (stringBuilder.length() > 0) {
                            stringBuilder.append(' ');
                        }
                        stringBuilder.append((char) (next & 0xFF));
                        parseState = NORMAL;
                    }
                    break;
                }
            case LINE_END:
            case BEGIN_LINE_END:
                {
                    if (next == '\n' && parseState == BEGIN_LINE_END) {
                        parseState = LINE_END;
                    } else if (next == '\t' || next == ' ') {
                        //this is a continuation
                        parseState = WHITESPACE;
                    } else {
                        //we have a header
                        String headerValue = stringBuilder.toString();
                        if (++state.mapCount > maxHeaders) {
                            throw new BadRequestException(UndertowMessages.MESSAGES.tooManyHeaders(maxHeaders));
                        }
                        //TODO: we need to decode this according to RFC-2047 if we have seen a =? symbol
                        builder.getRequestHeaders().add(headerName, headerValue);
                        if (headerValuesCache.size() < maxHeaders) {
                            //we have a limit on how many we can cache
                            //to prevent memory filling and hash collision attacks
                            headerValuesCache.put(headerName, headerValue);
                        }
                        state.nextHeader = null;
                        state.leftOver = next;
                        state.stringBuilder.setLength(0);
                        if (next == '\r') {
                            parseState = AWAIT_DATA_END;
                        } else if (next == '\n') {
                            state.state = ParseState.PARSE_COMPLETE;
                            return;
                        } else {
                            state.state = ParseState.HEADER;
                            state.parseState = 0;
                            return;
                        }
                    }
                    break;
                }
            case AWAIT_DATA_END:
                {
                    state.state = ParseState.PARSE_COMPLETE;
                    return;
                }
        }
    }
    //we only write to the state if we did not finish parsing
    state.parseState = parseState;
}
Also used : HttpString(io.undertow.util.HttpString)

Example 2 with HttpString

use of io.undertow.util.HttpString in project camel by apache.

the class UndertowConsumer method handleRequest.

@Override
public void handleRequest(HttpServerExchange httpExchange) throws Exception {
    HttpString requestMethod = httpExchange.getRequestMethod();
    if (Methods.OPTIONS.equals(requestMethod) && !getEndpoint().isOptionsEnabled()) {
        String allowedMethods;
        if (getEndpoint().getHttpMethodRestrict() != null) {
            allowedMethods = "OPTIONS," + getEndpoint().getHttpMethodRestrict();
        } else {
            allowedMethods = "GET,HEAD,POST,PUT,DELETE,TRACE,OPTIONS,CONNECT,PATCH";
        }
        //return list of allowed methods in response headers
        httpExchange.setStatusCode(StatusCodes.OK);
        httpExchange.getResponseHeaders().put(ExchangeHeaders.CONTENT_TYPE, MimeMappings.DEFAULT_MIME_MAPPINGS.get("txt"));
        httpExchange.getResponseHeaders().put(ExchangeHeaders.CONTENT_LENGTH, 0);
        httpExchange.getResponseHeaders().put(Headers.ALLOW, allowedMethods);
        httpExchange.getResponseSender().close();
        return;
    }
    //perform blocking operation on exchange
    if (httpExchange.isInIoThread()) {
        httpExchange.dispatch(this);
        return;
    }
    //create new Exchange
    //binding is used to extract header and payload(if available)
    Exchange camelExchange = getEndpoint().createExchange(httpExchange);
    //Unit of Work to process the Exchange
    createUoW(camelExchange);
    try {
        getProcessor().process(camelExchange);
    } catch (Exception e) {
        getExceptionHandler().handleException(e);
    } finally {
        doneUoW(camelExchange);
    }
    Object body = getResponseBody(httpExchange, camelExchange);
    TypeConverter tc = getEndpoint().getCamelContext().getTypeConverter();
    if (body == null) {
        LOG.trace("No payload to send as reply for exchange: " + camelExchange);
        httpExchange.getResponseHeaders().put(ExchangeHeaders.CONTENT_TYPE, MimeMappings.DEFAULT_MIME_MAPPINGS.get("txt"));
        httpExchange.getResponseSender().send("No response available");
    } else {
        ByteBuffer bodyAsByteBuffer = tc.convertTo(ByteBuffer.class, body);
        httpExchange.getResponseSender().send(bodyAsByteBuffer);
    }
    httpExchange.getResponseSender().close();
}
Also used : HttpServerExchange(io.undertow.server.HttpServerExchange) Exchange(org.apache.camel.Exchange) TypeConverter(org.apache.camel.TypeConverter) HttpString(io.undertow.util.HttpString) ByteBuffer(java.nio.ByteBuffer) IOException(java.io.IOException) HttpString(io.undertow.util.HttpString)

Example 3 with HttpString

use of io.undertow.util.HttpString in project camel by apache.

the class UndertowHelper method createMethod.

/**
     * Creates the HttpMethod to use to call the remote server, often either its GET or POST.
     */
public static HttpString createMethod(Exchange exchange, UndertowEndpoint endpoint, boolean hasPayload) throws URISyntaxException {
    // is a query string provided in the endpoint URI or in a header (header
    // overrules endpoint)
    String queryString = exchange.getIn().getHeader(Exchange.HTTP_QUERY, String.class);
    // We need also check the HTTP_URI header query part
    String uriString = exchange.getIn().getHeader(Exchange.HTTP_URI, String.class);
    // resolve placeholders in uriString
    try {
        uriString = exchange.getContext().resolvePropertyPlaceholders(uriString);
    } catch (Exception e) {
        throw new RuntimeExchangeException("Cannot resolve property placeholders with uri: " + uriString, exchange, e);
    }
    if (uriString != null) {
        URI uri = new URI(uriString);
        queryString = uri.getQuery();
    }
    if (queryString == null) {
        queryString = endpoint.getHttpURI().getRawQuery();
    }
    // compute what method to use either GET or POST
    HttpString answer;
    String m = exchange.getIn().getHeader(Exchange.HTTP_METHOD, String.class);
    if (m != null) {
        // always use what end-user provides in a header
        answer = new HttpString(m);
    } else if (queryString != null) {
        // if a query string is provided then use GET
        answer = Methods.GET;
    } else {
        // fallback to POST if we have payload, otherwise GET
        answer = hasPayload ? Methods.POST : Methods.GET;
    }
    return answer;
}
Also used : RuntimeExchangeException(org.apache.camel.RuntimeExchangeException) HttpString(io.undertow.util.HttpString) URI(java.net.URI) RuntimeExchangeException(org.apache.camel.RuntimeExchangeException) URISyntaxException(java.net.URISyntaxException) HttpString(io.undertow.util.HttpString)

Example 4 with HttpString

use of io.undertow.util.HttpString in project camel by apache.

the class UndertowProducer method process.

@Override
public boolean process(Exchange exchange, AsyncCallback callback) {
    ClientConnection connection = null;
    try {
        final UndertowClient client = UndertowClient.getInstance();
        IoFuture<ClientConnection> connect = client.connect(endpoint.getHttpURI(), worker, pool, options);
        // creating the url to use takes 2-steps
        final String exchangeUri = UndertowHelper.createURL(exchange, getEndpoint());
        final URI uri = UndertowHelper.createURI(exchange, exchangeUri, getEndpoint());
        final String pathAndQuery = URISupport.pathAndQueryOf(uri);
        // what http method to use
        HttpString method = UndertowHelper.createMethod(exchange, endpoint, exchange.getIn().getBody() != null);
        ClientRequest request = new ClientRequest();
        request.setProtocol(Protocols.HTTP_1_1);
        request.setPath(pathAndQuery);
        request.setMethod(method);
        final HeaderMap requestHeaders = request.getRequestHeaders();
        // Set the Host header
        Message message = exchange.getIn();
        final String host = message.getHeader("Host", String.class);
        requestHeaders.put(Headers.HOST, Optional.ofNullable(host).orElseGet(() -> uri.getAuthority()));
        Object body = getRequestBody(request, exchange);
        TypeConverter tc = endpoint.getCamelContext().getTypeConverter();
        ByteBuffer bodyAsByte = tc.tryConvertTo(ByteBuffer.class, body);
        if (body != null) {
            requestHeaders.put(Headers.CONTENT_LENGTH, bodyAsByte.array().length);
        }
        if (getEndpoint().getCookieHandler() != null) {
            Map<String, List<String>> cookieHeaders = getEndpoint().getCookieHandler().loadCookies(exchange, uri);
            for (Map.Entry<String, List<String>> entry : cookieHeaders.entrySet()) {
                requestHeaders.putAll(new HttpString(entry.getKey()), entry.getValue());
            }
        }
        if (LOG.isDebugEnabled()) {
            LOG.debug("Executing http {} method: {}", method, pathAndQuery);
        }
        connection = connect.get();
        connection.sendRequest(request, new UndertowProducerCallback(connection, bodyAsByte, exchange, callback));
    } catch (Exception e) {
        IOHelper.close(connection);
        exchange.setException(e);
        callback.done(true);
        return true;
    }
    // use async routing engine
    return false;
}
Also used : Message(org.apache.camel.Message) UndertowClient(io.undertow.client.UndertowClient) HttpString(io.undertow.util.HttpString) URI(java.net.URI) ByteBuffer(java.nio.ByteBuffer) URISyntaxException(java.net.URISyntaxException) IOException(java.io.IOException) TypeConverter(org.apache.camel.TypeConverter) HeaderMap(io.undertow.util.HeaderMap) ClientConnection(io.undertow.client.ClientConnection) LinkedList(java.util.LinkedList) List(java.util.List) HashMap(java.util.HashMap) OptionMap(org.xnio.OptionMap) HeaderMap(io.undertow.util.HeaderMap) Map(java.util.Map) ClientRequest(io.undertow.client.ClientRequest) HttpString(io.undertow.util.HttpString)

Example 5 with HttpString

use of io.undertow.util.HttpString in project camel by apache.

the class DefaultUndertowHttpBinding method populateCamelHeaders.

@Override
public void populateCamelHeaders(HttpServerExchange httpExchange, Map<String, Object> headersMap, Exchange exchange) throws Exception {
    LOG.trace("populateCamelHeaders: {}");
    // NOTE: these headers is applied using the same logic as camel-http/camel-jetty to be consistent
    headersMap.put(Exchange.HTTP_METHOD, httpExchange.getRequestMethod().toString());
    // strip query parameters from the uri
    headersMap.put(Exchange.HTTP_URL, httpExchange.getRequestURL());
    // uri is without the host and port
    headersMap.put(Exchange.HTTP_URI, httpExchange.getRequestURI());
    headersMap.put(Exchange.HTTP_QUERY, httpExchange.getQueryString());
    headersMap.put(Exchange.HTTP_RAW_QUERY, httpExchange.getQueryString());
    String path = httpExchange.getRequestPath();
    UndertowEndpoint endpoint = (UndertowEndpoint) exchange.getFromEndpoint();
    if (endpoint.getHttpURI() != null) {
        // need to match by lower case as we want to ignore case on context-path
        String endpointPath = endpoint.getHttpURI().getPath();
        String matchPath = path.toLowerCase(Locale.US);
        String match = endpointPath.toLowerCase(Locale.US);
        if (match != null && matchPath.startsWith(match)) {
            path = path.substring(endpointPath.length());
        }
    }
    headersMap.put(Exchange.HTTP_PATH, path);
    if (LOG.isTraceEnabled()) {
        LOG.trace("HTTP-Method {}", httpExchange.getRequestMethod());
        LOG.trace("HTTP-Uri {}", httpExchange.getRequestURI());
    }
    for (HttpString name : httpExchange.getRequestHeaders().getHeaderNames()) {
        //String name = httpName.toString();
        if (name.toString().toLowerCase(Locale.US).equals("content-type")) {
            name = ExchangeHeaders.CONTENT_TYPE;
        }
        if (name.toString().toLowerCase(Locale.US).equals("authorization")) {
            String value = httpExchange.getRequestHeaders().get(name).toString();
            // store a special header that this request was authenticated using HTTP Basic
            if (value != null && value.trim().startsWith("Basic")) {
                if (headerFilterStrategy != null && !headerFilterStrategy.applyFilterToExternalHeaders(Exchange.AUTHENTICATION, "Basic", exchange)) {
                    UndertowHelper.appendHeader(headersMap, Exchange.AUTHENTICATION, "Basic");
                }
            }
        }
        // add the headers one by one, and use the header filter strategy
        Iterator<?> it = httpExchange.getRequestHeaders().get(name).iterator();
        while (it.hasNext()) {
            Object value = it.next();
            LOG.trace("HTTP-header: {}", value);
            if (headerFilterStrategy != null && !headerFilterStrategy.applyFilterToExternalHeaders(name.toString(), value, exchange)) {
                UndertowHelper.appendHeader(headersMap, name.toString(), value);
            }
        }
    }
    //process uri parameters as headers
    Map<String, Deque<String>> pathParameters = httpExchange.getQueryParameters();
    //continue if the map is not empty, otherwise there are no params
    if (!pathParameters.isEmpty()) {
        for (Map.Entry<String, Deque<String>> entry : pathParameters.entrySet()) {
            String name = entry.getKey();
            Object values = entry.getValue();
            Iterator<?> it = ObjectHelper.createIterator(values);
            while (it.hasNext()) {
                Object value = it.next();
                LOG.trace("URI-Parameter: {}", value);
                if (headerFilterStrategy != null && !headerFilterStrategy.applyFilterToExternalHeaders(name, value, exchange)) {
                    UndertowHelper.appendHeader(headersMap, name, value);
                }
            }
        }
    }
    // Create headers for REST path placeholder variables
    Map<String, Object> predicateContextParams = httpExchange.getAttachment(Predicate.PREDICATE_CONTEXT);
    if (predicateContextParams != null) {
        // Remove this as it's an unwanted artifact of our Undertow predicate chain
        predicateContextParams.remove("remaining");
        for (String paramName : predicateContextParams.keySet()) {
            LOG.trace("REST Template Variable {}: {})", paramName, predicateContextParams.get(paramName));
            headersMap.put(paramName, predicateContextParams.get(paramName));
        }
    }
}
Also used : HttpString(io.undertow.util.HttpString) Deque(java.util.Deque) HashMap(java.util.HashMap) HeaderMap(io.undertow.util.HeaderMap) Map(java.util.Map) HttpString(io.undertow.util.HttpString)

Aggregations

HttpString (io.undertow.util.HttpString)117 HeaderMap (io.undertow.util.HeaderMap)24 IOException (java.io.IOException)23 HttpServerExchange (io.undertow.server.HttpServerExchange)21 Map (java.util.Map)21 HashMap (java.util.HashMap)16 User (com.networknt.portal.usermanagement.model.common.model.user.User)13 HttpHandler (io.undertow.server.HttpHandler)13 Test (org.junit.Test)12 ClientRequest (io.undertow.client.ClientRequest)10 URI (java.net.URI)10 ArrayList (java.util.ArrayList)10 ClientConnection (io.undertow.client.ClientConnection)9 ByteBuffer (java.nio.ByteBuffer)9 ClientResponse (io.undertow.client.ClientResponse)8 HeaderValues (io.undertow.util.HeaderValues)8 List (java.util.List)8 CountDownLatch (java.util.concurrent.CountDownLatch)8 URISyntaxException (java.net.URISyntaxException)7 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)6