1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
15 func TestHeaderParsing(t *testing.T) {
16 headers := http.Header{
17 "Url": []string{"http://www.google.com/"},
18 "Method": []string{"get"},
19 "Version": []string{"http/1.1"},
21 var headerValueBlockBuf bytes.Buffer
22 writeHeaderValueBlock(&headerValueBlockBuf, headers)
24 const bogusStreamId = 1
25 newHeaders, err := parseHeaderValueBlock(&headerValueBlockBuf, bogusStreamId)
27 t.Fatal("parseHeaderValueBlock:", err)
30 if !reflect.DeepEqual(headers, newHeaders) {
31 t.Fatal("got: ", newHeaders, "\nwant: ", headers)
35 func TestCreateParseSynStreamFrame(t *testing.T) {
36 buffer := new(bytes.Buffer)
38 headerCompressionDisabled: true,
40 headerBuf: new(bytes.Buffer),
43 synStreamFrame := SynStreamFrame{
44 CFHeader: ControlFrameHeader{
46 frameType: TypeSynStream,
49 "Url": []string{"http://www.google.com/"},
50 "Method": []string{"get"},
51 "Version": []string{"http/1.1"},
54 if err := framer.WriteFrame(&synStreamFrame); err != nil {
55 t.Fatal("WriteFrame without compression:", err)
57 frame, err := framer.ReadFrame()
59 t.Fatal("ReadFrame without compression:", err)
61 parsedSynStreamFrame, ok := frame.(*SynStreamFrame)
63 t.Fatal("Parsed incorrect frame type:", frame)
65 if !reflect.DeepEqual(synStreamFrame, *parsedSynStreamFrame) {
66 t.Fatal("got: ", *parsedSynStreamFrame, "\nwant: ", synStreamFrame)
69 // Test again with compression
71 framer, err = NewFramer(buffer, buffer)
73 t.Fatal("Failed to create new framer:", err)
75 if err := framer.WriteFrame(&synStreamFrame); err != nil {
76 t.Fatal("WriteFrame with compression:", err)
78 frame, err = framer.ReadFrame()
80 t.Fatal("ReadFrame with compression:", err)
82 parsedSynStreamFrame, ok = frame.(*SynStreamFrame)
84 t.Fatal("Parsed incorrect frame type:", frame)
86 if !reflect.DeepEqual(synStreamFrame, *parsedSynStreamFrame) {
87 t.Fatal("got: ", *parsedSynStreamFrame, "\nwant: ", synStreamFrame)
91 func TestCreateParseSynReplyFrame(t *testing.T) {
92 buffer := new(bytes.Buffer)
94 headerCompressionDisabled: true,
96 headerBuf: new(bytes.Buffer),
99 synReplyFrame := SynReplyFrame{
100 CFHeader: ControlFrameHeader{
102 frameType: TypeSynReply,
104 Headers: http.Header{
105 "Url": []string{"http://www.google.com/"},
106 "Method": []string{"get"},
107 "Version": []string{"http/1.1"},
110 if err := framer.WriteFrame(&synReplyFrame); err != nil {
111 t.Fatal("WriteFrame without compression:", err)
113 frame, err := framer.ReadFrame()
115 t.Fatal("ReadFrame without compression:", err)
117 parsedSynReplyFrame, ok := frame.(*SynReplyFrame)
119 t.Fatal("Parsed incorrect frame type:", frame)
121 if !reflect.DeepEqual(synReplyFrame, *parsedSynReplyFrame) {
122 t.Fatal("got: ", *parsedSynReplyFrame, "\nwant: ", synReplyFrame)
125 // Test again with compression
127 framer, err = NewFramer(buffer, buffer)
129 t.Fatal("Failed to create new framer:", err)
131 if err := framer.WriteFrame(&synReplyFrame); err != nil {
132 t.Fatal("WriteFrame with compression:", err)
134 frame, err = framer.ReadFrame()
136 t.Fatal("ReadFrame with compression:", err)
138 parsedSynReplyFrame, ok = frame.(*SynReplyFrame)
140 t.Fatal("Parsed incorrect frame type:", frame)
142 if !reflect.DeepEqual(synReplyFrame, *parsedSynReplyFrame) {
143 t.Fatal("got: ", *parsedSynReplyFrame, "\nwant: ", synReplyFrame)
147 func TestCreateParseRstStream(t *testing.T) {
148 buffer := new(bytes.Buffer)
149 framer, err := NewFramer(buffer, buffer)
151 t.Fatal("Failed to create new framer:", err)
153 rstStreamFrame := RstStreamFrame{
154 CFHeader: ControlFrameHeader{
156 frameType: TypeRstStream,
159 Status: InvalidStream,
161 if err := framer.WriteFrame(&rstStreamFrame); err != nil {
162 t.Fatal("WriteFrame:", err)
164 frame, err := framer.ReadFrame()
166 t.Fatal("ReadFrame:", err)
168 parsedRstStreamFrame, ok := frame.(*RstStreamFrame)
170 t.Fatal("Parsed incorrect frame type:", frame)
172 if !reflect.DeepEqual(rstStreamFrame, *parsedRstStreamFrame) {
173 t.Fatal("got: ", *parsedRstStreamFrame, "\nwant: ", rstStreamFrame)
177 func TestCreateParseSettings(t *testing.T) {
178 buffer := new(bytes.Buffer)
179 framer, err := NewFramer(buffer, buffer)
181 t.Fatal("Failed to create new framer:", err)
183 settingsFrame := SettingsFrame{
184 CFHeader: ControlFrameHeader{
186 frameType: TypeSettings,
188 FlagIdValues: []SettingsFlagIdValue{
189 {FlagSettingsPersistValue, SettingsCurrentCwnd, 10},
190 {FlagSettingsPersisted, SettingsUploadBandwidth, 1},
193 if err := framer.WriteFrame(&settingsFrame); err != nil {
194 t.Fatal("WriteFrame:", err)
196 frame, err := framer.ReadFrame()
198 t.Fatal("ReadFrame:", err)
200 parsedSettingsFrame, ok := frame.(*SettingsFrame)
202 t.Fatal("Parsed incorrect frame type:", frame)
204 if !reflect.DeepEqual(settingsFrame, *parsedSettingsFrame) {
205 t.Fatal("got: ", *parsedSettingsFrame, "\nwant: ", settingsFrame)
209 func TestCreateParseNoop(t *testing.T) {
210 buffer := new(bytes.Buffer)
211 framer, err := NewFramer(buffer, buffer)
213 t.Fatal("Failed to create new framer:", err)
215 noopFrame := NoopFrame{
216 CFHeader: ControlFrameHeader{
221 if err := framer.WriteFrame(&noopFrame); err != nil {
222 t.Fatal("WriteFrame:", err)
224 frame, err := framer.ReadFrame()
226 t.Fatal("ReadFrame:", err)
228 parsedNoopFrame, ok := frame.(*NoopFrame)
230 t.Fatal("Parsed incorrect frame type:", frame)
232 if !reflect.DeepEqual(noopFrame, *parsedNoopFrame) {
233 t.Fatal("got: ", *parsedNoopFrame, "\nwant: ", noopFrame)
237 func TestCreateParsePing(t *testing.T) {
238 buffer := new(bytes.Buffer)
239 framer, err := NewFramer(buffer, buffer)
241 t.Fatal("Failed to create new framer:", err)
243 pingFrame := PingFrame{
244 CFHeader: ControlFrameHeader{
250 if err := framer.WriteFrame(&pingFrame); err != nil {
251 t.Fatal("WriteFrame:", err)
253 frame, err := framer.ReadFrame()
255 t.Fatal("ReadFrame:", err)
257 parsedPingFrame, ok := frame.(*PingFrame)
259 t.Fatal("Parsed incorrect frame type:", frame)
261 if !reflect.DeepEqual(pingFrame, *parsedPingFrame) {
262 t.Fatal("got: ", *parsedPingFrame, "\nwant: ", pingFrame)
266 func TestCreateParseGoAway(t *testing.T) {
267 buffer := new(bytes.Buffer)
268 framer, err := NewFramer(buffer, buffer)
270 t.Fatal("Failed to create new framer:", err)
272 goAwayFrame := GoAwayFrame{
273 CFHeader: ControlFrameHeader{
275 frameType: TypeGoAway,
277 LastGoodStreamId: 31337,
279 if err := framer.WriteFrame(&goAwayFrame); err != nil {
280 t.Fatal("WriteFrame:", err)
282 frame, err := framer.ReadFrame()
284 t.Fatal("ReadFrame:", err)
286 parsedGoAwayFrame, ok := frame.(*GoAwayFrame)
288 t.Fatal("Parsed incorrect frame type:", frame)
290 if !reflect.DeepEqual(goAwayFrame, *parsedGoAwayFrame) {
291 t.Fatal("got: ", *parsedGoAwayFrame, "\nwant: ", goAwayFrame)
295 func TestCreateParseHeadersFrame(t *testing.T) {
296 buffer := new(bytes.Buffer)
298 headerCompressionDisabled: true,
300 headerBuf: new(bytes.Buffer),
303 headersFrame := HeadersFrame{
304 CFHeader: ControlFrameHeader{
306 frameType: TypeHeaders,
309 headersFrame.Headers = http.Header{
310 "Url": []string{"http://www.google.com/"},
311 "Method": []string{"get"},
312 "Version": []string{"http/1.1"},
314 if err := framer.WriteFrame(&headersFrame); err != nil {
315 t.Fatal("WriteFrame without compression:", err)
317 frame, err := framer.ReadFrame()
319 t.Fatal("ReadFrame without compression:", err)
321 parsedHeadersFrame, ok := frame.(*HeadersFrame)
323 t.Fatal("Parsed incorrect frame type:", frame)
325 if !reflect.DeepEqual(headersFrame, *parsedHeadersFrame) {
326 t.Fatal("got: ", *parsedHeadersFrame, "\nwant: ", headersFrame)
329 // Test again with compression
331 framer, err = NewFramer(buffer, buffer)
332 if err := framer.WriteFrame(&headersFrame); err != nil {
333 t.Fatal("WriteFrame with compression:", err)
335 frame, err = framer.ReadFrame()
337 t.Fatal("ReadFrame with compression:", err)
339 parsedHeadersFrame, ok = frame.(*HeadersFrame)
341 t.Fatal("Parsed incorrect frame type:", frame)
343 if !reflect.DeepEqual(headersFrame, *parsedHeadersFrame) {
344 t.Fatal("got: ", *parsedHeadersFrame, "\nwant: ", headersFrame)
348 func TestCreateParseDataFrame(t *testing.T) {
349 buffer := new(bytes.Buffer)
350 framer, err := NewFramer(buffer, buffer)
352 t.Fatal("Failed to create new framer:", err)
354 dataFrame := DataFrame{
356 Data: []byte{'h', 'e', 'l', 'l', 'o'},
358 if err := framer.WriteFrame(&dataFrame); err != nil {
359 t.Fatal("WriteFrame:", err)
361 frame, err := framer.ReadFrame()
363 t.Fatal("ReadFrame:", err)
365 parsedDataFrame, ok := frame.(*DataFrame)
367 t.Fatal("Parsed incorrect frame type:", frame)
369 if !reflect.DeepEqual(dataFrame, *parsedDataFrame) {
370 t.Fatal("got: ", *parsedDataFrame, "\nwant: ", dataFrame)
374 func TestCompressionContextAcrossFrames(t *testing.T) {
375 buffer := new(bytes.Buffer)
376 framer, err := NewFramer(buffer, buffer)
378 t.Fatal("Failed to create new framer:", err)
380 headersFrame := HeadersFrame{
381 CFHeader: ControlFrameHeader{
383 frameType: TypeHeaders,
385 Headers: http.Header{
386 "Url": []string{"http://www.google.com/"},
387 "Method": []string{"get"},
388 "Version": []string{"http/1.1"},
391 if err := framer.WriteFrame(&headersFrame); err != nil {
392 t.Fatal("WriteFrame (HEADERS):", err)
394 synStreamFrame := SynStreamFrame{ControlFrameHeader{Version, TypeSynStream, 0, 0}, 0, 0, 0, nil}
395 synStreamFrame.Headers = http.Header{
396 "Url": []string{"http://www.google.com/"},
397 "Method": []string{"get"},
398 "Version": []string{"http/1.1"},
400 if err := framer.WriteFrame(&synStreamFrame); err != nil {
401 t.Fatal("WriteFrame (SYN_STREAM):", err)
403 frame, err := framer.ReadFrame()
405 t.Fatal("ReadFrame (HEADERS):", err, buffer.Bytes())
407 parsedHeadersFrame, ok := frame.(*HeadersFrame)
409 t.Fatalf("expected HeadersFrame; got %T %v", frame, frame)
411 if !reflect.DeepEqual(headersFrame, *parsedHeadersFrame) {
412 t.Fatal("got: ", *parsedHeadersFrame, "\nwant: ", headersFrame)
414 frame, err = framer.ReadFrame()
416 t.Fatal("ReadFrame (SYN_STREAM):", err, buffer.Bytes())
418 parsedSynStreamFrame, ok := frame.(*SynStreamFrame)
420 t.Fatalf("expected SynStreamFrame; got %T %v", frame, frame)
422 if !reflect.DeepEqual(synStreamFrame, *parsedSynStreamFrame) {
423 t.Fatal("got: ", *parsedSynStreamFrame, "\nwant: ", synStreamFrame)
427 func TestMultipleSPDYFrames(t *testing.T) {
428 // Initialize the framers.
429 pr1, pw1 := io.Pipe()
430 pr2, pw2 := io.Pipe()
431 writer, err := NewFramer(pw1, pr2)
433 t.Fatal("Failed to create writer:", err)
435 reader, err := NewFramer(pw2, pr1)
437 t.Fatal("Failed to create reader:", err)
440 // Set up the frames we're actually transferring.
441 headersFrame := HeadersFrame{
442 CFHeader: ControlFrameHeader{
444 frameType: TypeHeaders,
446 Headers: http.Header{
447 "Url": []string{"http://www.google.com/"},
448 "Method": []string{"get"},
449 "Version": []string{"http/1.1"},
452 synStreamFrame := SynStreamFrame{
453 CFHeader: ControlFrameHeader{
455 frameType: TypeSynStream,
457 Headers: http.Header{
458 "Url": []string{"http://www.google.com/"},
459 "Method": []string{"get"},
460 "Version": []string{"http/1.1"},
464 // Start the goroutines to write the frames.
466 if err := writer.WriteFrame(&headersFrame); err != nil {
467 t.Fatal("WriteFrame (HEADERS): ", err)
469 if err := writer.WriteFrame(&synStreamFrame); err != nil {
470 t.Fatal("WriteFrame (SYN_STREAM): ", err)
474 // Read the frames and verify they look as expected.
475 frame, err := reader.ReadFrame()
477 t.Fatal("ReadFrame (HEADERS): ", err)
479 parsedHeadersFrame, ok := frame.(*HeadersFrame)
481 t.Fatal("Parsed incorrect frame type:", frame)
483 if !reflect.DeepEqual(headersFrame, *parsedHeadersFrame) {
484 t.Fatal("got: ", *parsedHeadersFrame, "\nwant: ", headersFrame)
486 frame, err = reader.ReadFrame()
488 t.Fatal("ReadFrame (SYN_STREAM):", err)
490 parsedSynStreamFrame, ok := frame.(*SynStreamFrame)
492 t.Fatal("Parsed incorrect frame type.")
494 if !reflect.DeepEqual(synStreamFrame, *parsedSynStreamFrame) {
495 t.Fatal("got: ", *parsedSynStreamFrame, "\nwant: ", synStreamFrame)