mirror of
https://github.com/pomerium/pomerium.git
synced 2025-04-29 10:26:29 +02:00
core/envoy: format envoy local replies (#5067)
This commit is contained in:
parent
fab2181be4
commit
494dc4accc
4 changed files with 56 additions and 12 deletions
|
@ -1,12 +1,16 @@
|
|||
package envoyconfig
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
envoy_config_accesslog_v3 "github.com/envoyproxy/go-control-plane/envoy/config/accesslog/v3"
|
||||
envoy_config_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
|
||||
envoy_config_route_v3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3"
|
||||
envoy_http_connection_manager "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3"
|
||||
|
||||
"github.com/pomerium/pomerium/config"
|
||||
"github.com/pomerium/pomerium/internal/httputil"
|
||||
"github.com/pomerium/pomerium/ui"
|
||||
)
|
||||
|
||||
func (b *Builder) buildVirtualHost(
|
||||
|
@ -33,7 +37,7 @@ func (b *Builder) buildVirtualHost(
|
|||
// coming directly from envoy
|
||||
func (b *Builder) buildLocalReplyConfig(
|
||||
options *config.Options,
|
||||
) *envoy_http_connection_manager.LocalReplyConfig {
|
||||
) (*envoy_http_connection_manager.LocalReplyConfig, error) {
|
||||
// add global headers for HSTS headers (#2110)
|
||||
var headers []*envoy_config_core_v3.HeaderValueOption
|
||||
// if we're the proxy or authenticate service, add our global headers
|
||||
|
@ -41,6 +45,18 @@ func (b *Builder) buildLocalReplyConfig(
|
|||
headers = toEnvoyHeaders(options.GetSetResponseHeaders())
|
||||
}
|
||||
|
||||
data := map[string]any{
|
||||
"status": "%RESPONSE_CODE%",
|
||||
"statusText": "%RESPONSE_CODE_DETAILS%",
|
||||
"requestId": "%STREAM_ID%",
|
||||
}
|
||||
httputil.AddBrandingOptionsToMap(data, options.BrandingOptions)
|
||||
|
||||
bs, err := ui.RenderPage("Error", "Error", data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error rendering error page for local reply: %w", err)
|
||||
}
|
||||
|
||||
return &envoy_http_connection_manager.LocalReplyConfig{
|
||||
Mappers: []*envoy_http_connection_manager.ResponseMapper{{
|
||||
Filter: &envoy_config_accesslog_v3.AccessLogFilter{
|
||||
|
@ -48,7 +64,17 @@ func (b *Builder) buildLocalReplyConfig(
|
|||
ResponseFlagFilter: &envoy_config_accesslog_v3.ResponseFlagFilter{},
|
||||
},
|
||||
},
|
||||
BodyFormatOverride: &envoy_config_core_v3.SubstitutionFormatString{
|
||||
ContentType: "text/html; charset=UTF-8",
|
||||
Format: &envoy_config_core_v3.SubstitutionFormatString_TextFormatSource{
|
||||
TextFormatSource: &envoy_config_core_v3.DataSource{
|
||||
Specifier: &envoy_config_core_v3.DataSource_InlineBytes{
|
||||
InlineBytes: bs,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
HeadersToAdd: headers,
|
||||
}},
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
|
|
@ -284,6 +284,11 @@ func (b *Builder) buildMainHTTPConnectionManagerFilter(
|
|||
return nil, err
|
||||
}
|
||||
|
||||
localReply, err := b.buildLocalReplyConfig(cfg.Options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
mgr := &envoy_http_connection_manager.HttpConnectionManager{
|
||||
AlwaysSetRequestIdInResponse: true,
|
||||
CodecType: cfg.Options.GetCodecType().ToEnvoy(),
|
||||
|
@ -304,7 +309,7 @@ func (b *Builder) buildMainHTTPConnectionManagerFilter(
|
|||
UseRemoteAddress: &wrapperspb.BoolValue{Value: true},
|
||||
SkipXffAppend: cfg.Options.SkipXffAppend,
|
||||
XffNumTrustedHops: cfg.Options.XffNumTrustedHops,
|
||||
LocalReplyConfig: b.buildLocalReplyConfig(cfg.Options),
|
||||
LocalReplyConfig: localReply,
|
||||
NormalizePath: wrapperspb.Bool(true),
|
||||
}
|
||||
|
||||
|
|
|
@ -52,9 +52,7 @@
|
|||
},
|
||||
"timeout": "10s"
|
||||
},
|
||||
"metadataContextNamespaces": [
|
||||
"com.pomerium.client-certificate-info"
|
||||
],
|
||||
"metadataContextNamespaces": ["com.pomerium.client-certificate-info"],
|
||||
"statusOnError": {
|
||||
"code": "InternalServerError"
|
||||
},
|
||||
|
@ -108,6 +106,12 @@
|
|||
"localReplyConfig": {
|
||||
"mappers": [
|
||||
{
|
||||
"bodyFormatOverride": {
|
||||
"contentType": "text/html; charset=UTF-8",
|
||||
"textFormatSource": {
|
||||
"inlineBytes": "PCFET0NUWVBFIGh0bWw+CjxodG1sIGxhbmc9ImVuIj4KICA8aGVhZD4KICAgIDxtZXRhIGNoYXJzZXQ9InV0Zi04IiAvPgogICAgPGxpbmsgaWQ9ImZhdmljb24iIHJlbD0ic2hvcnRjdXQgaWNvbiIgaHJlZj0iLy5wb21lcml1bS9mYXZpY29uLmljbz92PTIiIC8+CiAgICA8bGluawogICAgICBjbGFzcz0icG9tZXJpdW1fZmF2aWNvbiIKICAgICAgcmVsPSJhcHBsZS10b3VjaC1pY29uIgogICAgICBzaXplcz0iMTgweDE4MCIKICAgICAgaHJlZj0iLy5wb21lcml1bS9hcHBsZS10b3VjaC1pY29uLnBuZyIKICAgIC8+CiAgICA8bGluawogICAgICBjbGFzcz0icG9tZXJpdW1fZmF2aWNvbiIKICAgICAgcmVsPSJpY29uIgogICAgICBzaXplcz0iMzJ4MzIiCiAgICAgIGhyZWY9Ii8ucG9tZXJpdW0vZmF2aWNvbi0zMngzMi5wbmciCiAgICAvPgogICAgPGxpbmsKICAgICAgY2xhc3M9InBvbWVyaXVtX2Zhdmljb24iCiAgICAgIHJlbD0iaWNvbiIKICAgICAgc2l6ZXM9IjE2eDE2IgogICAgICBocmVmPSIvLnBvbWVyaXVtL2Zhdmljb24tMTZ4MTYucG5nIgogICAgLz4KICAgIDxtZXRhCiAgICAgIG5hbWU9InZpZXdwb3J0IgogICAgICBjb250ZW50PSJ3aWR0aD1kZXZpY2Utd2lkdGgsIGluaXRpYWwtc2NhbGU9MSwgc2hyaW5rLXRvLWZpdD1ubyIKICAgIC8+CiAgICA8dGl0bGU+RXJyb3I8L3RpdGxlPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSIvLnBvbWVyaXVtL2luZGV4LmNzcyIgLz4KICA8L2hlYWQ+CiAgPGJvZHk+CiAgICA8bm9zY3JpcHQ+WW91IG5lZWQgdG8gZW5hYmxlIEphdmFTY3JpcHQgdG8gcnVuIHRoaXMgYXBwLjwvbm9zY3JpcHQ+CiAgICA8ZGl2IGlkPSJyb290Ij48L2Rpdj4KICAgIDxzY3JpcHQ+CiAgICAgIHdpbmRvdy5QT01FUklVTV9EQVRBID0geyJwYWdlIjoiRXJyb3IiLCJyZXF1ZXN0SWQiOiIlU1RSRUFNX0lEJSIsInN0YXR1cyI6IiVSRVNQT05TRV9DT0RFJSIsInN0YXR1c1RleHQiOiIlUkVTUE9OU0VfQ09ERV9ERVRBSUxTJSJ9OwogICAgPC9zY3JpcHQ+CiAgICA8c2NyaXB0IHNyYz0iLy5wb21lcml1bS9pbmRleC5qcyI+PC9zY3JpcHQ+CiAgPC9ib2R5Pgo8L2h0bWw+Cg=="
|
||||
}
|
||||
},
|
||||
"filter": {
|
||||
"responseFlagFilter": {}
|
||||
},
|
||||
|
|
21
ui/embed.go
21
ui/embed.go
|
@ -27,18 +27,27 @@ func ServeFile(w http.ResponseWriter, r *http.Request, filePath string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// RenderPage rends the index.html page.
|
||||
func RenderPage(page, title string, data map[string]any) ([]byte, error) {
|
||||
if data == nil {
|
||||
data = make(map[string]any)
|
||||
}
|
||||
data["page"] = page
|
||||
|
||||
return renderIndex(map[string]any{
|
||||
"Title": title,
|
||||
"Data": data,
|
||||
})
|
||||
}
|
||||
|
||||
// ServePage serves the index.html page.
|
||||
func ServePage(w http.ResponseWriter, r *http.Request, page, title string, data map[string]interface{}) error {
|
||||
func ServePage(w http.ResponseWriter, r *http.Request, page, title string, data map[string]any) error {
|
||||
if data == nil {
|
||||
data = make(map[string]any)
|
||||
}
|
||||
data["csrfToken"] = csrf.Token(r)
|
||||
data["page"] = page
|
||||
|
||||
bs, err := renderIndex(map[string]any{
|
||||
"Title": title,
|
||||
"Data": data,
|
||||
})
|
||||
bs, err := RenderPage(page, title, data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue