add cors headers to http proxy

This commit is contained in:
terminal
2022-04-21 12:40:14 +03:00
parent 4f1216b14f
commit c3285354c1
8 changed files with 45 additions and 1 deletions

View File

@@ -401,6 +401,14 @@ See <<tls>> section
If set to `true` then Dshackle preserves _batch_ order based on request order.
Note that latter is ineffective and use this option only when a client cannot reference responses by their IDs.
| `сors-origin`
|
| Access-Control-Allow-Origin contents. If empty the header will be omitted in response
| `cors-allowed-headers`
| `Content-Type`
| Access-Control-Allow-Headers contents. Takes effect only if сors-origi is present in config
| `routes`
|
a| Routing paths for Proxy.

View File

@@ -55,6 +55,16 @@ open class ProxyConfig {
*/
var preserveBatchOrder: Boolean = false
/**
* Access-Control-Allow-Origin contents. If null then will omit this header completely
*/
var corsOrigin: String? = null
/**
* Access-Control-Allow-Headers contents. Takes effect only if corsOrigin is not null
*/
var corsAllowedHeaders: String = "Content-Type"
class Route(
/**
* URL binding for the route. http://$host:$port/$id

View File

@@ -64,6 +64,12 @@ class ProxyConfigReader : YamlConfigReader(), ConfigReader<ProxyConfig> {
getValueAsBool(input, "preserve-batch-order")?.let {
config.preserveBatchOrder = it
}
getValueAsString(input, "cors-origin")?.let {
config.corsOrigin = it
}
getValueAsString(input, "cors-allowed-headers")?.let {
config.corsAllowedHeaders = it
}
val currentRoutes = HashSet<String>()
getList<MappingNode>(input, "routes")?.let { routes ->
config.routes = routes.value.map { route ->

View File

@@ -49,6 +49,19 @@ class HttpHandler(
private val log = LoggerFactory.getLogger(HttpHandler::class.java)
}
private fun addCorsHeadersIfSet(resp: HttpServerResponse): HttpServerResponse {
return config.corsOrigin?.let {
resp.addHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, it)
.addHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, config.corsAllowedHeaders)
} ?: resp
}
fun preflight(): BiFunction<HttpServerRequest, HttpServerResponse, Publisher<Void>> {
return BiFunction { _, resp ->
addCorsHeadersIfSet(resp).send()
}
}
fun proxy(routeConfig: ProxyConfig.Route): BiFunction<HttpServerRequest, HttpServerResponse, Publisher<Void>> {
return BiFunction { req, resp ->
// handle access events
@@ -59,7 +72,8 @@ class HttpHandler(
val results = processRequest(routeConfig.blockchain, request, eventHandler)
// make sure that the access log handler is closed at the end, so it can render the logs
.doFinally { eventHandler.close() }
resp.addHeader(HttpHeaders.CONTENT_TYPE, "application/json")
addCorsHeadersIfSet(resp)
.addHeader(HttpHeaders.CONTENT_TYPE, "application/json")
.send(results)
}
}

View File

@@ -114,6 +114,7 @@ class ProxyServer(
config.routes.forEach { routeConfig ->
// TODO implement a manual handling of the routes and WS upgrade to have a better control over the connection and improve the access logging
routes.post("/" + routeConfig.id, httpHandler.proxy(routeConfig))
routes.options("/" + routeConfig.id, httpHandler.preflight())
if (config.websocketEnabled && wsHandler != null) {
routes.ws("/" + routeConfig.id, wsHandler.proxy(routeConfig))
}

View File

@@ -83,6 +83,8 @@ class ProxyConfigReaderSpec extends Specification {
act.port == 8080
act.preserveBatchOrder
act.routes.size() == 2
act.corsOrigin == "*"
act.corsAllowedHeaders == "Content-Type"
with(act.routes[0]) {
id == "ethereum"
blockchain == Chain.ETHEREUM

View File

@@ -31,6 +31,7 @@ class ProxyServerSpec extends Specification {
then:
1 * routes.post("/test", _)
1 * routes.options("/test", _)
1 * routes.ws("/test", _)
}

View File

@@ -3,6 +3,8 @@ proxy:
host: 0.0.0.0
port: 8080
preserve-batch-order: true
cors-origin: "*"
cors-allowed-headers: "Content-Type"
routes:
- id: ethereum
blockchain: ethereum