CorsMiddleware extends AbstractWebMiddleware<HttpRequest, NRES> { @Override public HttpResponse handle(HttpRequest request, MiddlewareChain<HttpRequest, NRES, ?, ?> chain) { if (isCORSRequest(request)) { if (!isOriginAllowed(request) || methods.stream().noneMatch(x -> x.equalsIgnoreCase(request.getRequestMethod()))) { return invalidCors(request); } if (isPreflightRequest(request)) { Headers responseHeaders = Headers.empty(); if (isAnyOriginAllowed()) { responseHeaders.put("Access-Control-Allow-Origin", "*"); } else { String origin = some(request.getHeaders(), headers -> headers.get("origin")) .orElse("*"); responseHeaders.put("Access-Control-Allow-Origin", origin); } if (methods != null && !methods.isEmpty()) { responseHeaders.put("Access-Control-Allow-Methods", String.join(", ", methods)); } if (headers != null && !headers.isEmpty()) { responseHeaders.put("Access-Control-Allow-Headers", String.join(", ", headers)); } if (credentials) { responseHeaders.put("Access-Control-Allow-Credentials", "true"); } if (maxage > 0L) { responseHeaders.put("Access-Control-Max-Age", String.valueOf(maxage)); } return builder(HttpResponse.of("")) .set(HttpResponse::setStatus, 200) .set(HttpResponse::setHeaders, responseHeaders) .build(); } } HttpResponse response = castToHttpResponse(chain.next(request)); if (isCORSRequest(request)) { if (origins != null && !origins.isEmpty()) { header(response, "Access-Control-Allow-Origin", String.join(", ", origins)); } if (credentials) { header(response, "Access-Control-Allow-Credentials", "true"); } } return response; } CorsMiddleware(); @Override HttpResponse handle(HttpRequest request, MiddlewareChain<HttpRequest, NRES, ?, ?> chain); void setMethods(Set<String> methods); void setOrigins(Set<String> origins); void setHeaders(Set<String> headers); void setMaxage(Long maxage); void setCredentials(boolean credentials);  }
@Test void testAddHeaders() { HttpRequest request = builder(new DefaultHttpRequest()) .set(HttpRequest::setHeaders, Headers.of("Origin", "http: .set(HttpRequest::setRequestMethod, "POST") .build(); MiddlewareChain<HttpRequest, HttpResponse, ?, ?> chain = new DefaultMiddlewareChain<>( new AnyPredicate<>(), null, (Endpoint<HttpRequest, HttpResponse>) req -> builder(HttpResponse.of("hello")) .set(HttpResponse::setHeaders, Headers.of("Content-Type", "text/html")).build()); CorsMiddleware<HttpResponse> sut = new CorsMiddleware<>(); HttpResponse result = sut.handle(request, chain); Headers headers = result.getHeaders(); assertThat(result.getStatus()).isEqualTo(200); assertThat(headers) .contains(entry("Access-Control-Allow-Origin", "*"), entry("Content-Type", "text/html")); assertThat(result.getBodyAsString()).isEqualTo("hello"); }
@Test void testCORSRequestWithLowerCaseMethod() { HttpRequest request = builder(new DefaultHttpRequest()) .set(HttpRequest::setHeaders, Headers.of("Origin", "http: .set(HttpRequest::setRequestMethod, "post") .build(); MiddlewareChain<HttpRequest, HttpResponse, ?, ?> chain = new DefaultMiddlewareChain<>( new AnyPredicate<>(), null, (Endpoint<HttpRequest, HttpResponse>) req -> builder(HttpResponse.of("hello")) .set(HttpResponse::setHeaders, Headers.of("Content-Type", "text/html")).build()); CorsMiddleware<HttpResponse> sut = new CorsMiddleware<>(); HttpResponse result = sut.handle(request, chain); Headers headers = result.getHeaders(); assertThat(result.getStatus()).isEqualTo(200); assertThat(headers) .contains(entry("Access-Control-Allow-Origin", "*"), entry("Content-Type", "text/html")); assertThat(result.getBodyAsString()).isEqualTo("hello"); }