Path: blob/main/components/proxy/plugins/secwebsocketkey/sec-websocket-key.go
2500 views
// Copyright (c) 2021 Gitpod GmbH. All rights reserved.1// Licensed under the GNU Affero General Public License (AGPL).2// See License.AGPL.txt in the project root for license information.34package secwebsocketkey56import (7"crypto/rand"8"encoding/base64"9"net/http"1011"github.com/caddyserver/caddy/v2"12"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"13"github.com/caddyserver/caddy/v2/caddyconfig/httpcaddyfile"14"github.com/caddyserver/caddy/v2/modules/caddyhttp"15)1617const (18secWebsocketKeyHeader = "Sec-WebSocket-Key"19secWebsocketKeyModule = "gitpod.sec_websocket_key"20)2122func init() {23caddy.RegisterModule(SecWebsocketKey{})24httpcaddyfile.RegisterHandlerDirective(secWebsocketKeyModule, parseWebsocketCaddyfile)25}2627// SecWebsocketKey implements an HTTP handler that adds a random sec-websocket-key if the header is missing28type SecWebsocketKey struct {29BaseDomain string `json:"base_domain,omitempty"`30Debug bool `json:"debug,omitempty"`31}3233// CaddyModule returns the Caddy module information.34func (SecWebsocketKey) CaddyModule() caddy.ModuleInfo {35return caddy.ModuleInfo{36ID: "http.handlers.gitpod_sec_websocket_key",37New: func() caddy.Module { return new(SecWebsocketKey) },38}39}4041// ServeHTTP implements caddyhttp.MiddlewareHandler.42func (m SecWebsocketKey) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error {43key := r.Header.Get(secWebsocketKeyHeader)44if key == "" {45buf := make([]byte, 20)46_, err := rand.Read(buf)47if err != nil {48return err49}50randomKey := base64.StdEncoding.EncodeToString(buf)51r.Header.Set(secWebsocketKeyHeader, randomKey)52}5354return next.ServeHTTP(w, r)55}5657// UnmarshalCaddyfile implements Caddyfile.Unmarshaler.58func (m *SecWebsocketKey) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {59return nil60}6162func parseWebsocketCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error) {63m := new(SecWebsocketKey)64err := m.UnmarshalCaddyfile(h.Dispenser)65if err != nil {66return nil, err67}6869return m, nil70}7172// Interface guards73var (74_ caddyhttp.MiddlewareHandler = (*SecWebsocketKey)(nil)75_ caddyfile.Unmarshaler = (*SecWebsocketKey)(nil)76)777879