cloudflare/cloudflared

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
2021.1.4

Branches

Tags

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

Clone

HTTPS

Download ZIP

connection/connection_test.go

152lines · modecode

1package connection
2
3import (
4 "fmt"
5 "io"
6 "net/http"
7 "net/url"
8 "testing"
9 "time"
10
11 "github.com/gobwas/ws/wsutil"
12 "github.com/rs/zerolog"
13 "github.com/stretchr/testify/assert"
14)
15
16const (
17 largeFileSize = 2 * 1024 * 1024
18)
19
20var (
21 testConfig = &Config{
22 OriginClient: &mockOriginClient{},
23 GracePeriod: time.Millisecond * 100,
24 }
25 log = zerolog.Nop()
26 testOriginURL = &url.URL{
27 Scheme: "https",
28 Host: "connectiontest.argotunnel.com",
29 }
30 testTunnelEventChan = make(chan Event)
31 testObserver = &Observer{
32 &log,
33 m,
34 []chan Event{testTunnelEventChan},
35 false,
36 }
37 testLargeResp = make([]byte, largeFileSize)
38)
39
40type testRequest struct {
41 name string
42 endpoint string
43 expectedStatus int
44 expectedBody []byte
45 isProxyError bool
46}
47
48type mockOriginClient struct {
49}
50
51func (moc *mockOriginClient) Proxy(w ResponseWriter, r *http.Request, isWebsocket bool) error {
52 if isWebsocket {
53 return wsEndpoint(w, r)
54 }
55 switch r.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
72type nowriter struct {
73 io.Reader
74}
75
76func (nowriter) Write(p []byte) (int, error) {
77 return 0, fmt.Errorf("Writer not implemented")
78}
79
80func wsEndpoint(w ResponseWriter, r *http.Request) error {
81 resp := &http.Response{
82 StatusCode: http.StatusSwitchingProtocols,
83 }
84 _ = w.WriteRespHeaders(resp)
85 clientReader := nowriter{r.Body}
86 go func() {
87 for {
88 data, err := wsutil.ReadClientText(clientReader)
89 if err != nil {
90 return
91 }
92 if err := wsutil.WriteServerText(w, data); err != nil {
93 return
94 }
95 }
96 }()
97 <-r.Context().Done()
98 return nil
99}
100
101func originRespEndpoint(w ResponseWriter, status int, data []byte) {
102 resp := &http.Response{
103 StatusCode: status,
104 }
105 _ = w.WriteRespHeaders(resp)
106 _, _ = w.Write(data)
107}
108
109type mockConnectedFuse struct{}
110
111func (mcf mockConnectedFuse) Connected() {}
112
113func (mcf mockConnectedFuse) IsConnected() bool {
114 return true
115}
116
117func TestIsEventStream(t *testing.T) {
118 tests := []struct {
119 headers http.Header
120 isEventStream bool
121 }{
122 {
123 headers: newHeader("Content-Type", "text/event-stream"),
124 isEventStream: true,
125 },
126 {
127 headers: newHeader("content-type", "text/event-stream"),
128 isEventStream: true,
129 },
130 {
131 headers: newHeader("Content-Type", "text/event-stream; charset=utf-8"),
132 isEventStream: true,
133 },
134 {
135 headers: newHeader("Content-Type", "application/json"),
136 isEventStream: false,
137 },
138 {
139 headers: http.Header{},
140 isEventStream: false,
141 },
142 }
143 for _, test := range tests {
144 assert.Equal(t, test.isEventStream, IsServerSentEvent(test.headers))
145 }
146}
147
148func newHeader(key, value string) http.Header {
149 header := http.Header{}
150 header.Add(key, value)
151 return header
152}