Example usage for io.vertx.core.http HttpServerResponse headWritten

List of usage examples for io.vertx.core.http HttpServerResponse headWritten

Introduction

In this page you can find the example usage for io.vertx.core.http HttpServerResponse headWritten.

Prototype

boolean headWritten();

Source Link

Usage

From source file:io.nitor.api.backend.lambda.LambdaHandler.java

License:Apache License

@Override
public void handle(RoutingContext ctx) {
    HttpServerRequest sreq = ctx.request();
    final String path = normalizePath(sreq.path(), routeLength);
    if (path == null) {
        ctx.response().setStatusCode(NOT_FOUND.code()).end();
        return;/*from  ww  w  . j a  va  2 s  . c  om*/
    }
    HttpServerResponse sres = ctx.response();
    PathMatchResult<Entry<String, String>> matchRes = pathTemplateMatcher.match(path);
    final String lambdaFunction, qualifier;
    if (matchRes == null) {
        logger.error("No matching path template");
        sres.setStatusCode(BAD_GATEWAY.code());
        return;
    } else {
        lambdaFunction = matchRes.getValue().getKey();
        qualifier = matchRes.getValue().getValue();
    }
    sreq.bodyHandler(new Handler<Buffer>() {
        @Override
        public void handle(Buffer event) {
            byte[] body = event.getBytes();
            APIGatewayProxyRequestEvent reqObj = new APIGatewayProxyRequestEvent();
            /*
            * Handle body
            */
            String bodyObjStr = null;
            boolean isBase64Encoded = true;
            if (body != null && body.length > 0) {
                String ct = sreq.getHeader("content-type").toLowerCase();
                if (ct.startsWith("text/") || ct.startsWith("application/json")
                        || (ct.indexOf("charset=") > 0)) {
                    String charset = "utf-8";
                    if (ct.indexOf("charset=") > 0) {
                        charset = getCharsetFromContentType(ct);
                    }
                    try {
                        bodyObjStr = Charset.forName(charset).newDecoder()
                                .onMalformedInput(CodingErrorAction.REPORT)
                                .onUnmappableCharacter(CodingErrorAction.REPORT).decode(ByteBuffer.wrap(body))
                                .toString();
                        isBase64Encoded = false;
                    } catch (CharacterCodingException e) {
                        logger.error("Decoding body failed", e);
                    }
                }
                if (bodyObjStr == null) {
                    bodyObjStr = Base64.getEncoder().encodeToString(body);
                }
                reqObj = reqObj.withBody(bodyObjStr).withIsBase64Encoded(isBase64Encoded);
            }
            Map<String, List<String>> headerMultivalue = sreq.headers().entries().stream()
                    .collect(toMap(Entry::getKey, x -> sreq.headers().getAll(x.getKey())));
            Map<String, String> headerValue = sreq.headers().entries().stream()
                    .collect(toMap(Entry::getKey, Entry::getValue));

            /*
            * Handle request context
            */
            RequestIdentity reqId = new RequestIdentity().withSourceIp(getRemoteAddress(ctx))
                    .withUserAgent(sreq.getHeader(USER_AGENT));
            if (ctx.user() != null) {
                reqId.withUser(ctx.user().principal().toString());
            }
            ProxyRequestContext reqCtx = new ProxyRequestContext()
                    .withPath(sreq.path().substring(0, routeLength)).withHttpMethod(sreq.method().toString())
                    .withIdentity(reqId);
            reqObj = reqObj.withMultiValueHeaders(headerMultivalue).withHeaders(headerValue)
                    .withHttpMethod(sreq.method().toString()).withPath(sreq.path()).withResource(path)
                    .withQueryStringParameters(splitQuery(sreq.query()))
                    .withMultiValueQueryStringParameters(splitMultiValueQuery(sreq.query()))
                    .withPathParameters(matchRes.getParameters()).withRequestContext(reqCtx);
            String reqStr = JsonObject.mapFrom(reqObj).toString();
            byte[] sendBody = reqStr.getBytes(UTF_8);
            InvokeRequest req = InvokeRequest.builder().invocationType(InvocationType.REQUEST_RESPONSE)
                    .functionName(lambdaFunction).qualifier(qualifier).payload(SdkBytes.fromByteArray(sendBody))
                    .build();
            logger.info("Calling lambda " + lambdaFunction + ":" + qualifier);
            logger.debug("Payload: " + reqStr);
            CompletableFuture<InvokeResponse> respFuture = lambdaCl.invoke(req);
            respFuture.whenComplete((iresp, err) -> {
                if (iresp != null) {
                    try {
                        String payload = iresp.payload().asString(UTF_8);
                        JsonObject resp = new JsonObject(payload);
                        int statusCode = resp.getInteger("statusCode");
                        sres.setStatusCode(statusCode);
                        for (Entry<String, Object> next : resp.getJsonObject("headers").getMap().entrySet()) {
                            sres.putHeader(next.getKey(), next.getValue().toString());
                        }
                        String respBody = resp.getString("body");
                        byte[] bodyArr = new byte[0];
                        if (body != null && !respBody.isEmpty()) {
                            if (TRUE.equals(resp.getBoolean("isBase64Encoded"))) {
                                bodyArr = Base64.getDecoder().decode(body);
                            } else {
                                bodyArr = respBody.getBytes(UTF_8);
                            }
                        }
                        sres.putHeader(CONTENT_LENGTH, String.valueOf(bodyArr.length));
                        Buffer buffer = Buffer.buffer(bodyArr);
                        tryToCacheContent(ctx, buffer);
                        sres.write(buffer);
                    } catch (Throwable t) {
                        logger.error("Error processing lambda request", t);
                        if (!sres.headWritten()) {
                            sres.setStatusCode(BAD_GATEWAY.code());
                            sres.putHeader(CONTENT_TYPE, "application/json");
                            Buffer response = Buffer.buffer(new LambdaErrorResponse(t).toString());
                            sres.putHeader(CONTENT_LENGTH, String.valueOf(response.length()));
                            sres.write(response);
                        }
                    } finally {
                        sres.end();
                    }
                } else {
                    logger.error("Error processing lambda request", err);
                    sres.setStatusCode(BAD_GATEWAY.code());
                    sres.putHeader(CONTENT_TYPE, "application/json");
                    Buffer response = Buffer.buffer(new LambdaErrorResponse(err).toString());
                    sres.putHeader(CONTENT_LENGTH, String.valueOf(response.length()));
                    sres.end(response);
                }
            });
        }
    });
}

From source file:io.nitor.api.backend.NitorBackend.java

License:Apache License

@Override
public void start() {
    vertx.exceptionHandler(e -> logger.error("Fallback exception handler got", e));

    HttpServerOptions httpServerOptions = SetupHttpServerOptions.createHttpServerOptions(config());

    Router router = Router.router(vertx);

    HttpClientOptions clientOptions = new HttpClientOptions();
    clientOptions.setConnectTimeout((int) SECONDS.toMillis(5));
    clientOptions.setIdleTimeout((int) SECONDS.toMillis(15));
    clientOptions.setSsl(true);//from   w w w. j a va 2s .  c  o  m
    HttpClient httpClient = vertx.createHttpClient(clientOptions);

    Map<String, String> injectedResponseHeaders = new HashMap<>();
    for (Entry<String, Object> defaultHeader : config().getJsonObject("defaultHeaders")) {
        injectedResponseHeaders.put(defaultHeader.getKey().toLowerCase(), defaultHeader.getValue().toString());
    }

    String publicURI = config().getString("publicURI",
            "http" + (httpServerOptions.isSsl() ? "s" : "") + "://localhost:" + listenPort);
    if (publicURI.endsWith("/")) {
        publicURI = publicURI.substring(0, publicURI.length() - 1);
    }
    publicURI = publicURI.toLowerCase(ROOT);

    boolean isOrigReqHttps = httpServerOptions.isSsl() || publicURI.startsWith("https:");
    boolean trustPreviousProxy = config().getBoolean("trustPreviousProxy",
            publicURI.startsWith("https:") && !httpServerOptions.isSsl());

    router.route().handler(new AccessLogHandler()::handle);
    router.route().handler(routingContext -> {
        HttpServerResponse resp = routingContext.response();
        if (isOrigReqHttps) {
            resp.putHeader("strict-transport-security", "max-age=31536000; includeSubDomains");
        }
        if (trustPreviousProxy) {
            String origHost = parseForwardedHeaders(routingContext.request().headers());
            if (origHost != null) {
                routingContext.put(REMOTE_ADDRESS, origHost);
            }
        }
        if (!injectedResponseHeaders.isEmpty()) {
            routingContext.addHeadersEndHandler(v -> {
                for (Entry<String, String> header : injectedResponseHeaders.entrySet()) {
                    if (!resp.headers().contains(header.getKey())) {
                        resp.putHeader(header.getKey(), header.getValue());
                    }
                }
            });
        }
        routingContext.next();
    });

    router.get("/healthCheck").handler(routingContext -> routingContext.response().setStatusCode(200).end());

    router.get("/certCheck").handler(routingContext -> {
        String resp;
        try {
            resp = "Certs: " + Arrays.toString(routingContext.request().peerCertificateChain());
        } catch (SSLPeerUnverifiedException e) {
            resp = "No client certs available:" + e.getMessage();
        }
        routingContext.response().setChunked(true).putHeader(CONTENT_TYPE, "text/plain; charset=utf-8")
                .write(resp).end();
    });

    JsonObject clientAuth = config().getJsonObject("clientAuth");
    if (clientAuth != null) {
        if (null != clientAuth.getString("clientChain")) {
            router.route(clientAuth.getString("route", "/*")).handler(routingContext -> {
                try {
                    routingContext.request().peerCertificateChain();
                    routingContext.next();
                } catch (SSLPeerUnverifiedException e) {
                    routingContext.response().setStatusCode(FORBIDDEN.code());
                    routingContext.response().end();
                    logger.info("Rejected request that was missing valid client certificate from ip {}: {}",
                            routingContext.request().remoteAddress(), e.getMessage());
                }
            });
        }
    }

    boolean virtualHost = config().getBoolean("virtualHost", false);
    if (virtualHost) {
        router.route().handler(ctx -> {
            ctx.put("host", getUriHostName(ctx.request().host()));
            ctx.next();
        });
    }

    JsonObject sessionConf = config().getJsonObject("session");
    CookieSessionHandler sessionHandler = sessionConf != null ? new CookieSessionHandler(sessionConf) : null;
    if (sessionHandler != null) {
        router.route().handler(CookieHandler.create());

        router.get("/proxyLogout").handler(routingContext -> {
            routingContext.cookies()
                    .forEach(cookie -> secureCookie(cookie, (int) DAYS.toSeconds(30)).setValue(""));
            routingContext.response().putHeader(CACHE_CONTROL, "no-cache, no-store, must-revalidate")
                    .putHeader(EXPIRES, "0").putHeader(CONTENT_TYPE, "text/plain; charset=utf-8")
                    .end("Logged out", "UTF-8");
        });
    }

    JsonObject adAuth = config().getJsonObject("adAuth");
    if (adAuth != null) {
        JsonObject openIdConfig = adAuth.getJsonObject("openIdConfig");
        if (openIdConfig == null || !openIdConfig.containsKey("authorization_endpoint")
                || !openIdConfig.containsKey("token_endpoint")) {
            String configURI = adAuth.getString("configurationURI");
            try {
                logger.info("Fetching configuration from " + configURI);
                URL url = URI.create(configURI).toURL();
                openIdConfig = new JsonObject(buffer(toBytes(url.openStream())));
            } catch (Exception e) {
                RuntimeException ex = new RuntimeException("Failed to fetch open id config from " + configURI,
                        e);
                logger.fatal("adAuth config failure", ex);
                throw ex;
            }
            logger.info(
                    "To speed up startup please define \"adAuth\": {\"openIdConfig\": {\"authorization_endpoint\": \""
                            + openIdConfig.getString("authorization_endpoint") + "\", \"token_endpoint\": \""
                            + openIdConfig.getString("token_endpoint") + "\" } }");
        }
        adAuth.put("openIdConfig", openIdConfig);
        SetupAzureAdConnectAuth.setupAzureAd(adAuth, router, publicURI, virtualHost, sessionHandler,
                httpClient);
    }

    JsonObject basicAuth = config().getJsonObject("basicAuth");
    if (basicAuth != null) {
        AuthHandler basicAuthHandler = BasicAuthHandler.create(
                new SimpleConfigAuthProvider(basicAuth.getJsonObject("users")),
                basicAuth.getString("realm", "nitor"));
        router.route(basicAuth.getString("route", "/*")).handler(basicAuthHandler);
    }

    if (sessionHandler != null) {
        router.get("/cookieCheck").handler(routingContext -> {
            Map<String, String> headers = sessionHandler.getSessionData(routingContext);
            StringBuilder sb = new StringBuilder(2048);
            if (headers == null) {
                sb.append("No valid session");
            } else {
                headers.forEach((key, value) -> {
                    sb.append(key).append('=');
                    if (key.startsWith(SECRET_DATA_PREFIX))
                        sb.append("<secret>");
                    else
                        sb.append(value);
                    sb.append('\n');
                });
            }
            routingContext.response().putHeader(CONTENT_TYPE, "text/plain; charset=utf-8").end(sb.toString());
        });
    }

    JsonArray customizeConf = config().getJsonArray("customize");
    if (customizeConf != null) {
        customizeConf.forEach(c -> {
            JsonObject conf = (JsonObject) c;
            InlineJS inlineJs = new InlineJS(vertx, conf.getString("jsFile", "custom.js"));
            router.route(conf.getString("route")).handler(ctx -> {
                inlineJs.call("handleRequest", ctx.request(), ctx);
                ctx.addHeadersEndHandler((v) -> inlineJs.call("handleResponse", ctx.response(), ctx));
                ctx.next();
            });
        });
    }

    setupServices(config(), httpServerOptions, router, new ServiceRouterBuilder(), httpClient, sessionHandler,
            adAuth, isOrigReqHttps);

    router.route().failureHandler(routingContext -> {
        String error = "ERROR";
        int statusCode = routingContext.statusCode();
        Throwable t = routingContext.failure();
        logger.info("Handling failure statusCode=" + statusCode, t);
        HttpServerResponse resp = routingContext.response();
        if (resp.ended()) {
            return;
        }
        if (resp.headWritten()) {
            resp.end();
            routingContext.request().connection().close();
            return;
        }
        if (t != null) {
            if (t instanceof ProxyException) {
                statusCode = ((ProxyException) t).statusCode;
            }
            error = "ERROR: " + t.toString();
        }
        resp.setStatusCode(statusCode != -1 ? statusCode : INTERNAL_SERVER_ERROR.code());
        resp.headers().set("Content-Type", "text/plain; charset=UTF-8");
        resp.headers().set("Content-Length", Integer.toString(error.length()));
        resp.end(error);
    });

    vertx.createHttpServer(httpServerOptions).requestHandler(router).listen(listenPort, listenHost);
}