Example usage for io.vertx.core.http HttpMethod OTHER

List of usage examples for io.vertx.core.http HttpMethod OTHER

Introduction

In this page you can find the example usage for io.vertx.core.http HttpMethod OTHER.

Prototype

HttpMethod OTHER

To view the source code for io.vertx.core.http HttpMethod OTHER.

Click Source Link

Usage

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  w  w  w . j a  va  2  s . co  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;
    }
}