cloudflare/cloudflared

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
ffac598fabae3fa510dce39d05dc497912752de5

Branches

Tags

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

Clone

HTTPS

Download ZIP

connection/connection_test.go

146lines · 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 testObserver = NewObserver(&log, false)
31 testLargeResp = make([]byte, largeFileSize)
32)
33
34type testRequest struct {
35 name string
36 endpoint string
37 expectedStatus int
38 expectedBody []byte
39 isProxyError bool
40}
41
42type mockOriginClient struct {
43}
44
45func (moc *mockOriginClient) Proxy(w ResponseWriter, r *http.Request, isWebsocket bool) error {
46 if isWebsocket {
47 return wsEndpoint(w, r)
48 }
49 switch r.URL.Path {
50 case "/ok":
51 originRespEndpoint(w, http.StatusOK, []byte(http.StatusText(http.StatusOK)))
52 case "/large_file":
53 originRespEndpoint(w, http.StatusOK, testLargeResp)
54 case "/400":
55 originRespEndpoint(w, http.StatusBadRequest, []byte(http.StatusText(http.StatusBadRequest)))
56 case "/500":
57 originRespEndpoint(w, http.StatusInternalServerError, []byte(http.StatusText(http.StatusInternalServerError)))
58 case "/error":
59 return fmt.Errorf("Failed to proxy to origin")
60 default:
61 originRespEndpoint(w, http.StatusNotFound, []byte("page not found"))
62 }
63 return nil
64}
65
66type nowriter struct {
67 io.Reader
68}
69
70func (nowriter) Write(p []byte) (int, error) {
71 return 0, fmt.Errorf("Writer not implemented")
72}
73
74func wsEndpoint(w ResponseWriter, r *http.Request) error {
75 resp := &http.Response{
76 StatusCode: http.StatusSwitchingProtocols,
77 }
78 _ = w.WriteRespHeaders(resp)
79 clientReader := nowriter{r.Body}
80 go func() {
81 for {
82 data, err := wsutil.ReadClientText(clientReader)
83 if err != nil {
84 return
85 }
86 if err := wsutil.WriteServerText(w, data); err != nil {
87 return
88 }
89 }
90 }()
91 <-r.Context().Done()
92 return nil
93}
94
95func originRespEndpoint(w ResponseWriter, status int, data []byte) {
96 resp := &http.Response{
97 StatusCode: status,
98 }
99 _ = w.WriteRespHeaders(resp)
100 _, _ = w.Write(data)
101}
102
103type mockConnectedFuse struct{}
104
105func (mcf mockConnectedFuse) Connected() {}
106
107func (mcf mockConnectedFuse) IsConnected() bool {
108 return true
109}
110
111func TestIsEventStream(t *testing.T) {
112 tests := []struct {
113 headers http.Header
114 isEventStream bool
115 }{
116 {
117 headers: newHeader("Content-Type", "text/event-stream"),
118 isEventStream: true,
119 },
120 {
121 headers: newHeader("content-type", "text/event-stream"),
122 isEventStream: true,
123 },
124 {
125 headers: newHeader("Content-Type", "text/event-stream; charset=utf-8"),
126 isEventStream: true,
127 },
128 {
129 headers: newHeader("Content-Type", "application/json"),
130 isEventStream: false,
131 },
132 {
133 headers: http.Header{},
134 isEventStream: false,
135 },
136 }
137 for _, test := range tests {
138 assert.Equal(t, test.isEventStream, IsServerSentEvent(test.headers))
139 }
140}
141
142func newHeader(key, value string) http.Header {
143 header := http.Header{}
144 header.Add(key, value)
145 return header
146}
147