cloudflare/cloudflared

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
2021.3.2

Branches

Tags

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

Clone

HTTPS

Download ZIP

connection/connection_test.go

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