cloudflare/cloudflared

Public

mirrored from https://github.com/cloudflare/cloudflaredAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
2021.10.5

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

connection/connection_test.go

161lines · modecode

1package connection
2
3import (
4 "context"
5 "fmt"
6 "io"
7 "net/http"
8 "net/url"
9 "testing"
10 "time"
11
12 "github.com/gobwas/ws/wsutil"
13 "github.com/rs/zerolog"
14 "github.com/stretchr/testify/assert"
15
16 "github.com/cloudflare/cloudflared/ingress"
17)
18
19const (
20 largeFileSize = 2 * 1024 * 1024
21)
22
23var (
24 unusedWarpRoutingService = (*ingress.WarpRoutingService)(nil)
25 testConfig = &Config{
26 OriginProxy: &mockOriginProxy{},
27 GracePeriod: time.Millisecond * 100,
28 }
29 log = zerolog.Nop()
30 testOriginURL = &url.URL{
31 Scheme: "https",
32 Host: "connectiontest.argotunnel.com",
33 }
34 testLargeResp = make([]byte, largeFileSize)
35)
36
37type testRequest struct {
38 name string
39 endpoint string
40 expectedStatus int
41 expectedBody []byte
42 isProxyError bool
43}
44
45type mockOriginProxy struct{}
46
47func (moc *mockOriginProxy) ProxyHTTP(
48 w ResponseWriter,
49 req *http.Request,
50 isWebsocket bool,
51) error {
52 if isWebsocket {
53 return wsEndpoint(w, req)
54 }
55 switch req.URL.Path {
56 case "/ok":
57 originRespEndpoint(w, http.StatusOK, []byte(http.StatusText(http.StatusOK)))
58 case "/large_file":
59 originRespEndpoint(w, http.StatusOK, testLargeResp)
60 case "/400":
61 originRespEndpoint(w, http.StatusBadRequest, []byte(http.StatusText(http.StatusBadRequest)))
62 case "/500":
63 originRespEndpoint(w, http.StatusInternalServerError, []byte(http.StatusText(http.StatusInternalServerError)))
64 case "/error":
65 return fmt.Errorf("Failed to proxy to origin")
66 default:
67 originRespEndpoint(w, http.StatusNotFound, []byte("page not found"))
68 }
69 return nil
70
71}
72
73func (moc *mockOriginProxy) ProxyTCP(
74 ctx context.Context,
75 rwa ReadWriteAcker,
76 r *TCPRequest,
77) error {
78 return nil
79}
80
81type nowriter struct {
82 io.Reader
83}
84
85func (nowriter) Write(p []byte) (int, error) {
86 return 0, fmt.Errorf("Writer not implemented")
87}
88
89func wsEndpoint(w ResponseWriter, r *http.Request) error {
90 resp := &http.Response{
91 StatusCode: http.StatusSwitchingProtocols,
92 }
93 _ = w.WriteRespHeaders(resp.StatusCode, resp.Header)
94 clientReader := nowriter{r.Body}
95 go func() {
96 for {
97 data, err := wsutil.ReadClientText(clientReader)
98 if err != nil {
99 return
100 }
101 if err := wsutil.WriteServerText(w, data); err != nil {
102 return
103 }
104 }
105 }()
106 <-r.Context().Done()
107 return nil
108}
109
110func originRespEndpoint(w ResponseWriter, status int, data []byte) {
111 resp := &http.Response{
112 StatusCode: status,
113 }
114 _ = w.WriteRespHeaders(resp.StatusCode, resp.Header)
115 _, _ = w.Write(data)
116}
117
118type mockConnectedFuse struct{}
119
120func (mcf mockConnectedFuse) Connected() {}
121
122func (mcf mockConnectedFuse) IsConnected() bool {
123 return true
124}
125
126func TestIsEventStream(t *testing.T) {
127 tests := []struct {
128 headers http.Header
129 isEventStream bool
130 }{
131 {
132 headers: newHeader("Content-Type", "text/event-stream"),
133 isEventStream: true,
134 },
135 {
136 headers: newHeader("content-type", "text/event-stream"),
137 isEventStream: true,
138 },
139 {
140 headers: newHeader("Content-Type", "text/event-stream; charset=utf-8"),
141 isEventStream: true,
142 },
143 {
144 headers: newHeader("Content-Type", "application/json"),
145 isEventStream: false,
146 },
147 {
148 headers: http.Header{},
149 isEventStream: false,
150 },
151 }
152 for _, test := range tests {
153 assert.Equal(t, test.isEventStream, IsServerSentEvent(test.headers))
154 }
155}
156
157func newHeader(key, value string) http.Header {
158 header := http.Header{}
159 header.Add(key, value)
160 return header
161}
162