frame_test.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735
  1. // Copyright 2014 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.
  4. package http2
  5. import (
  6. "bytes"
  7. "fmt"
  8. "io"
  9. "reflect"
  10. "strings"
  11. "testing"
  12. "unsafe"
  13. )
  14. func testFramer() (*Framer, *bytes.Buffer) {
  15. buf := new(bytes.Buffer)
  16. return NewFramer(buf, buf), buf
  17. }
  18. func TestFrameSizes(t *testing.T) {
  19. // Catch people rearranging the FrameHeader fields.
  20. if got, want := int(unsafe.Sizeof(FrameHeader{})), 12; got != want {
  21. t.Errorf("FrameHeader size = %d; want %d", got, want)
  22. }
  23. }
  24. func TestFrameTypeString(t *testing.T) {
  25. tests := []struct {
  26. ft FrameType
  27. want string
  28. }{
  29. {FrameData, "DATA"},
  30. {FramePing, "PING"},
  31. {FrameGoAway, "GOAWAY"},
  32. {0xf, "UNKNOWN_FRAME_TYPE_15"},
  33. }
  34. for i, tt := range tests {
  35. got := tt.ft.String()
  36. if got != tt.want {
  37. t.Errorf("%d. String(FrameType %d) = %q; want %q", i, int(tt.ft), got, tt.want)
  38. }
  39. }
  40. }
  41. func TestWriteRST(t *testing.T) {
  42. fr, buf := testFramer()
  43. var streamID uint32 = 1<<24 + 2<<16 + 3<<8 + 4
  44. var errCode uint32 = 7<<24 + 6<<16 + 5<<8 + 4
  45. fr.WriteRSTStream(streamID, ErrCode(errCode))
  46. const wantEnc = "\x00\x00\x04\x03\x00\x01\x02\x03\x04\x07\x06\x05\x04"
  47. if buf.String() != wantEnc {
  48. t.Errorf("encoded as %q; want %q", buf.Bytes(), wantEnc)
  49. }
  50. f, err := fr.ReadFrame()
  51. if err != nil {
  52. t.Fatal(err)
  53. }
  54. want := &RSTStreamFrame{
  55. FrameHeader: FrameHeader{
  56. valid: true,
  57. Type: 0x3,
  58. Flags: 0x0,
  59. Length: 0x4,
  60. StreamID: 0x1020304,
  61. },
  62. ErrCode: 0x7060504,
  63. }
  64. if !reflect.DeepEqual(f, want) {
  65. t.Errorf("parsed back %#v; want %#v", f, want)
  66. }
  67. }
  68. func TestWriteData(t *testing.T) {
  69. fr, buf := testFramer()
  70. var streamID uint32 = 1<<24 + 2<<16 + 3<<8 + 4
  71. data := []byte("ABC")
  72. fr.WriteData(streamID, true, data)
  73. const wantEnc = "\x00\x00\x03\x00\x01\x01\x02\x03\x04ABC"
  74. if buf.String() != wantEnc {
  75. t.Errorf("encoded as %q; want %q", buf.Bytes(), wantEnc)
  76. }
  77. f, err := fr.ReadFrame()
  78. if err != nil {
  79. t.Fatal(err)
  80. }
  81. df, ok := f.(*DataFrame)
  82. if !ok {
  83. t.Fatalf("got %T; want *DataFrame", f)
  84. }
  85. if !bytes.Equal(df.Data(), data) {
  86. t.Errorf("got %q; want %q", df.Data(), data)
  87. }
  88. if f.Header().Flags&1 == 0 {
  89. t.Errorf("didn't see END_STREAM flag")
  90. }
  91. }
  92. func TestWriteHeaders(t *testing.T) {
  93. tests := []struct {
  94. name string
  95. p HeadersFrameParam
  96. wantEnc string
  97. wantFrame *HeadersFrame
  98. }{
  99. {
  100. "basic",
  101. HeadersFrameParam{
  102. StreamID: 42,
  103. BlockFragment: []byte("abc"),
  104. Priority: PriorityParam{},
  105. },
  106. "\x00\x00\x03\x01\x00\x00\x00\x00*abc",
  107. &HeadersFrame{
  108. FrameHeader: FrameHeader{
  109. valid: true,
  110. StreamID: 42,
  111. Type: FrameHeaders,
  112. Length: uint32(len("abc")),
  113. },
  114. Priority: PriorityParam{},
  115. headerFragBuf: []byte("abc"),
  116. },
  117. },
  118. {
  119. "basic + end flags",
  120. HeadersFrameParam{
  121. StreamID: 42,
  122. BlockFragment: []byte("abc"),
  123. EndStream: true,
  124. EndHeaders: true,
  125. Priority: PriorityParam{},
  126. },
  127. "\x00\x00\x03\x01\x05\x00\x00\x00*abc",
  128. &HeadersFrame{
  129. FrameHeader: FrameHeader{
  130. valid: true,
  131. StreamID: 42,
  132. Type: FrameHeaders,
  133. Flags: FlagHeadersEndStream | FlagHeadersEndHeaders,
  134. Length: uint32(len("abc")),
  135. },
  136. Priority: PriorityParam{},
  137. headerFragBuf: []byte("abc"),
  138. },
  139. },
  140. {
  141. "with padding",
  142. HeadersFrameParam{
  143. StreamID: 42,
  144. BlockFragment: []byte("abc"),
  145. EndStream: true,
  146. EndHeaders: true,
  147. PadLength: 5,
  148. Priority: PriorityParam{},
  149. },
  150. "\x00\x00\t\x01\r\x00\x00\x00*\x05abc\x00\x00\x00\x00\x00",
  151. &HeadersFrame{
  152. FrameHeader: FrameHeader{
  153. valid: true,
  154. StreamID: 42,
  155. Type: FrameHeaders,
  156. Flags: FlagHeadersEndStream | FlagHeadersEndHeaders | FlagHeadersPadded,
  157. Length: uint32(1 + len("abc") + 5), // pad length + contents + padding
  158. },
  159. Priority: PriorityParam{},
  160. headerFragBuf: []byte("abc"),
  161. },
  162. },
  163. {
  164. "with priority",
  165. HeadersFrameParam{
  166. StreamID: 42,
  167. BlockFragment: []byte("abc"),
  168. EndStream: true,
  169. EndHeaders: true,
  170. PadLength: 2,
  171. Priority: PriorityParam{
  172. StreamDep: 15,
  173. Exclusive: true,
  174. Weight: 127,
  175. },
  176. },
  177. "\x00\x00\v\x01-\x00\x00\x00*\x02\x80\x00\x00\x0f\u007fabc\x00\x00",
  178. &HeadersFrame{
  179. FrameHeader: FrameHeader{
  180. valid: true,
  181. StreamID: 42,
  182. Type: FrameHeaders,
  183. Flags: FlagHeadersEndStream | FlagHeadersEndHeaders | FlagHeadersPadded | FlagHeadersPriority,
  184. Length: uint32(1 + 5 + len("abc") + 2), // pad length + priority + contents + padding
  185. },
  186. Priority: PriorityParam{
  187. StreamDep: 15,
  188. Exclusive: true,
  189. Weight: 127,
  190. },
  191. headerFragBuf: []byte("abc"),
  192. },
  193. },
  194. }
  195. for _, tt := range tests {
  196. fr, buf := testFramer()
  197. if err := fr.WriteHeaders(tt.p); err != nil {
  198. t.Errorf("test %q: %v", tt.name, err)
  199. continue
  200. }
  201. if buf.String() != tt.wantEnc {
  202. t.Errorf("test %q: encoded %q; want %q", tt.name, buf.Bytes(), tt.wantEnc)
  203. }
  204. f, err := fr.ReadFrame()
  205. if err != nil {
  206. t.Errorf("test %q: failed to read the frame back: %v", tt.name, err)
  207. continue
  208. }
  209. if !reflect.DeepEqual(f, tt.wantFrame) {
  210. t.Errorf("test %q: mismatch.\n got: %#v\nwant: %#v\n", tt.name, f, tt.wantFrame)
  211. }
  212. }
  213. }
  214. func TestWriteContinuation(t *testing.T) {
  215. const streamID = 42
  216. tests := []struct {
  217. name string
  218. end bool
  219. frag []byte
  220. wantFrame *ContinuationFrame
  221. }{
  222. {
  223. "not end",
  224. false,
  225. []byte("abc"),
  226. &ContinuationFrame{
  227. FrameHeader: FrameHeader{
  228. valid: true,
  229. StreamID: streamID,
  230. Type: FrameContinuation,
  231. Length: uint32(len("abc")),
  232. },
  233. headerFragBuf: []byte("abc"),
  234. },
  235. },
  236. {
  237. "end",
  238. true,
  239. []byte("def"),
  240. &ContinuationFrame{
  241. FrameHeader: FrameHeader{
  242. valid: true,
  243. StreamID: streamID,
  244. Type: FrameContinuation,
  245. Flags: FlagContinuationEndHeaders,
  246. Length: uint32(len("def")),
  247. },
  248. headerFragBuf: []byte("def"),
  249. },
  250. },
  251. }
  252. for _, tt := range tests {
  253. fr, _ := testFramer()
  254. if err := fr.WriteContinuation(streamID, tt.end, tt.frag); err != nil {
  255. t.Errorf("test %q: %v", tt.name, err)
  256. continue
  257. }
  258. fr.AllowIllegalReads = true
  259. f, err := fr.ReadFrame()
  260. if err != nil {
  261. t.Errorf("test %q: failed to read the frame back: %v", tt.name, err)
  262. continue
  263. }
  264. if !reflect.DeepEqual(f, tt.wantFrame) {
  265. t.Errorf("test %q: mismatch.\n got: %#v\nwant: %#v\n", tt.name, f, tt.wantFrame)
  266. }
  267. }
  268. }
  269. func TestWritePriority(t *testing.T) {
  270. const streamID = 42
  271. tests := []struct {
  272. name string
  273. priority PriorityParam
  274. wantFrame *PriorityFrame
  275. }{
  276. {
  277. "not exclusive",
  278. PriorityParam{
  279. StreamDep: 2,
  280. Exclusive: false,
  281. Weight: 127,
  282. },
  283. &PriorityFrame{
  284. FrameHeader{
  285. valid: true,
  286. StreamID: streamID,
  287. Type: FramePriority,
  288. Length: 5,
  289. },
  290. PriorityParam{
  291. StreamDep: 2,
  292. Exclusive: false,
  293. Weight: 127,
  294. },
  295. },
  296. },
  297. {
  298. "exclusive",
  299. PriorityParam{
  300. StreamDep: 3,
  301. Exclusive: true,
  302. Weight: 77,
  303. },
  304. &PriorityFrame{
  305. FrameHeader{
  306. valid: true,
  307. StreamID: streamID,
  308. Type: FramePriority,
  309. Length: 5,
  310. },
  311. PriorityParam{
  312. StreamDep: 3,
  313. Exclusive: true,
  314. Weight: 77,
  315. },
  316. },
  317. },
  318. }
  319. for _, tt := range tests {
  320. fr, _ := testFramer()
  321. if err := fr.WritePriority(streamID, tt.priority); err != nil {
  322. t.Errorf("test %q: %v", tt.name, err)
  323. continue
  324. }
  325. f, err := fr.ReadFrame()
  326. if err != nil {
  327. t.Errorf("test %q: failed to read the frame back: %v", tt.name, err)
  328. continue
  329. }
  330. if !reflect.DeepEqual(f, tt.wantFrame) {
  331. t.Errorf("test %q: mismatch.\n got: %#v\nwant: %#v\n", tt.name, f, tt.wantFrame)
  332. }
  333. }
  334. }
  335. func TestWriteSettings(t *testing.T) {
  336. fr, buf := testFramer()
  337. settings := []Setting{{1, 2}, {3, 4}}
  338. fr.WriteSettings(settings...)
  339. const wantEnc = "\x00\x00\f\x04\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x03\x00\x00\x00\x04"
  340. if buf.String() != wantEnc {
  341. t.Errorf("encoded as %q; want %q", buf.Bytes(), wantEnc)
  342. }
  343. f, err := fr.ReadFrame()
  344. if err != nil {
  345. t.Fatal(err)
  346. }
  347. sf, ok := f.(*SettingsFrame)
  348. if !ok {
  349. t.Fatalf("Got a %T; want a SettingsFrame", f)
  350. }
  351. var got []Setting
  352. sf.ForeachSetting(func(s Setting) error {
  353. got = append(got, s)
  354. valBack, ok := sf.Value(s.ID)
  355. if !ok || valBack != s.Val {
  356. t.Errorf("Value(%d) = %v, %v; want %v, true", s.ID, valBack, ok, s.Val)
  357. }
  358. return nil
  359. })
  360. if !reflect.DeepEqual(settings, got) {
  361. t.Errorf("Read settings %+v != written settings %+v", got, settings)
  362. }
  363. }
  364. func TestWriteSettingsAck(t *testing.T) {
  365. fr, buf := testFramer()
  366. fr.WriteSettingsAck()
  367. const wantEnc = "\x00\x00\x00\x04\x01\x00\x00\x00\x00"
  368. if buf.String() != wantEnc {
  369. t.Errorf("encoded as %q; want %q", buf.Bytes(), wantEnc)
  370. }
  371. }
  372. func TestWriteWindowUpdate(t *testing.T) {
  373. fr, buf := testFramer()
  374. const streamID = 1<<24 + 2<<16 + 3<<8 + 4
  375. const incr = 7<<24 + 6<<16 + 5<<8 + 4
  376. if err := fr.WriteWindowUpdate(streamID, incr); err != nil {
  377. t.Fatal(err)
  378. }
  379. const wantEnc = "\x00\x00\x04\x08\x00\x01\x02\x03\x04\x07\x06\x05\x04"
  380. if buf.String() != wantEnc {
  381. t.Errorf("encoded as %q; want %q", buf.Bytes(), wantEnc)
  382. }
  383. f, err := fr.ReadFrame()
  384. if err != nil {
  385. t.Fatal(err)
  386. }
  387. want := &WindowUpdateFrame{
  388. FrameHeader: FrameHeader{
  389. valid: true,
  390. Type: 0x8,
  391. Flags: 0x0,
  392. Length: 0x4,
  393. StreamID: 0x1020304,
  394. },
  395. Increment: 0x7060504,
  396. }
  397. if !reflect.DeepEqual(f, want) {
  398. t.Errorf("parsed back %#v; want %#v", f, want)
  399. }
  400. }
  401. func TestWritePing(t *testing.T) { testWritePing(t, false) }
  402. func TestWritePingAck(t *testing.T) { testWritePing(t, true) }
  403. func testWritePing(t *testing.T, ack bool) {
  404. fr, buf := testFramer()
  405. if err := fr.WritePing(ack, [8]byte{1, 2, 3, 4, 5, 6, 7, 8}); err != nil {
  406. t.Fatal(err)
  407. }
  408. var wantFlags Flags
  409. if ack {
  410. wantFlags = FlagPingAck
  411. }
  412. var wantEnc = "\x00\x00\x08\x06" + string(wantFlags) + "\x00\x00\x00\x00" + "\x01\x02\x03\x04\x05\x06\x07\x08"
  413. if buf.String() != wantEnc {
  414. t.Errorf("encoded as %q; want %q", buf.Bytes(), wantEnc)
  415. }
  416. f, err := fr.ReadFrame()
  417. if err != nil {
  418. t.Fatal(err)
  419. }
  420. want := &PingFrame{
  421. FrameHeader: FrameHeader{
  422. valid: true,
  423. Type: 0x6,
  424. Flags: wantFlags,
  425. Length: 0x8,
  426. StreamID: 0,
  427. },
  428. Data: [8]byte{1, 2, 3, 4, 5, 6, 7, 8},
  429. }
  430. if !reflect.DeepEqual(f, want) {
  431. t.Errorf("parsed back %#v; want %#v", f, want)
  432. }
  433. }
  434. func TestReadFrameHeader(t *testing.T) {
  435. tests := []struct {
  436. in string
  437. want FrameHeader
  438. }{
  439. {in: "\x00\x00\x00" + "\x00" + "\x00" + "\x00\x00\x00\x00", want: FrameHeader{}},
  440. {in: "\x01\x02\x03" + "\x04" + "\x05" + "\x06\x07\x08\x09", want: FrameHeader{
  441. Length: 66051, Type: 4, Flags: 5, StreamID: 101124105,
  442. }},
  443. // Ignore high bit:
  444. {in: "\xff\xff\xff" + "\xff" + "\xff" + "\xff\xff\xff\xff", want: FrameHeader{
  445. Length: 16777215, Type: 255, Flags: 255, StreamID: 2147483647}},
  446. {in: "\xff\xff\xff" + "\xff" + "\xff" + "\x7f\xff\xff\xff", want: FrameHeader{
  447. Length: 16777215, Type: 255, Flags: 255, StreamID: 2147483647}},
  448. }
  449. for i, tt := range tests {
  450. got, err := readFrameHeader(make([]byte, 9), strings.NewReader(tt.in))
  451. if err != nil {
  452. t.Errorf("%d. readFrameHeader(%q) = %v", i, tt.in, err)
  453. continue
  454. }
  455. tt.want.valid = true
  456. if got != tt.want {
  457. t.Errorf("%d. readFrameHeader(%q) = %+v; want %+v", i, tt.in, got, tt.want)
  458. }
  459. }
  460. }
  461. func TestReadWriteFrameHeader(t *testing.T) {
  462. tests := []struct {
  463. len uint32
  464. typ FrameType
  465. flags Flags
  466. streamID uint32
  467. }{
  468. {len: 0, typ: 255, flags: 1, streamID: 0},
  469. {len: 0, typ: 255, flags: 1, streamID: 1},
  470. {len: 0, typ: 255, flags: 1, streamID: 255},
  471. {len: 0, typ: 255, flags: 1, streamID: 256},
  472. {len: 0, typ: 255, flags: 1, streamID: 65535},
  473. {len: 0, typ: 255, flags: 1, streamID: 65536},
  474. {len: 0, typ: 1, flags: 255, streamID: 1},
  475. {len: 255, typ: 1, flags: 255, streamID: 1},
  476. {len: 256, typ: 1, flags: 255, streamID: 1},
  477. {len: 65535, typ: 1, flags: 255, streamID: 1},
  478. {len: 65536, typ: 1, flags: 255, streamID: 1},
  479. {len: 16777215, typ: 1, flags: 255, streamID: 1},
  480. }
  481. for _, tt := range tests {
  482. fr, buf := testFramer()
  483. fr.startWrite(tt.typ, tt.flags, tt.streamID)
  484. fr.writeBytes(make([]byte, tt.len))
  485. fr.endWrite()
  486. fh, err := ReadFrameHeader(buf)
  487. if err != nil {
  488. t.Errorf("ReadFrameHeader(%+v) = %v", tt, err)
  489. continue
  490. }
  491. if fh.Type != tt.typ || fh.Flags != tt.flags || fh.Length != tt.len || fh.StreamID != tt.streamID {
  492. t.Errorf("ReadFrameHeader(%+v) = %+v; mismatch", tt, fh)
  493. }
  494. }
  495. }
  496. func TestWriteTooLargeFrame(t *testing.T) {
  497. fr, _ := testFramer()
  498. fr.startWrite(0, 1, 1)
  499. fr.writeBytes(make([]byte, 1<<24))
  500. err := fr.endWrite()
  501. if err != ErrFrameTooLarge {
  502. t.Errorf("endWrite = %v; want errFrameTooLarge", err)
  503. }
  504. }
  505. func TestWriteGoAway(t *testing.T) {
  506. const debug = "foo"
  507. fr, buf := testFramer()
  508. if err := fr.WriteGoAway(0x01020304, 0x05060708, []byte(debug)); err != nil {
  509. t.Fatal(err)
  510. }
  511. const wantEnc = "\x00\x00\v\a\x00\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08" + debug
  512. if buf.String() != wantEnc {
  513. t.Errorf("encoded as %q; want %q", buf.Bytes(), wantEnc)
  514. }
  515. f, err := fr.ReadFrame()
  516. if err != nil {
  517. t.Fatal(err)
  518. }
  519. want := &GoAwayFrame{
  520. FrameHeader: FrameHeader{
  521. valid: true,
  522. Type: 0x7,
  523. Flags: 0,
  524. Length: uint32(4 + 4 + len(debug)),
  525. StreamID: 0,
  526. },
  527. LastStreamID: 0x01020304,
  528. ErrCode: 0x05060708,
  529. debugData: []byte(debug),
  530. }
  531. if !reflect.DeepEqual(f, want) {
  532. t.Fatalf("parsed back:\n%#v\nwant:\n%#v", f, want)
  533. }
  534. if got := string(f.(*GoAwayFrame).DebugData()); got != debug {
  535. t.Errorf("debug data = %q; want %q", got, debug)
  536. }
  537. }
  538. func TestWritePushPromise(t *testing.T) {
  539. pp := PushPromiseParam{
  540. StreamID: 42,
  541. PromiseID: 42,
  542. BlockFragment: []byte("abc"),
  543. }
  544. fr, buf := testFramer()
  545. if err := fr.WritePushPromise(pp); err != nil {
  546. t.Fatal(err)
  547. }
  548. const wantEnc = "\x00\x00\x07\x05\x00\x00\x00\x00*\x00\x00\x00*abc"
  549. if buf.String() != wantEnc {
  550. t.Errorf("encoded as %q; want %q", buf.Bytes(), wantEnc)
  551. }
  552. f, err := fr.ReadFrame()
  553. if err != nil {
  554. t.Fatal(err)
  555. }
  556. _, ok := f.(*PushPromiseFrame)
  557. if !ok {
  558. t.Fatalf("got %T; want *PushPromiseFrame", f)
  559. }
  560. want := &PushPromiseFrame{
  561. FrameHeader: FrameHeader{
  562. valid: true,
  563. Type: 0x5,
  564. Flags: 0x0,
  565. Length: 0x7,
  566. StreamID: 42,
  567. },
  568. PromiseID: 42,
  569. headerFragBuf: []byte("abc"),
  570. }
  571. if !reflect.DeepEqual(f, want) {
  572. t.Fatalf("parsed back:\n%#v\nwant:\n%#v", f, want)
  573. }
  574. }
  575. // test checkFrameOrder and that HEADERS and CONTINUATION frames can't be intermingled.
  576. func TestReadFrameOrder(t *testing.T) {
  577. head := func(f *Framer, id uint32, end bool) {
  578. f.WriteHeaders(HeadersFrameParam{
  579. StreamID: id,
  580. BlockFragment: []byte("foo"), // unused, but non-empty
  581. EndHeaders: end,
  582. })
  583. }
  584. cont := func(f *Framer, id uint32, end bool) {
  585. f.WriteContinuation(id, end, []byte("foo"))
  586. }
  587. tests := [...]struct {
  588. name string
  589. w func(*Framer)
  590. atLeast int
  591. wantErr string
  592. }{
  593. 0: {
  594. w: func(f *Framer) {
  595. head(f, 1, true)
  596. },
  597. },
  598. 1: {
  599. w: func(f *Framer) {
  600. head(f, 1, true)
  601. head(f, 2, true)
  602. },
  603. },
  604. 2: {
  605. wantErr: "got HEADERS for stream 2; expected CONTINUATION following HEADERS for stream 1",
  606. w: func(f *Framer) {
  607. head(f, 1, false)
  608. head(f, 2, true)
  609. },
  610. },
  611. 3: {
  612. wantErr: "got DATA for stream 1; expected CONTINUATION following HEADERS for stream 1",
  613. w: func(f *Framer) {
  614. head(f, 1, false)
  615. },
  616. },
  617. 4: {
  618. w: func(f *Framer) {
  619. head(f, 1, false)
  620. cont(f, 1, true)
  621. head(f, 2, true)
  622. },
  623. },
  624. 5: {
  625. wantErr: "got CONTINUATION for stream 2; expected stream 1",
  626. w: func(f *Framer) {
  627. head(f, 1, false)
  628. cont(f, 2, true)
  629. head(f, 2, true)
  630. },
  631. },
  632. 6: {
  633. wantErr: "unexpected CONTINUATION for stream 1",
  634. w: func(f *Framer) {
  635. cont(f, 1, true)
  636. },
  637. },
  638. 7: {
  639. wantErr: "unexpected CONTINUATION for stream 1",
  640. w: func(f *Framer) {
  641. cont(f, 1, false)
  642. },
  643. },
  644. 8: {
  645. wantErr: "HEADERS frame with stream ID 0",
  646. w: func(f *Framer) {
  647. head(f, 0, true)
  648. },
  649. },
  650. 9: {
  651. wantErr: "CONTINUATION frame with stream ID 0",
  652. w: func(f *Framer) {
  653. cont(f, 0, true)
  654. },
  655. },
  656. 10: {
  657. wantErr: "unexpected CONTINUATION for stream 1",
  658. atLeast: 5,
  659. w: func(f *Framer) {
  660. head(f, 1, false)
  661. cont(f, 1, false)
  662. cont(f, 1, false)
  663. cont(f, 1, false)
  664. cont(f, 1, true)
  665. cont(f, 1, false)
  666. },
  667. },
  668. }
  669. for i, tt := range tests {
  670. buf := new(bytes.Buffer)
  671. f := NewFramer(buf, buf)
  672. f.AllowIllegalWrites = true
  673. tt.w(f)
  674. f.WriteData(1, true, nil) // to test transition away from last step
  675. var err error
  676. n := 0
  677. var log bytes.Buffer
  678. for {
  679. var got Frame
  680. got, err = f.ReadFrame()
  681. fmt.Fprintf(&log, " read %v, %v\n", got, err)
  682. if err != nil {
  683. break
  684. }
  685. n++
  686. }
  687. if err == io.EOF {
  688. err = nil
  689. }
  690. ok := tt.wantErr == ""
  691. if ok && err != nil {
  692. t.Errorf("%d. after %d good frames, ReadFrame = %v; want success\n%s", i, n, err, log.Bytes())
  693. continue
  694. }
  695. if !ok && err != ConnectionError(ErrCodeProtocol) {
  696. t.Errorf("%d. after %d good frames, ReadFrame = %v; want ConnectionError(ErrCodeProtocol)\n%s", i, n, err, log.Bytes())
  697. continue
  698. }
  699. if f.errReason != tt.wantErr {
  700. t.Errorf("%d. framer eror = %q; want %q\n%s", i, f.errReason, tt.wantErr, log.Bytes())
  701. }
  702. if n < tt.atLeast {
  703. t.Errorf("%d. framer only read %d frames; want at least %d\n%s", i, n, tt.atLeast, log.Bytes())
  704. }
  705. }
  706. }