diff --git a/components/app/app.go b/components/app/app.go
index 0d857473d..1236568db 100644
--- a/components/app/app.go
+++ b/components/app/app.go
@@ -34,7 +34,7 @@ var (
Name = "HORNET"
// Version of the app.
- Version = "2.0.0"
+ Version = "2.0.1"
)
func App() *app.App {
diff --git a/components/restapi/component.go b/components/restapi/component.go
index 0dbb9535c..290c4d8ff 100644
--- a/components/restapi/component.go
+++ b/components/restapi/component.go
@@ -97,7 +97,9 @@ func provide(c *dig.Container) error {
ParamsRestAPI.DebugRequestLoggerEnabled,
)
e.Use(middleware.CORS())
- e.Use(middleware.Gzip())
+ if ParamsRestAPI.UseGZIP {
+ e.Use(middleware.Gzip())
+ }
e.Use(middleware.BodyLimit(ParamsRestAPI.Limits.MaxBodyLength))
return e
diff --git a/components/restapi/params.go b/components/restapi/params.go
index 469d2cefb..96f66ab64 100644
--- a/components/restapi/params.go
+++ b/components/restapi/params.go
@@ -14,6 +14,8 @@ type ParametersRestAPI struct {
PublicRoutes []string `usage:"the HTTP REST routes which can be called without authorization. Wildcards using * are allowed"`
// the HTTP REST routes which need to be called with authorization. Wildcards using * are allowed
ProtectedRoutes []string `usage:"the HTTP REST routes which need to be called with authorization. Wildcards using * are allowed"`
+ // UseGZIP defines whether to use the gzip middleware to compress HTTP responses
+ UseGZIP bool `default:"true" usage:"use the gzip middleware to compress HTTP responses"`
// whether the debug logging for requests should be enabled
DebugRequestLoggerEnabled bool `default:"false" usage:"whether the debug logging for requests should be enabled"`
@@ -55,6 +57,8 @@ var ParamsRestAPI = &ParametersRestAPI{
"/api/participation/v1/events*",
"/api/participation/v1/outputs*",
"/api/participation/v1/addresses*",
+ "/api/core/v0/*",
+ "/api/core/v1/*",
},
ProtectedRoutes: []string{
"/api/*",
diff --git a/config_defaults.json b/config_defaults.json
index 8c6e10f8c..00c39a2ac 100644
--- a/config_defaults.json
+++ b/config_defaults.json
@@ -191,11 +191,14 @@
"/api/mqtt/v1",
"/api/participation/v1/events*",
"/api/participation/v1/outputs*",
- "/api/participation/v1/addresses*"
+ "/api/participation/v1/addresses*",
+ "/api/core/v0/*",
+ "/api/core/v1/*"
],
"protectedRoutes": [
"/api/*"
],
+ "useGZIP": true,
"debugRequestLoggerEnabled": false,
"jwtAuth": {
"salt": "HORNET"
diff --git a/configuration.md b/configuration.md
index 6b9840c9f..04cd1bd40 100755
--- a/configuration.md
+++ b/configuration.md
@@ -481,16 +481,17 @@ Example:
## 13. RestAPI
-| Name | Description | Type | Default value |
-| --------------------------- | ---------------------------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
-| enabled | Whether the REST API plugin is enabled | boolean | true |
-| bindAddress | The bind address on which the REST API listens on | string | "0.0.0.0:14265" |
-| publicRoutes | The HTTP REST routes which can be called without authorization. Wildcards using \* are allowed | array | /health
/api/routes
/api/core/v2/info
/api/core/v2/tips
/api/core/v2/blocks\*
/api/core/v2/transactions\*
/api/core/v2/milestones\*
/api/core/v2/outputs\*
/api/core/v2/treasury
/api/core/v2/receipts\*
/api/debug/v1/\*
/api/indexer/v1/\*
/api/mqtt/v1
/api/participation/v1/events\*
/api/participation/v1/outputs\*
/api/participation/v1/addresses\* |
-| protectedRoutes | The HTTP REST routes which need to be called with authorization. Wildcards using \* are allowed | array | /api/\* |
-| debugRequestLoggerEnabled | Whether the debug logging for requests should be enabled | boolean | false |
-| [jwtAuth](#restapi_jwtauth) | Configuration for JWT Auth | object | |
-| [pow](#restapi_pow) | Configuration for Proof of Work | object | |
-| [limits](#restapi_limits) | Configuration for limits | object | |
+| Name | Description | Type | Default value |
+| --------------------------- | ---------------------------------------------------------------------------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| enabled | Whether the REST API plugin is enabled | boolean | true |
+| bindAddress | The bind address on which the REST API listens on | string | "0.0.0.0:14265" |
+| publicRoutes | The HTTP REST routes which can be called without authorization. Wildcards using \* are allowed | array | /health
/api/routes
/api/core/v2/info
/api/core/v2/tips
/api/core/v2/blocks\*
/api/core/v2/transactions\*
/api/core/v2/milestones\*
/api/core/v2/outputs\*
/api/core/v2/treasury
/api/core/v2/receipts\*
/api/debug/v1/\*
/api/indexer/v1/\*
/api/mqtt/v1
/api/participation/v1/events\*
/api/participation/v1/outputs\*
/api/participation/v1/addresses\*
/api/core/v0/\*
/api/core/v1/\* |
+| protectedRoutes | The HTTP REST routes which need to be called with authorization. Wildcards using \* are allowed | array | /api/\* |
+| useGZIP | Use the gzip middleware to compress HTTP responses | boolean | true |
+| debugRequestLoggerEnabled | Whether the debug logging for requests should be enabled | boolean | false |
+| [jwtAuth](#restapi_jwtauth) | Configuration for JWT Auth | object | |
+| [pow](#restapi_pow) | Configuration for Proof of Work | object | |
+| [limits](#restapi_limits) | Configuration for limits | object | |
### JWT Auth
@@ -535,11 +536,14 @@ Example:
"/api/mqtt/v1",
"/api/participation/v1/events*",
"/api/participation/v1/outputs*",
- "/api/participation/v1/addresses*"
+ "/api/participation/v1/addresses*",
+ "/api/core/v0/*",
+ "/api/core/v1/*"
],
"protectedRoutes": [
"/api/*"
],
+ "useGZIP": true,
"debugRequestLoggerEnabled": false,
"jwtAuth": {
"salt": "HORNET"
diff --git a/pkg/restapi/proxy.go b/pkg/restapi/proxy.go
index dc4890f6d..b7bf9eff5 100644
--- a/pkg/restapi/proxy.go
+++ b/pkg/restapi/proxy.go
@@ -3,6 +3,7 @@ package restapi
import (
"errors"
"fmt"
+ "net/http"
"net/url"
"strings"
"sync"
@@ -110,6 +111,10 @@ func NewDynamicProxy(e *echo.Echo, prefix string) *DynamicProxy {
}
func (p *DynamicProxy) middleware(prefix string) echo.MiddlewareFunc {
+ hasAcceptEncodingGZIP := func(header http.Header) bool {
+ return strings.Contains(header.Get(echo.HeaderAcceptEncoding), "gzip")
+ }
+
config := middleware.DefaultProxyConfig
config.Skipper = p.balancer.skipper
config.Balancer = p.balancer
@@ -117,7 +122,33 @@ func (p *DynamicProxy) middleware(prefix string) echo.MiddlewareFunc {
fmt.Sprintf("^%s/%s/*", p.balancer.prefix, prefix): "/$1",
}
- return middleware.ProxyWithConfig(config)
+ configUncompressed := middleware.DefaultProxyConfig
+ configUncompressed.Skipper = p.balancer.skipper
+ configUncompressed.Balancer = p.balancer
+ configUncompressed.Rewrite = map[string]string{
+ fmt.Sprintf("^%s/%s/*", p.balancer.prefix, prefix): "/$1",
+ }
+ //nolint:forcetypeassert // we can safely assume that the DefaultTransport is a http.Transport
+ transportUncompressed := http.DefaultTransport.(*http.Transport).Clone()
+ transportUncompressed.DisableCompression = true
+ configUncompressed.Transport = transportUncompressed
+
+ return func(next echo.HandlerFunc) echo.HandlerFunc {
+ return func(c echo.Context) error {
+ // we forward compressed requests if the client also supports compressed responses
+ compressed := hasAcceptEncodingGZIP(c.Request().Header)
+
+ // we need to remove "Accept-Encoding" headers in the request,
+ // because the transport handles this automatically if not set
+ c.Request().Header.Del(echo.HeaderAcceptEncoding)
+
+ if !compressed {
+ return middleware.ProxyWithConfig(configUncompressed)(next)(c)
+ }
+
+ return middleware.ProxyWithConfig(config)(next)(c)
+ }
+ }
}
func (p *DynamicProxy) AddGroup(prefix string) *echo.Group {