1
16
17 package ws
18
19 import (
20 "bytes"
21 "io"
22 "log"
23 "net/http"
24 "net/http/httptest"
25 "strings"
26 "testing"
27
28 "github.com/moby/spdystream"
29 "github.com/gorilla/websocket"
30 )
31
32 var upgrader = websocket.Upgrader{
33 ReadBufferSize: 1024,
34 WriteBufferSize: 1024,
35 }
36
37 var serverSpdyConn *spdystream.Connection
38
39
40
41 func ExampleConn() {
42 wsconn, _, _ := websocket.DefaultDialer.Dial("ws://localhost/", http.Header{"Origin": {"http://localhost/"}})
43 conn, _ := spdystream.NewConnection(NewConnection(wsconn), false)
44 go conn.Serve(spdystream.NoOpStreamHandler)
45 stream, _ := conn.CreateStream(http.Header{}, nil, false)
46 stream.Wait()
47 }
48
49 func serveWs(w http.ResponseWriter, r *http.Request) {
50 if r.Method != "GET" {
51 http.Error(w, "Method not allowed", 405)
52 return
53 }
54
55 ws, err := upgrader.Upgrade(w, r, nil)
56 if err != nil {
57 if _, ok := err.(websocket.HandshakeError); !ok {
58 log.Println(err)
59 }
60 return
61 }
62
63 wrap := NewConnection(ws)
64 spdyConn, err := spdystream.NewConnection(wrap, true)
65 if err != nil {
66 log.Fatal(err)
67 return
68 }
69 serverSpdyConn = spdyConn
70 spdyConn.Serve(authStreamHandler)
71 }
72
73 func TestSpdyStreamOverWs(t *testing.T) {
74 server := httptest.NewServer(http.HandlerFunc(serveWs))
75 defer server.Close()
76 defer func() {
77 if serverSpdyConn != nil {
78 serverSpdyConn.Close()
79 }
80 }()
81
82 wsconn, _, err := websocket.DefaultDialer.Dial(strings.Replace(server.URL, "http://", "ws://", 1), http.Header{"Origin": {server.URL}})
83 if err != nil {
84 t.Fatal(err)
85 }
86
87 wrap := NewConnection(wsconn)
88 spdyConn, err := spdystream.NewConnection(wrap, false)
89 if err != nil {
90 defer wsconn.Close()
91 t.Fatal(err)
92 }
93 defer spdyConn.Close()
94 authenticated = true
95 go spdyConn.Serve(spdystream.NoOpStreamHandler)
96
97 stream, streamErr := spdyConn.CreateStream(http.Header{}, nil, false)
98 if streamErr != nil {
99 t.Fatalf("Error creating stream: %s", streamErr)
100 }
101
102 waitErr := stream.Wait()
103 if waitErr != nil {
104 t.Fatalf("Error waiting for stream: %s", waitErr)
105 }
106
107 message := []byte("hello")
108 writeErr := stream.WriteData(message, false)
109 if writeErr != nil {
110 t.Fatalf("Error writing data")
111 }
112
113 buf := make([]byte, 10)
114 n, readErr := stream.Read(buf)
115 if readErr != nil {
116 t.Fatalf("Error reading data from stream: %s", readErr)
117 }
118 if n != 5 {
119 t.Fatalf("Unexpected number of bytes read:\nActual: %d\nExpected: 5", n)
120 }
121 if !bytes.Equal(buf[:n], message) {
122 t.Fatalf("Did not receive expected message:\nActual: %s\nExpectd: %s", buf, message)
123 }
124
125 writeErr = stream.WriteData(message, true)
126 if writeErr != nil {
127 t.Fatalf("Error writing data")
128 }
129
130 smallBuf := make([]byte, 3)
131 n, readErr = stream.Read(smallBuf)
132 if readErr != nil {
133 t.Fatalf("Error reading data from stream: %s", readErr)
134 }
135 if n != 3 {
136 t.Fatalf("Unexpected number of bytes read:\nActual: %d\nExpected: 3", n)
137 }
138 if !bytes.Equal(smallBuf[:n], []byte("hel")) {
139 t.Fatalf("Did not receive expected message:\nActual: %s\nExpectd: %s", smallBuf[:n], message)
140 }
141 n, readErr = stream.Read(smallBuf)
142 if readErr != nil {
143 t.Fatalf("Error reading data from stream: %s", readErr)
144 }
145 if n != 2 {
146 t.Fatalf("Unexpected number of bytes read:\nActual: %d\nExpected: 2", n)
147 }
148 if !bytes.Equal(smallBuf[:n], []byte("lo")) {
149 t.Fatalf("Did not receive expected message:\nActual: %s\nExpected: lo", smallBuf[:n])
150 }
151
152 n, readErr = stream.Read(buf)
153 if readErr != io.EOF {
154 t.Fatalf("Expected EOF reading from finished stream, read %d bytes", n)
155 }
156
157
158 streamCloseErr := stream.Close()
159 if streamCloseErr == nil {
160 t.Fatalf("No error closing finished stream")
161 }
162 if streamCloseErr != spdystream.ErrWriteClosedStream {
163 t.Fatalf("Unexpected error closing stream: %s", streamCloseErr)
164 }
165
166 streamResetErr := stream.Reset()
167 if streamResetErr != nil {
168 t.Fatalf("Error reseting stream: %s", streamResetErr)
169 }
170
171 authenticated = false
172 badStream, badStreamErr := spdyConn.CreateStream(http.Header{}, nil, false)
173 if badStreamErr != nil {
174 t.Fatalf("Error creating stream: %s", badStreamErr)
175 }
176
177 waitErr = badStream.Wait()
178 if waitErr == nil {
179 t.Fatalf("Did not receive error creating stream")
180 }
181 if waitErr != spdystream.ErrReset {
182 t.Fatalf("Unexpected error creating stream: %s", waitErr)
183 }
184
185 spdyCloseErr := spdyConn.Close()
186 if spdyCloseErr != nil {
187 t.Fatalf("Error closing spdy connection: %s", spdyCloseErr)
188 }
189 }
190
191 var authenticated bool
192
193 func authStreamHandler(stream *spdystream.Stream) {
194 if !authenticated {
195 stream.Refuse()
196 return
197 }
198 spdystream.MirrorStreamHandler(stream)
199 }
200
View as plain text