/
noise.go
75 lines (62 loc) · 1.72 KB
/
noise.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package handlers
import (
stderrors "errors"
"github.com/labstack/echo/v4"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
"io"
"net/http"
"tailscale.com/control/controlhttp"
"tailscale.com/net/netutil"
"tailscale.com/types/key"
)
type NoiseHandlers struct {
controlKey key.MachinePrivate
createPeerHandler CreatePeerHandler
}
type CreatePeerHandler func(p key.MachinePublic) http.Handler
func NewNoiseHandlers(controlKey key.MachinePrivate, createPeerHandler CreatePeerHandler) *NoiseHandlers {
return &NoiseHandlers{
controlKey: controlKey,
createPeerHandler: createPeerHandler,
}
}
func (h *NoiseHandlers) Upgrade(c echo.Context) error {
conn, err := controlhttp.AcceptHTTP(c.Request().Context(), c.Response(), c.Request(), h.controlKey, nil)
if err != nil {
return logError(err)
}
handler := h.createPeerHandler(conn.Peer())
server := http.Server{}
server.Handler = h2c.NewHandler(handler, &http2.Server{})
if err := server.Serve(netutil.NewOneConnListener(conn, nil)); err != nil && !stderrors.Is(err, io.EOF) {
return err
}
return nil
}
type JsonBinder struct {
echo.DefaultBinder
}
func (b JsonBinder) Bind(i interface{}, c echo.Context) error {
if err := b.BindPathParams(c, i); err != nil {
return err
}
method := c.Request().Method
if method == http.MethodGet || method == http.MethodDelete || method == http.MethodHead {
if err := b.BindQueryParams(c, i); err != nil {
return err
}
}
if c.Request().ContentLength == 0 {
return nil
}
if err := c.Echo().JSONSerializer.Deserialize(c, i); err != nil {
switch err.(type) {
case *echo.HTTPError:
return err
default:
return echo.NewHTTPError(http.StatusBadRequest, err.Error()).SetInternal(err)
}
}
return nil
}