Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/components/proxy/plugins/secwebsocketkey/sec-websocket-key.go
2500 views
1
// Copyright (c) 2021 Gitpod GmbH. All rights reserved.
2
// Licensed under the GNU Affero General Public License (AGPL).
3
// See License.AGPL.txt in the project root for license information.
4
5
package secwebsocketkey
6
7
import (
8
"crypto/rand"
9
"encoding/base64"
10
"net/http"
11
12
"github.com/caddyserver/caddy/v2"
13
"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
14
"github.com/caddyserver/caddy/v2/caddyconfig/httpcaddyfile"
15
"github.com/caddyserver/caddy/v2/modules/caddyhttp"
16
)
17
18
const (
19
secWebsocketKeyHeader = "Sec-WebSocket-Key"
20
secWebsocketKeyModule = "gitpod.sec_websocket_key"
21
)
22
23
func init() {
24
caddy.RegisterModule(SecWebsocketKey{})
25
httpcaddyfile.RegisterHandlerDirective(secWebsocketKeyModule, parseWebsocketCaddyfile)
26
}
27
28
// SecWebsocketKey implements an HTTP handler that adds a random sec-websocket-key if the header is missing
29
type SecWebsocketKey struct {
30
BaseDomain string `json:"base_domain,omitempty"`
31
Debug bool `json:"debug,omitempty"`
32
}
33
34
// CaddyModule returns the Caddy module information.
35
func (SecWebsocketKey) CaddyModule() caddy.ModuleInfo {
36
return caddy.ModuleInfo{
37
ID: "http.handlers.gitpod_sec_websocket_key",
38
New: func() caddy.Module { return new(SecWebsocketKey) },
39
}
40
}
41
42
// ServeHTTP implements caddyhttp.MiddlewareHandler.
43
func (m SecWebsocketKey) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error {
44
key := r.Header.Get(secWebsocketKeyHeader)
45
if key == "" {
46
buf := make([]byte, 20)
47
_, err := rand.Read(buf)
48
if err != nil {
49
return err
50
}
51
randomKey := base64.StdEncoding.EncodeToString(buf)
52
r.Header.Set(secWebsocketKeyHeader, randomKey)
53
}
54
55
return next.ServeHTTP(w, r)
56
}
57
58
// UnmarshalCaddyfile implements Caddyfile.Unmarshaler.
59
func (m *SecWebsocketKey) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
60
return nil
61
}
62
63
func parseWebsocketCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error) {
64
m := new(SecWebsocketKey)
65
err := m.UnmarshalCaddyfile(h.Dispenser)
66
if err != nil {
67
return nil, err
68
}
69
70
return m, nil
71
}
72
73
// Interface guards
74
var (
75
_ caddyhttp.MiddlewareHandler = (*SecWebsocketKey)(nil)
76
_ caddyfile.Unmarshaler = (*SecWebsocketKey)(nil)
77
)
78
79