Example usage for io.vertx.core.http HttpClientRequest setTimeout

List of usage examples for io.vertx.core.http HttpClientRequest setTimeout

Introduction

In this page you can find the example usage for io.vertx.core.http HttpClientRequest setTimeout.

Prototype

@Fluent
HttpClientRequest setTimeout(long timeoutMs);

Source Link

Document

Set's the amount of time after which if the request does not return any data within the timeout period an java.util.concurrent.TimeoutException will be passed to the exception handler (if provided) and the request will be closed.

Usage

From source file:io.gravitee.fetcher.http.HttpFetcher.java

License:Apache License

private CompletableFuture<Buffer> fetchContent() {
    CompletableFuture<Buffer> future = new VertxCompletableFuture<>(vertx);

    URI requestUri = URI.create(httpFetcherConfiguration.getUrl());
    boolean ssl = HTTPS_SCHEME.equalsIgnoreCase(requestUri.getScheme());

    final HttpClientOptions options = new HttpClientOptions().setSsl(ssl).setTrustAll(true).setMaxPoolSize(1)
            .setKeepAlive(false).setTcpKeepAlive(false).setConnectTimeout(httpClientTimeout);

    if (httpFetcherConfiguration.isUseSystemProxy()) {
        ProxyOptions proxyOptions = new ProxyOptions();
        proxyOptions.setType(ProxyType.valueOf(httpClientProxyType));
        if (HTTPS_SCHEME.equals(requestUri.getScheme())) {
            proxyOptions.setHost(httpClientProxyHttpsHost);
            proxyOptions.setPort(httpClientProxyHttpsPort);
            proxyOptions.setUsername(httpClientProxyHttpsUsername);
            proxyOptions.setPassword(httpClientProxyHttpsPassword);
        } else {//from  w ww.  j  a v a2 s  .  c  o m
            proxyOptions.setHost(httpClientProxyHttpHost);
            proxyOptions.setPort(httpClientProxyHttpPort);
            proxyOptions.setUsername(httpClientProxyHttpUsername);
            proxyOptions.setPassword(httpClientProxyHttpPassword);
        }
        options.setProxyOptions(proxyOptions);
    }

    final HttpClient httpClient = vertx.createHttpClient(options);

    final int port = requestUri.getPort() != -1 ? requestUri.getPort()
            : (HTTPS_SCHEME.equals(requestUri.getScheme()) ? 443 : 80);

    try {
        HttpClientRequest request = httpClient.request(HttpMethod.GET, port, requestUri.getHost(),
                requestUri.toString());

        request.setTimeout(httpClientTimeout);

        request.handler(response -> {
            if (response.statusCode() == HttpStatusCode.OK_200) {
                response.bodyHandler(buffer -> {
                    future.complete(buffer);

                    // Close client
                    httpClient.close();
                });
            } else {
                future.complete(null);
            }
        });

        request.exceptionHandler(event -> {
            try {
                future.completeExceptionally(event);

                // Close client
                httpClient.close();
            } catch (IllegalStateException ise) {
                // Do not take care about exception when closing client
            }
        });

        request.end();
    } catch (Exception ex) {
        logger.error("Unable to fetch content using HTTP", ex);
        future.completeExceptionally(ex);
    }

    return future;
}

From source file:io.gravitee.gateway.http.connector.VertxHttpClient.java

License:Apache License

@Override
public ProxyConnection request(ProxyRequest proxyRequest) {
    HttpClient httpClient = httpClients.computeIfAbsent(Vertx.currentContext(), createHttpClient());

    // Remove hop-by-hop headers.
    if (!proxyRequest.isWebSocket()) {
        for (CharSequence header : HOP_HEADERS) {
            proxyRequest.headers().remove(header);
        }/*from www .  ja  v  a 2  s  .c o  m*/
    } else {
        for (CharSequence header : WS_HOP_HEADERS) {
            proxyRequest.headers().remove(header);
        }
    }

    final URI uri = proxyRequest.uri();
    final int port = uri.getPort() != -1 ? uri.getPort() : (HTTPS_SCHEME.equals(uri.getScheme()) ? 443 : 80);

    final String host = (port == DEFAULT_HTTP_PORT || port == DEFAULT_HTTPS_PORT) ? uri.getHost()
            : uri.getHost() + ':' + port;

    proxyRequest.headers().set(HttpHeaders.HOST, host);

    // Apply headers from endpoint
    if (endpoint.getHeaders() != null && !endpoint.getHeaders().isEmpty()) {
        endpoint.getHeaders().forEach(proxyRequest.headers()::set);
    }

    String relativeUri = (uri.getRawQuery() == null) ? uri.getRawPath()
            : uri.getRawPath() + '?' + uri.getRawQuery();

    if (proxyRequest.isWebSocket()) {
        VertxWebSocketProxyConnection webSocketProxyConnection = new VertxWebSocketProxyConnection();
        WebSocketProxyRequest wsProxyRequest = (WebSocketProxyRequest) proxyRequest;

        httpClient.websocket(port, uri.getHost(), relativeUri, new Handler<WebSocket>() {
            @Override
            public void handle(WebSocket event) {
                // The client -> gateway connection must be upgraded now that the one between gateway -> upstream
                // has been accepted
                wsProxyRequest.upgrade();

                // From server to client
                wsProxyRequest.frameHandler(frame -> {
                    if (frame.type() == io.gravitee.gateway.api.ws.WebSocketFrame.Type.BINARY) {
                        event.writeBinaryMessage(io.vertx.core.buffer.Buffer.buffer(frame.data().getBytes()));
                    } else if (frame.type() == io.gravitee.gateway.api.ws.WebSocketFrame.Type.TEXT) {
                        event.writeTextMessage(frame.data().toString());
                    }
                });

                wsProxyRequest.closeHandler(result -> event.close());

                // From client to server
                event.frameHandler(frame -> wsProxyRequest.write(new VertxWebSocketFrame(frame)));

                event.closeHandler(event1 -> wsProxyRequest.close());

                event.exceptionHandler(new Handler<Throwable>() {
                    @Override
                    public void handle(Throwable throwable) {
                        wsProxyRequest.reject(HttpStatusCode.BAD_REQUEST_400);
                        ProxyResponse clientResponse = new EmptyProxyResponse(HttpStatusCode.BAD_REQUEST_400);

                        clientResponse.headers().set(HttpHeaders.CONNECTION,
                                HttpHeadersValues.CONNECTION_CLOSE);
                        webSocketProxyConnection.handleResponse(clientResponse);
                    }
                });

                // Tell the reactor that the request has been handled by the HTTP client
                webSocketProxyConnection.handleResponse(new SwitchProtocolProxyResponse());
            }
        }, throwable -> {
            if (throwable instanceof WebsocketRejectedException) {
                wsProxyRequest.reject(((WebsocketRejectedException) throwable).getStatus());
                ProxyResponse clientResponse = new EmptyProxyResponse(
                        ((WebsocketRejectedException) throwable).getStatus());

                clientResponse.headers().set(HttpHeaders.CONNECTION, HttpHeadersValues.CONNECTION_CLOSE);
                webSocketProxyConnection.handleResponse(clientResponse);
            } else {
                wsProxyRequest.reject(HttpStatusCode.BAD_GATEWAY_502);
                ProxyResponse clientResponse = new EmptyProxyResponse(HttpStatusCode.BAD_GATEWAY_502);

                clientResponse.headers().set(HttpHeaders.CONNECTION, HttpHeadersValues.CONNECTION_CLOSE);
                webSocketProxyConnection.handleResponse(clientResponse);
            }
        });

        return webSocketProxyConnection;
    } else {
        // Prepare HTTP request
        HttpClientRequest clientRequest = httpClient.request(HttpMethod.valueOf(proxyRequest.method().name()),
                port, uri.getHost(), relativeUri);
        clientRequest.setTimeout(endpoint.getHttpClientOptions().getReadTimeout());
        clientRequest.setFollowRedirects(endpoint.getHttpClientOptions().isFollowRedirects());

        if (proxyRequest.method() == io.gravitee.common.http.HttpMethod.OTHER) {
            clientRequest.setRawMethod(proxyRequest.rawMethod());
        }

        VertxProxyConnection proxyConnection = new VertxProxyConnection(proxyRequest, clientRequest);
        clientRequest.handler(
                clientResponse -> handleClientResponse(proxyConnection, clientResponse, clientRequest));

        clientRequest.connectionHandler(connection -> {
            connection.exceptionHandler(ex -> {
                // I don't want to fill my logs with error
            });
        });

        clientRequest.exceptionHandler(event -> {
            if (!proxyConnection.isCanceled() && !proxyConnection.isTransmitted()) {
                proxyRequest.metrics().setMessage(event.getMessage());

                if (proxyConnection.timeoutHandler() != null && (event instanceof ConnectException
                        || event instanceof TimeoutException || event instanceof NoRouteToHostException
                        || event instanceof UnknownHostException)) {
                    proxyConnection.handleConnectTimeout(event);
                } else {
                    ProxyResponse clientResponse = new EmptyProxyResponse(
                            ((event instanceof ConnectTimeoutException) || (event instanceof TimeoutException))
                                    ? HttpStatusCode.GATEWAY_TIMEOUT_504
                                    : HttpStatusCode.BAD_GATEWAY_502);

                    clientResponse.headers().set(HttpHeaders.CONNECTION, HttpHeadersValues.CONNECTION_CLOSE);
                    proxyConnection.handleResponse(clientResponse);
                }
            }
        });

        return proxyConnection;
    }
}

From source file:io.gravitee.gateway.http.vertx.VertxHttpClient.java

License:Apache License

@Override
public ClientRequest request(io.gravitee.common.http.HttpMethod method, URI uri, HttpHeaders headers,
        Handler<ClientResponse> responseHandler) {
    HttpClient httpClient = httpClients.computeIfAbsent(Vertx.currentContext(), createHttpClient());

    final int port = uri.getPort() != -1 ? uri.getPort() : (HTTPS_SCHEME.equals(uri.getScheme()) ? 443 : 80);

    String relativeUri = (uri.getRawQuery() == null) ? uri.getRawPath()
            : uri.getRawPath() + '?' + uri.getRawQuery();

    HttpClientRequest clientRequest = httpClient.request(convert(method), port, uri.getHost(), relativeUri,
            clientResponse -> handleClientResponse(clientResponse, responseHandler));

    clientRequest.setTimeout(endpoint.getHttpClientOptions().getReadTimeout());

    VertxClientRequest invokerRequest = new VertxClientRequest(clientRequest);

    clientRequest.exceptionHandler(event -> {
        LOGGER.error("Server proxying failed: {}", event.getMessage());

        if (invokerRequest.connectTimeoutHandler() != null && event instanceof ConnectTimeoutException) {
            invokerRequest.connectTimeoutHandler().handle(event);
        } else {/*from   ww  w .  j  a  v  a 2s .  c om*/
            VertxClientResponse clientResponse = new VertxClientResponse(
                    ((event instanceof ConnectTimeoutException) || (event instanceof TimeoutException))
                            ? HttpStatusCode.GATEWAY_TIMEOUT_504
                            : HttpStatusCode.BAD_GATEWAY_502);

            clientResponse.headers().set(HttpHeaders.CONNECTION, HttpHeadersValues.CONNECTION_CLOSE);

            Buffer buffer = null;

            if (event.getMessage() != null) {
                // Create body content with error message
                buffer = Buffer.buffer(event.getMessage());
                clientResponse.headers().set(HttpHeaders.CONTENT_LENGTH, Integer.toString(buffer.length()));
            }

            responseHandler.handle(clientResponse);

            if (buffer != null) {
                clientResponse.bodyHandler().handle(buffer);
            }

            clientResponse.endHandler().handle(null);
        }
    });

    // Copy headers to final API
    copyRequestHeaders(headers, clientRequest,
            (port == 80 || port == 443) ? uri.getHost() : uri.getHost() + ':' + port);

    // Check chunk flag on the request if there are some content to push and if transfer_encoding is set
    // with chunk value
    if (hasContent(headers)) {
        String transferEncoding = headers.getFirst(HttpHeaders.TRANSFER_ENCODING);
        if (HttpHeadersValues.TRANSFER_ENCODING_CHUNKED.equalsIgnoreCase(transferEncoding)) {
            clientRequest.setChunked(true);
        }
    }

    // Send HTTP head as soon as possible
    clientRequest.sendHead();

    return invokerRequest;
}

From source file:io.gravitee.gateway.services.healthcheck.http.HttpEndpointRuleHandler.java

License:Apache License

@Override
public void handle(Long timer) {
    HttpEndpoint endpoint = (HttpEndpoint) rule.endpoint();

    logger.debug("Running health-check for endpoint: {} [{}]", endpoint.getName(), endpoint.getTarget());

    // Run request for each step
    for (io.gravitee.definition.model.services.healthcheck.Step step : rule.steps()) {
        try {/* w ww.  j  a v  a 2 s . c  om*/
            URI hcRequestUri = create(endpoint.getTarget(), step.getRequest());

            // Prepare HTTP client
            HttpClientOptions httpClientOptions = new HttpClientOptions().setMaxPoolSize(1).setKeepAlive(false)
                    .setTcpKeepAlive(false);

            if (endpoint.getHttpClientOptions() != null) {
                httpClientOptions
                        .setIdleTimeout((int) (endpoint.getHttpClientOptions().getIdleTimeout() / 1000))
                        .setConnectTimeout((int) endpoint.getHttpClientOptions().getConnectTimeout())
                        .setTryUseCompression(endpoint.getHttpClientOptions().isUseCompression());
            }

            // Configure HTTP proxy
            HttpProxy proxy = endpoint.getHttpProxy();
            if (proxy != null && proxy.isEnabled()) {
                ProxyOptions proxyOptions = new ProxyOptions().setHost(proxy.getHost()).setPort(proxy.getPort())
                        .setUsername(proxy.getUsername()).setPassword(proxy.getPassword())
                        .setType(ProxyType.valueOf(proxy.getType().name()));

                httpClientOptions.setProxyOptions(proxyOptions);
            }

            HttpClientSslOptions sslOptions = endpoint.getHttpClientSslOptions();

            if (HTTPS_SCHEME.equalsIgnoreCase(hcRequestUri.getScheme())) {
                // Configure SSL
                httpClientOptions.setSsl(true);

                if (sslOptions != null) {
                    httpClientOptions.setVerifyHost(sslOptions.isHostnameVerifier())
                            .setTrustAll(sslOptions.isTrustAll());

                    // Client trust configuration
                    if (!sslOptions.isTrustAll() && sslOptions.getTrustStore() != null) {
                        switch (sslOptions.getTrustStore().getType()) {
                        case PEM:
                            PEMTrustStore pemTrustStore = (PEMTrustStore) sslOptions.getTrustStore();
                            PemTrustOptions pemTrustOptions = new PemTrustOptions();
                            if (pemTrustStore.getPath() != null && !pemTrustStore.getPath().isEmpty()) {
                                pemTrustOptions.addCertPath(pemTrustStore.getPath());
                            } else if (pemTrustStore.getContent() != null
                                    && !pemTrustStore.getContent().isEmpty()) {
                                pemTrustOptions.addCertValue(
                                        io.vertx.core.buffer.Buffer.buffer(pemTrustStore.getContent()));
                            } else {
                                throw new EndpointException(
                                        "Missing PEM certificate value for endpoint " + endpoint.getName());
                            }
                            httpClientOptions.setPemTrustOptions(pemTrustOptions);
                            break;
                        case PKCS12:
                            PKCS12TrustStore pkcs12TrustStore = (PKCS12TrustStore) sslOptions.getTrustStore();
                            PfxOptions pfxOptions = new PfxOptions();
                            pfxOptions.setPassword(pkcs12TrustStore.getPassword());
                            if (pkcs12TrustStore.getPath() != null && !pkcs12TrustStore.getPath().isEmpty()) {
                                pfxOptions.setPath(pkcs12TrustStore.getPath());
                            } else if (pkcs12TrustStore.getContent() != null
                                    && !pkcs12TrustStore.getContent().isEmpty()) {
                                pfxOptions.setValue(
                                        io.vertx.core.buffer.Buffer.buffer(pkcs12TrustStore.getContent()));
                            } else {
                                throw new EndpointException(
                                        "Missing PKCS12 value for endpoint " + endpoint.getName());
                            }
                            httpClientOptions.setPfxTrustOptions(pfxOptions);
                            break;
                        case JKS:
                            JKSTrustStore jksTrustStore = (JKSTrustStore) sslOptions.getTrustStore();
                            JksOptions jksOptions = new JksOptions();
                            jksOptions.setPassword(jksTrustStore.getPassword());
                            if (jksTrustStore.getPath() != null && !jksTrustStore.getPath().isEmpty()) {
                                jksOptions.setPath(jksTrustStore.getPath());
                            } else if (jksTrustStore.getContent() != null
                                    && !jksTrustStore.getContent().isEmpty()) {
                                jksOptions.setValue(
                                        io.vertx.core.buffer.Buffer.buffer(jksTrustStore.getContent()));
                            } else {
                                throw new EndpointException(
                                        "Missing JKS value for endpoint " + endpoint.getName());
                            }
                            httpClientOptions.setTrustStoreOptions(jksOptions);
                            break;
                        }
                    }

                    // Client authentication configuration
                    if (sslOptions.getKeyStore() != null) {
                        switch (sslOptions.getKeyStore().getType()) {
                        case PEM:
                            PEMKeyStore pemKeyStore = (PEMKeyStore) sslOptions.getKeyStore();
                            PemKeyCertOptions pemKeyCertOptions = new PemKeyCertOptions();
                            if (pemKeyStore.getCertPath() != null && !pemKeyStore.getCertPath().isEmpty()) {
                                pemKeyCertOptions.setCertPath(pemKeyStore.getCertPath());
                            } else if (pemKeyStore.getCertContent() != null
                                    && !pemKeyStore.getCertContent().isEmpty()) {
                                pemKeyCertOptions.setCertValue(
                                        io.vertx.core.buffer.Buffer.buffer(pemKeyStore.getCertContent()));
                            }
                            if (pemKeyStore.getKeyPath() != null && !pemKeyStore.getKeyPath().isEmpty()) {
                                pemKeyCertOptions.setKeyPath(pemKeyStore.getKeyPath());
                            } else if (pemKeyStore.getKeyContent() != null
                                    && !pemKeyStore.getKeyContent().isEmpty()) {
                                pemKeyCertOptions.setKeyValue(
                                        io.vertx.core.buffer.Buffer.buffer(pemKeyStore.getKeyContent()));
                            }
                            httpClientOptions.setPemKeyCertOptions(pemKeyCertOptions);
                            break;
                        case PKCS12:
                            PKCS12KeyStore pkcs12KeyStore = (PKCS12KeyStore) sslOptions.getKeyStore();
                            PfxOptions pfxOptions = new PfxOptions();
                            pfxOptions.setPassword(pkcs12KeyStore.getPassword());
                            if (pkcs12KeyStore.getPath() != null && !pkcs12KeyStore.getPath().isEmpty()) {
                                pfxOptions.setPath(pkcs12KeyStore.getPath());
                            } else if (pkcs12KeyStore.getContent() != null
                                    && !pkcs12KeyStore.getContent().isEmpty()) {
                                pfxOptions.setValue(
                                        io.vertx.core.buffer.Buffer.buffer(pkcs12KeyStore.getContent()));
                            }
                            httpClientOptions.setPfxKeyCertOptions(pfxOptions);
                            break;
                        case JKS:
                            JKSKeyStore jksKeyStore = (JKSKeyStore) sslOptions.getKeyStore();
                            JksOptions jksOptions = new JksOptions();
                            jksOptions.setPassword(jksKeyStore.getPassword());
                            if (jksKeyStore.getPath() != null && !jksKeyStore.getPath().isEmpty()) {
                                jksOptions.setPath(jksKeyStore.getPath());
                            } else if (jksKeyStore.getContent() != null
                                    && !jksKeyStore.getContent().isEmpty()) {
                                jksOptions
                                        .setValue(io.vertx.core.buffer.Buffer.buffer(jksKeyStore.getContent()));
                            }
                            httpClientOptions.setKeyStoreOptions(jksOptions);
                            break;
                        }
                    }
                }
            }

            HttpClient httpClient = vertx.createHttpClient(httpClientOptions);

            final int port = hcRequestUri.getPort() != -1 ? hcRequestUri.getPort()
                    : (HTTPS_SCHEME.equals(hcRequestUri.getScheme()) ? 443 : 80);

            String relativeUri = (hcRequestUri.getRawQuery() == null) ? hcRequestUri.getRawPath()
                    : hcRequestUri.getRawPath() + '?' + hcRequestUri.getRawQuery();

            // Run health-check
            HttpClientRequest healthRequest = httpClient.request(
                    HttpMethod.valueOf(step.getRequest().getMethod().name().toUpperCase()), port,
                    hcRequestUri.getHost(), relativeUri);

            // Set timeout on request
            if (endpoint.getHttpClientOptions() != null) {
                healthRequest.setTimeout(endpoint.getHttpClientOptions().getReadTimeout());
            }

            // Prepare request
            if (step.getRequest().getHeaders() != null) {
                step.getRequest().getHeaders().forEach(
                        httpHeader -> healthRequest.headers().set(httpHeader.getName(), httpHeader.getValue()));
            }

            final EndpointStatus.Builder healthBuilder = EndpointStatus
                    .forEndpoint(rule.api(), endpoint.getName()).on(currentTimeMillis());

            long startTime = currentTimeMillis();

            Request request = new Request();
            request.setMethod(step.getRequest().getMethod());
            request.setUri(hcRequestUri.toString());

            healthRequest.handler(response -> response.bodyHandler(buffer -> {
                long endTime = currentTimeMillis();
                logger.debug("Health-check endpoint returns a response with a {} status code",
                        response.statusCode());

                String body = buffer.toString();

                EndpointStatus.StepBuilder stepBuilder = validateAssertions(step,
                        new EvaluableHttpResponse(response, body));
                stepBuilder.request(request);
                stepBuilder.responseTime(endTime - startTime);

                Response healthResponse = new Response();
                healthResponse.setStatus(response.statusCode());

                // If validation fail, store request and response data
                if (!stepBuilder.isSuccess()) {
                    request.setBody(step.getRequest().getBody());

                    if (step.getRequest().getHeaders() != null) {
                        HttpHeaders reqHeaders = new HttpHeaders();
                        step.getRequest().getHeaders().forEach(httpHeader -> reqHeaders
                                .put(httpHeader.getName(), Collections.singletonList(httpHeader.getValue())));
                        request.setHeaders(reqHeaders);
                    }

                    // Extract headers
                    HttpHeaders headers = new HttpHeaders();
                    response.headers().names().forEach(
                            headerName -> headers.put(headerName, response.headers().getAll(headerName)));
                    healthResponse.setHeaders(headers);

                    // Store body
                    healthResponse.setBody(body);
                }

                stepBuilder.response(healthResponse);

                // Append step stepBuilder
                healthBuilder.step(stepBuilder.build());

                report(healthBuilder.build());

                // Close client
                httpClient.close();
            }));

            healthRequest.exceptionHandler(event -> {
                long endTime = currentTimeMillis();

                EndpointStatus.StepBuilder stepBuilder = EndpointStatus.forStep(step.getName());
                stepBuilder.fail(event.getMessage());

                Response healthResponse = new Response();

                // Extract request information
                request.setBody(step.getRequest().getBody());
                if (step.getRequest().getHeaders() != null) {
                    HttpHeaders reqHeaders = new HttpHeaders();
                    step.getRequest().getHeaders().forEach(httpHeader -> reqHeaders.put(httpHeader.getName(),
                            Collections.singletonList(httpHeader.getValue())));
                    request.setHeaders(reqHeaders);
                }

                if (event instanceof ConnectTimeoutException) {
                    stepBuilder.fail(event.getMessage());
                    healthResponse.setStatus(HttpStatusCode.REQUEST_TIMEOUT_408);
                } else {
                    healthResponse.setStatus(HttpStatusCode.SERVICE_UNAVAILABLE_503);
                }

                Step result = stepBuilder.build();
                result.setResponse(healthResponse);
                result.setRequest(request);

                result.setResponseTime(endTime - startTime);

                // Append step result
                healthBuilder.step(result);

                report(healthBuilder.build());

                try {
                    // Close client
                    httpClient.close();
                } catch (IllegalStateException ise) {
                    // Do not take care about exception when closing client
                }
            });

            // Send request
            logger.debug("Execute health-check request: {}", healthRequest);
            if (step.getRequest().getBody() != null && !step.getRequest().getBody().isEmpty()) {
                healthRequest.end(step.getRequest().getBody());
            } else {
                healthRequest.end();
            }
        } catch (EndpointException ee) {
            logger.error("An error occurs while configuring the endpoint " + endpoint.getName()
                    + ". Healthcheck is skipped for this endpoint.", ee);
        } catch (Exception ex) {
            logger.error("An unexpected error occurs", ex);
        }
    }
}

From source file:io.gravitee.resource.oauth2.generic.OAuth2GenericResource.java

License:Apache License

@Override
public void introspect(String accessToken, Handler<OAuth2Response> responseHandler) {
    HttpClient httpClient = httpClients.computeIfAbsent(Vertx.currentContext(),
            context -> vertx.createHttpClient(httpClientOptions));

    OAuth2ResourceConfiguration configuration = configuration();
    StringBuilder introspectionUriBuilder = new StringBuilder(introspectionEndpointURI);

    if (configuration.isTokenIsSuppliedByQueryParam()) {
        introspectionUriBuilder.append('?').append(configuration.getTokenQueryParamName()).append('=')
                .append(accessToken);/*from   w ww. j ava 2s. co m*/
    }

    String introspectionEndpointURI = introspectionUriBuilder.toString();
    logger.debug("Introspect access token by requesting {} [{}]", introspectionEndpointURI,
            configuration.getIntrospectionEndpointMethod());

    HttpMethod httpMethod = HttpMethod.valueOf(configuration.getIntrospectionEndpointMethod().toUpperCase());

    HttpClientRequest request = httpClient.requestAbs(httpMethod, introspectionEndpointURI);
    request.setTimeout(30000L);

    if (configuration().isUseClientAuthorizationHeader()) {
        String authorizationHeader = configuration.getClientAuthorizationHeaderName();
        String authorizationValue = configuration.getClientAuthorizationHeaderScheme().trim()
                + AUTHORIZATION_HEADER_SCHEME_SEPARATOR
                + Base64.getEncoder().encodeToString(
                        (configuration.getClientId() + AUTHORIZATION_HEADER_VALUE_BASE64_SEPARATOR
                                + configuration.getClientSecret()).getBytes());
        request.headers().add(authorizationHeader, authorizationValue);
        logger.debug("Set client authorization using HTTP header {} with value {}", authorizationHeader,
                authorizationValue);
    }

    // Set `Accept` header to ask for application/json content
    request.headers().add(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON);

    if (configuration.isTokenIsSuppliedByHttpHeader()) {
        request.headers().add(configuration.getTokenHeaderName(), accessToken);
    }

    request.handler(response -> response.bodyHandler(buffer -> {
        logger.debug("Introspection endpoint returns a response with a {} status code", response.statusCode());
        if (response.statusCode() == HttpStatusCode.OK_200) {
            // According to RFC 7662 : Note that a properly formed and authorized query for an inactive or
            // otherwise invalid token (or a token the protected resource is not
            // allowed to know about) is not considered an error response by this
            // specification.  In these cases, the authorization server MUST instead
            // respond with an introspection response with the "active" field set to
            // "false" as described in Section 2.2.
            String content = buffer.toString();

            try {
                JsonNode introspectNode = MAPPER.readTree(content);
                JsonNode activeNode = introspectNode.get("active");
                if (activeNode != null) {
                    boolean isActive = activeNode.asBoolean();
                    responseHandler.handle(new OAuth2Response(isActive, content));
                } else {
                    responseHandler.handle(new OAuth2Response(true, content));
                }
            } catch (IOException e) {
                logger.error("Unable to validate introspection endpoint payload: {}", content);
                responseHandler.handle(new OAuth2Response(false, content));
            }
        } else {
            responseHandler.handle(new OAuth2Response(false, buffer.toString()));
        }
    }));

    request.exceptionHandler(event -> {
        logger.error("An error occurs while checking OAuth2 token", event);
        responseHandler.handle(new OAuth2Response(false, event.getMessage()));
    });

    if (httpMethod == HttpMethod.POST && configuration.isTokenIsSuppliedByFormUrlEncoded()) {
        request.headers().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED);
        request.end(configuration.getTokenFormUrlEncodedName() + '=' + accessToken);
    } else {
        request.end();
    }
}

From source file:io.helixservice.feature.restclient.RestRequest.java

License:Open Source License

/**
 * Execute the request, with the expected response body marshaled
 * to a specific object type.//from   w w  w  .  j a  va  2 s  .co m
 *
 * @param responseType Type we expect the response to be marshaled to
 * @return RestResponse fluent interface
 * @throws SuspendExecution For Vert.x Sync
 */
public <T> RestResponse<T> asObject(Class<T> responseType) throws SuspendExecution {
    try {
        // Apply Params & Url Vars
        String modifiedUrlPath = addParameters(replaceUrlVars(urlPath));

        // Do request
        HttpClientRequest request;
        if (useDefaultHostAndPort) {
            request = httpClient.get().request(io.vertx.core.http.HttpMethod.valueOf(method.name()),
                    modifiedUrlPath);
        } else {
            request = httpClient.get().requestAbs(io.vertx.core.http.HttpMethod.valueOf(method.name()),
                    modifiedUrlPath);
        }

        // Set timeout, if requested
        if (timeoutInMs != null) {
            request.setTimeout(timeoutInMs);
        }

        // With headers
        request.headers().addAll(VertxTypeConverter.toVertxMultiMap(headers));

        // Write body if we need to
        Buffer body = Buffer.buffer();
        if (requestBody.isPresent()) {
            request.setChunked(true);
            Message message = marshallerSupplier.get().marshal(requestBody);

            List<String> contentTypes = message.getContentTypes();
            if (contentTypes != null && contentTypes.size() > 0) {
                request.putHeader("Content-Type", contentTypes);
            }

            body = body.appendBytes(message.getBody());
        }

        // Wait for response with Vert.x Sync
        HttpClientResponse httpClientResponse = getHttpClientResponse(request, body);
        Buffer bodyBuffer = getBuffer(httpClientResponse);

        return new RestResponse<>(httpClientResponse, bodyBuffer, marshallerSupplier, responseType);
    } catch (URISyntaxException | UnsupportedEncodingException e) {
        throw new IllegalArgumentException("Unable to parse urlPath=" + urlPath, e);
    }
}

From source file:io.nitor.api.backend.proxy.Proxy.java

License:Apache License

public void handle(RoutingContext routingContext) {
    final HttpServerRequest sreq = routingContext.request();
    final boolean isTls = isOrigReqHttps || "https".equals(routingContext.request().scheme());
    final boolean isHTTP2 = routingContext.request().version() == HTTP_2;
    final String chost = getRemoteAddress(routingContext);
    final ProxyTracer tracer = tracerFactory.get();
    String reqId = sreq.headers().get(requestIdHeader);
    boolean hadRequestId = reqId != null;
    if (reqId == null) {
        reqId = Long.toString(requestId.getAndIncrement());
    }/*from  w ww .  j a v  a 2 s . c o m*/
    tracer.incomingRequestStart(routingContext, isTls, isHTTP2, chost, reqId);
    if (!hadRequestId) {
        sreq.headers().add(requestIdHeader, reqId);
    }

    HttpServerResponse sres = sreq.response();
    sres.exceptionHandler(tracer::outgoingResponseException);
    routingContext.addHeadersEndHandler(tracer::outgoingResponseHeadersEnd);
    sres.bodyEndHandler(tracer::outgoingResponseBodyEnd);
    if (!isHTTP2) {
        sres.headers().add("keep-alive", keepAliveHeaderValue);
        sres.headers().add("connection", "keep-alive");
    }
    sreq.exceptionHandler(t -> {
        tracer.incomingRequestException(t);
        routingContext.fail(new ProxyException(500, RejectReason.incomingRequestFail, t));
    });

    final State state = new State();

    targetResolver.resolveNextHop(routingContext, nextHop -> {
        if (nextHop == null) {
            NullPointerException e = new NullPointerException("nextHop must not be null");
            tracer.incomingRequestException(e);
            throw e;
        }
        tracer.nextHopResolved(nextHop);

        MultiMap sreqh = sreq.headers();
        String origHost = null;
        if (isHTTP2) {
            origHost = sreqh.get(":authority");
        }
        if (origHost == null) {
            origHost = sreqh.get("Host");
        }
        if (origHost == null) {
            ProxyException e = new ProxyException(400, RejectReason.noHostHeader, null);
            tracer.incomingRequestException(e);
            routingContext.fail(e);
            return;
        }
        boolean isWebsocket = !isHTTP2 && "websocket".equals(sreqh.get("upgrade"));
        if (isWebsocket) {
            MultiMap creqh = new CaseInsensitiveHeaders();
            propagateRequestHeaders(isTls, chost, sreqh, origHost, creqh);
            if (nextHop.hostHeader != null) {
                creqh.set("Host", nextHop.hostHeader);
            } else {
                creqh.remove("Host");
            }
            tracer.outgoingWebsocketInitial(creqh);
            client.websocket(nextHop.socketPort, nextHop.socketHost, nextHop.uri, creqh, cws -> {
                // lol no headers copied
                final boolean[] isClosed = { false };
                ServerWebSocket sws = sreq.upgrade();
                tracer.websocketEstablished();
                for (final WebSocketBase[] pair : new WebSocketBase[][] { { sws, cws }, { cws, sws } }) {
                    pair[0].frameHandler(pair[1]::writeFrame).closeHandler(v -> {
                        if (!isClosed[0]) {
                            tracer.establishedWebsocketClosed();
                            isClosed[0] = true;
                            pair[1].close();
                        }
                    }).exceptionHandler(t -> {
                        tracer.establishedWebsocketException(t);
                        t.printStackTrace();
                        if (!isClosed[0]) {
                            isClosed[0] = true;
                            try {
                                pair[1].close();
                            } catch (IllegalStateException e) {
                                // whatever
                            }
                        }
                    });
                }
            }, t -> {
                tracer.outgoingWebsocketException(t);
                t.printStackTrace();
                sres.setStatusCode(HttpResponseStatus.BAD_GATEWAY.code());
                if (t instanceof WebSocketHandshakeRejectedException) {
                    WebSocketHandshakeRejectedException e = (WebSocketHandshakeRejectedException) t;
                    sres.setStatusCode(e.resp.status().code());
                    sres.setStatusMessage(e.resp.status().reasonPhrase());
                    MultiMap cresh = new HeadersAdaptor(e.resp.headers());
                    copyEndToEndHeaders(cresh, sres.headers());
                    sres.headers().add("keep-alive", keepAliveHeaderValue);
                    sres.headers().add("connection", "keep-alive");
                    sres.headers().set("content-length", "0");
                }
                tracer.outgoingResponseInitial();
                tracer.outgoingResponseHeadersEnd(null);
                sres.end();
                tracer.outgoingResponseBodyEnd(null);
            });
            return;
        }
        String expectStr;
        state.expecting100 = null != (expectStr = sreq.headers().get("expect"))
                && expectStr.equalsIgnoreCase("100-continue");
        HttpClientRequest creq = client.request(sreq.method(), nextHop.socketPort, nextHop.socketHost,
                nextHop.uri);
        creq.setTimeout(SECONDS.toMillis(clientReceiveTimeout));
        creq.handler(cres -> {
            cres.exceptionHandler(t -> {
                tracer.incomingResponseException(t);
                if (!state.serverFinished) {
                    state.clientFinished = true;
                    state.serverFinished = true;
                    routingContext.fail(new ProxyException(502, RejectReason.incomingResponseFail, t));
                }
            });
            tracer.incomingResponseStart(cres);
            sres.setStatusCode(cres.statusCode());
            sres.setStatusMessage(cres.statusMessage());
            MultiMap headers = cres.headers();
            copyEndToEndHeaders(headers, sres.headers());
            final boolean reqCompletedBeforeResponse = state.requestComplete;
            if (state.expecting100) {
                log.info("Got " + cres.statusCode() + " instead of 100 Continue");
                if (!isHTTP2) {
                    if (/* state.receivedRequestBodyBefore100 && */ !reqCompletedBeforeResponse) {
                        // TODO investigate whether vertx is able to handle the server request correctly without us closing the conn
                        // but actually the client might have data in transit..
                        log.info(
                                "Client might have started streaming data anyway, so request message boundary is lost. Continue streaming, but close server connection after response complete.");
                        sres.headers().set("connection", "close");
                    } else {
                        log.info(
                                "Client had streamed the complete data anyway. Can carry on without closing server conn.");
                    }
                }
            }
            if (!isHTTP2) {
                if (!sres.headers().contains("connection")
                        || !sres.headers().get("connection").contains("close")) {
                    sres.headers().add("keep-alive", keepAliveHeaderValue);
                    sres.headers().add("connection", "keep-alive");
                }
            }
            if (!headers.contains("content-length")) {
                sres.setChunked(true);
            }
            tracer.outgoingResponseInitial();
            cres.endHandler(v -> {
                tracer.incomingResponseEnd();
                state.clientFinished = true;
                if (!state.serverFinished) {
                    state.serverFinished = true;
                    sres.end();
                }
                if (state.expecting100
                        && /* state.receivedRequestBodyBefore100 && */ !reqCompletedBeforeResponse) {
                    log.info(
                            "Client had started streaming data anyway, so request message boundary is lost. Close client connection.");
                    creq.connection().close();
                }
            });
            pump.start(cres, sres, tracer);
        });
        creq.exceptionHandler(t -> {
            tracer.outgoingRequestException(t);
            if (!state.serverFinished) {
                state.clientFinished = true;
                state.serverFinished = true;
                routingContext.fail(new ProxyException(502, RejectReason.outgoingRequestFail, t));
            }
        });
        MultiMap creqh = creq.headers();
        propagateRequestHeaders(isTls, chost, sreqh, origHost, creqh);
        creq.headers().addAll(addHeaders);
        if (nextHop.hostHeader != null) {
            creq.setHost(nextHop.hostHeader);
        } else {
            creqh.remove("host");
        }
        if (sreqh.getAll("transfer-encoding").stream().anyMatch(v -> v.equals("chunked"))) {
            creq.setChunked(true);
        }
        sres.closeHandler(v -> {
            if (!state.clientFinished) {
                state.clientFinished = true;
                tracer.incomingConnectionPrematurelyClosed();
                HttpConnection connection = creq.connection();
                if (connection != null) {
                    connection.close();
                } // else TODO
            }
            if (!state.serverFinished) {
                state.serverFinished = true;
                routingContext.fail(new ProxyException(0, RejectReason.outgoingResponseFail, null));
            }
        });
        tracer.outgoingRequestInitial(creq);
        if (sreq.isEnded()) {
            state.requestComplete = true;
            Buffer body = routingContext.getBody();
            if (body == null || body.length() == 0) {
                creq.end();
            } else {
                if (!creq.isChunked()) {
                    creq.putHeader("content-length", Integer.toString(body.length()));
                }
                creq.end(routingContext.getBody());
            }
            tracer.incomingRequestEnd();
        } else {
            sreq.endHandler(v -> {
                state.requestComplete = true;
                try {
                    creq.end();
                } catch (IllegalStateException ex) {
                    // ignore - nothing can be done - the request is already complete/closed - TODO log?
                }
                tracer.incomingRequestEnd();
            });

            ReadStream<Buffer> sreqStream;
            if (state.expecting100) {
                log.debug("Expect: 100");
                creq.continueHandler(v -> {
                    // no longer expecting 100, it's like a normal not-expecting-100 request from now on
                    state.expecting100 = false;
                    // since we received 100 Continue, we know the server agrees to accept all the request body, so we can assume we are forgiven for sending data early
                    state.receivedRequestBodyBefore100 = false;
                    log.info("Got 100, propagating");
                    sres.writeContinue();
                });
                // in this case we must flush request headers before the body is sent
                creq.sendHead();
                sreqStream = new ReadStreamWrapper<Buffer>(sreq) {
                    final LazyHandlerWrapper<Buffer> handlerWrapper = new LazyHandlerWrapper<Buffer>(
                            super::handler, null) {
                        @Override
                        public void handle(Buffer event) {
                            log.info("Got first request body chunk");
                            if (state.expecting100) {
                                log.info("Got request body before '100 Continue'");
                                // data received despite not having yet recived 100-continue
                                state.receivedRequestBodyBefore100 = true;
                            }
                            deactivate();
                            wrapped.handle(event);
                        }
                    };

                    @Override
                    public ReadStream<Buffer> handler(Handler<Buffer> handler) {
                        return handlerWrapper.handler(handler, this);
                    }
                };
            } else {
                log.debug("Not expect-100");
                sreqStream = sreq;
            }
            pump.start(sreqStream, creq, tracer);
        }
    });
}

From source file:io.servicecomb.serviceregistry.client.http.RestUtils.java

License:Apache License

public static void httpDo(RequestContext requestContext, Handler<RestResponse> responseHandler) {
    HttpClientWithContext vertxHttpClient = HttpClientPool.INSTANCE.getClient();
    vertxHttpClient.runOnContext(httpClient -> {
        IpPort ipPort = requestContext.getIpPort();
        HttpMethod httpMethod = requestContext.getMethod();
        RequestParam requestParam = requestContext.getParams();

        if (ipPort == null) {
            LOGGER.error("request address is null");
            responseHandler.handle(new RestResponse(requestContext, null));
            return;
        }//from  w w  w  . ja  v  a2s  .c  om

        // query params
        StringBuilder url = new StringBuilder(requestContext.getUri());
        String queryParams = requestParam.getQueryParams();
        if (!queryParams.isEmpty()) {
            url.append(url.lastIndexOf("?") > 0 ? "&" : "?").append(queryParams);
        }

        HttpClientRequest httpClientRequest = httpClient.request(httpMethod, ipPort.getPort(),
                ipPort.getHostOrIp(), url.toString(), response -> {
                    responseHandler.handle(new RestResponse(requestContext, response));
                });

        httpClientRequest.setTimeout(ServiceRegistryConfig.INSTANCE.getRequestTimeout()).exceptionHandler(e -> {
            LOGGER.error("{} {} fail, endpoint is {}:{}, message: {}", httpMethod, url.toString(),
                    ipPort.getHostOrIp(), ipPort.getPort(), e.getMessage());
            responseHandler.handle(new RestResponse(requestContext, null));
        });

        //headers
        Map<String, String> headers = defaultHeaders();
        httpClientRequest.headers().addAll(headers);

        if (requestParam.getHeaders() != null && requestParam.getHeaders().size() > 0) {
            headers.putAll(requestParam.getHeaders());
            for (Map.Entry<String, String> header : requestParam.getHeaders().entrySet()) {
                httpClientRequest.putHeader(header.getKey(), header.getValue());
            }
        }

        // cookies header
        if (requestParam.getCookies() != null && requestParam.getCookies().size() > 0) {
            StringBuilder stringBuilder = new StringBuilder();
            for (Map.Entry<String, String> cookie : requestParam.getCookies().entrySet()) {
                stringBuilder.append(cookie.getKey()).append("=").append(cookie.getValue()).append("; ");
            }
            httpClientRequest.putHeader("Cookie", stringBuilder.toString());
            headers.put("Cookie", stringBuilder.toString());
        }

        //SignAuth
        SignRequest signReq = createSignRequest(requestContext.getMethod().toString(),
                requestContext.getIpPort(), requestContext.getParams(), url.toString(), headers);
        httpClientRequest.headers().addAll(getSignAuthHeaders(signReq));

        // body
        if (httpMethod != HttpMethod.GET && requestParam.getBody() != null
                && requestParam.getBody().length > 0) {
            httpClientRequest.end(Buffer.buffer(requestParam.getBody()));
        } else {
            httpClientRequest.end();
        }
    });
}

From source file:io.servicecomb.transport.rest.client.http.VertxHttpMethod.java

License:Apache License

public void doMethod(HttpClientWithContext httpClientWithContext, Invocation invocation,
        AsyncResponse asyncResp) throws Exception {
    OperationMeta operationMeta = invocation.getOperationMeta();
    RestOperationMeta swaggerRestOperation = operationMeta.getExtData(RestConst.SWAGGER_REST_OPERATION);

    String path = this.createRequestPath(invocation, swaggerRestOperation);
    IpPort ipPort = (IpPort) invocation.getEndpoint().getAddress();

    HttpClientRequest clientRequest = this.createRequest(httpClientWithContext.getHttpClient(), invocation,
            ipPort, path, asyncResp);//from w  w w.j  a v a2s . co  m
    clientRequest.putHeader(io.servicecomb.core.Const.TARGET_MICROSERVICE, invocation.getMicroserviceName());
    RestClientRequestImpl restClientRequest = new RestClientRequestImpl(clientRequest);
    RestCodec.argsToRest(invocation.getArgs(), swaggerRestOperation, restClientRequest);

    Buffer requestBodyBuffer = restClientRequest.getBodyBuffer();
    HttpServletRequestEx requestEx = new VertxClientRequestToHttpServletRequest(clientRequest,
            requestBodyBuffer);
    for (HttpClientFilter filter : httpClientFilters) {
        filter.beforeSendRequest(invocation, requestEx);
    }

    clientRequest.exceptionHandler(e -> {
        LOGGER.error(e.toString());
        asyncResp.fail(invocation.getInvocationType(), e);
    });

    LOGGER.debug("Running HTTP method {} on {} at {}:{}{}", invocation.getOperationMeta().getMethod(),
            invocation.getMicroserviceName(), ipPort.getHostOrIp(), ipPort.getPort(), path);

    // ??
    httpClientWithContext.runOnContext(httpClient -> {
        this.setCseContext(invocation, clientRequest);
        clientRequest.setTimeout(AbstractTransport.getRequestTimeout());
        try {
            restClientRequest.end();
        } catch (Exception e) {
            LOGGER.error("send http reqeust failed,", e);
            asyncResp.fail(invocation.getInvocationType(), e);
        }
    });
}

From source file:org.apache.servicecomb.serviceregistry.client.http.RestUtils.java

License:Apache License

public static void httpDo(long timeout, RequestContext requestContext, Handler<RestResponse> responseHandler) {
    HttpClientWithContext vertxHttpClient = HttpClientPool.INSTANCE.getClient();
    vertxHttpClient.runOnContext(httpClient -> {
        IpPort ipPort = requestContext.getIpPort();
        HttpMethod httpMethod = requestContext.getMethod();
        RequestParam requestParam = requestContext.getParams();

        if (ipPort == null) {
            LOGGER.error("request address is null");
            responseHandler.handle(new RestResponse(requestContext, null));
            return;
        }/*from w ww  .  ja v  a  2 s . c om*/

        // query params
        StringBuilder url = new StringBuilder(requestContext.getUri());
        String queryParams = requestParam.getQueryParams();
        if (!queryParams.isEmpty()) {
            url.append(url.lastIndexOf("?") > 0 ? "&" : "?").append(queryParams);
        }

        HttpClientRequest httpClientRequest = httpClient.request(httpMethod, ipPort.getPort(),
                ipPort.getHostOrIp(), url.toString(), response -> {
                    responseHandler.handle(new RestResponse(requestContext, response));
                });

        httpClientRequest.setTimeout(timeout).exceptionHandler(e -> {
            LOGGER.error("{} {} fail, endpoint is {}:{}, message: {}", httpMethod, url.toString(),
                    ipPort.getHostOrIp(), ipPort.getPort(), e.getMessage());
            responseHandler.handle(new RestResponse(requestContext, null));
        });

        //headers
        Map<String, String> headers = defaultHeaders();
        httpClientRequest.headers().addAll(headers);

        if (requestParam.getHeaders() != null && requestParam.getHeaders().size() > 0) {
            headers.putAll(requestParam.getHeaders());
            for (Map.Entry<String, String> header : requestParam.getHeaders().entrySet()) {
                httpClientRequest.putHeader(header.getKey(), header.getValue());
            }
        }

        // cookies header
        if (requestParam.getCookies() != null && requestParam.getCookies().size() > 0) {
            StringBuilder stringBuilder = new StringBuilder();
            for (Map.Entry<String, String> cookie : requestParam.getCookies().entrySet()) {
                stringBuilder.append(cookie.getKey()).append("=").append(cookie.getValue()).append("; ");
            }
            httpClientRequest.putHeader("Cookie", stringBuilder.toString());
            headers.put("Cookie", stringBuilder.toString());
        }

        //SignAuth
        SignRequest signReq = createSignRequest(requestContext.getMethod().toString(),
                requestContext.getIpPort(), requestContext.getParams(), url.toString(), headers);
        httpClientRequest.headers().addAll(getSignAuthHeaders(signReq));

        // body
        if (httpMethod != HttpMethod.GET && requestParam.getBody() != null
                && requestParam.getBody().length > 0) {
            httpClientRequest.end(Buffer.buffer(requestParam.getBody()));
        } else {
            httpClientRequest.end();
        }
    });
}