Skip to content

Commit

Permalink
Support path and method for the header
Browse files Browse the repository at this point in the history
Signed-off-by: George Gastaldi <[email protected]>
  • Loading branch information
gastaldi committed Nov 2, 2021
1 parent 79c82c9 commit 3933daf
Show file tree
Hide file tree
Showing 8 changed files with 122 additions and 25 deletions.
14 changes: 13 additions & 1 deletion docs/src/main/asciidoc/http-reference.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,23 @@ To enable HTTP headers to be sent on every response, add the following propertie

[source, properties]
----
quarkus.http.header."X-Content-Type-Options"=nosniff
quarkus.http.header."X-Content-Type-Options".value=nosniff
----

This will include the `X-Content-Type-Options: nosniff` HTTP Header on responses for requests performed on any resource in the application.

You can also specify a `path` pattern and the HTTP `methods` the header needs to be applied:

[source, properties]
----
quarkus.http.header.Pragma.value=no-cache
quarkus.http.header.Pragma.path=/headers/pragma
quarkus.http.header.Pragma.methods=GET,HEAD
----

This will apply the `Pragma` header only when the `/headers/pragma` resource is called with a `GET` or a `HEAD` method

include::{generated-dir}/config/quarkus-vertx-http-config-group-header-config.adoc[leveloffset=+1, opts=optional]

== HTTP/2 Support

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package io.quarkus.vertx.http.runtime;

import java.util.List;
import java.util.Optional;

import io.quarkus.runtime.annotations.ConfigGroup;
import io.quarkus.runtime.annotations.ConfigItem;

/**
* Configuration that allows for setting an HTTP header
*/
@ConfigGroup
public class HeaderConfig {

/**
* The path this header should be applied
*/
@ConfigItem(defaultValue = "/*")
public String path;

/**
* The value for this header configuration
*/
@ConfigItem
public String value;

/**
* The HTTP methods for this header configuration
*/
@ConfigItem
public Optional<List<String>> methods;
}
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ public class HttpConfiguration {
* Additional HTTP Headers always sent in the response
*/
@ConfigItem
public Map<String, String> header;
public Map<String, HeaderConfig> header;

public ProxyConfig proxy;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
Expand Down Expand Up @@ -227,7 +228,8 @@ public static void startServerAfterFailedStart() {
doServerStart(vertx, buildConfig, config, LaunchMode.DEVELOPMENT, new Supplier<Integer>() {
@Override
public Integer get() {
return ProcessorInfo.availableProcessors() * 2; //this is dev mode, so the number of IO threads not always being 100% correct does not really matter in this case
return ProcessorInfo.availableProcessors()
* 2; //this is dev mode, so the number of IO threads not always being 100% correct does not really matter in this case
}
}, null, false);
} catch (Exception e) {
Expand Down Expand Up @@ -361,13 +363,32 @@ public void handle(Void e) {
});
}
// Headers sent on any request, regardless of the response
Map<String, String> headers = httpConfiguration.header;
Map<String, HeaderConfig> headers = httpConfiguration.header;
if (!headers.isEmpty()) {
httpRouteRouter.route().order(Integer.MIN_VALUE).handler(new Handler<RoutingContext>() {
@Override
public void handle(RoutingContext event) {
event.response().headers().addAll(headers);
event.next();
// Creates a handler for each header entry
headers.forEach((name, config) -> {
if (!config.methods.isPresent()) {
httpRouteRouter.route(config.path)
.order(Integer.MIN_VALUE)
.handler(new Handler<RoutingContext>() {
@Override
public void handle(RoutingContext event) {
event.response().headers().add(name, config.value);
event.next();
}
});
} else {
for (String method : config.methods.get()) {
httpRouteRouter.route(HttpMethod.valueOf(method.toUpperCase(Locale.ROOT)), config.path)
.order(Integer.MIN_VALUE)
.handler(new Handler<RoutingContext>() {
@Override
public void handle(RoutingContext event) {
event.response().headers().add(name, config.value);
event.next();
}
});
}
}
});
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package io.quarkus.it.vertx;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;

@Path("/headers")
public class HeaderResource {

@GET
@Path("/any")
public String headers() {
return "ok";
}

@GET
@Path("/pragma")
public String pragmaHeaderMustBeSet() {
return "ok";
}

@GET
@Path("/override")
public Response headersOverride() {
return Response.ok("ok").header("foo", "abc").build();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;

/**
*
Expand All @@ -14,16 +13,4 @@ public class SimpleResource {
public String accessLogTest() {
return "passed";
}

@GET
@Path("/headers")
public String headers() {
return "ok";
}

@GET
@Path("/headers-override")
public Response headersOverride() {
return Response.ok("ok").header("foo", "abc").build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,8 @@ quarkus.http.access-log.enabled=true
quarkus.http.access-log.log-to-file=true
quarkus.http.access-log.base-file-name=quarkus-access-log
quarkus.http.access-log.log-directory=target
quarkus.http.header.foo=bar
quarkus.http.header.foo.value=bar
quarkus.http.header.Pragma.value=no-cache
quarkus.http.header.Pragma.path=/headers/pragma
quarkus.http.header.Pragma.methods=GET,HEAD
quarkus.native.additional-build-args=-H:IncludeResources=.*\\.jks,-H:EnableURLProtocols=http\\,https
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.quarkus.it.vertx;

import static io.restassured.RestAssured.given;
import static org.hamcrest.Matchers.emptyOrNullString;
import static org.hamcrest.Matchers.is;

import org.junit.jupiter.api.Test;
Expand All @@ -13,20 +14,33 @@ public class HeadersTestCase {
@Test
void testAdditionalHeaders() {
given()
.get("/simple/headers")
.get("/headers/any")
.then()
.header("foo", is("bar"))
.header("Pragma", emptyOrNullString())
.body(is("ok"));

}

@Test
void testAdditionalHeadersOverride() {
given()
.get("/simple/headers-override")
.get("/headers/override")
.then()
.header("foo", is("abc"))
.header("Pragma", emptyOrNullString())
.body(is("ok"));
}

@Test
void testPragmaIsSent() {
given()
.get("/headers/pragma")
.then()
.header("foo", is("bar"))
.header("Pragma", is("no-cache"))
.body(is("ok"));

}

}

0 comments on commit 3933daf

Please sign in to comment.