frame_test.go 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975
  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. "golang.org/x/net/http2/hpack"
  14. )
  15. func testFramer() (*Framer, *bytes.Buffer) {
  16. buf := new(bytes.Buffer)
  17. return NewFramer(buf, buf), buf
  18. }
  19. func TestFrameSizes(t *testing.T) {
  20. // Catch people rearranging the FrameHeader fields.
  21. if got, want := int(unsafe.Sizeof(FrameHeader{})), 12; got != want {
  22. t.Errorf("FrameHeader size = %d; want %d", got, want)
  23. }
  24. }
  25. func TestFrameTypeString(t *testing.T) {
  26. tests := []struct {
  27. ft FrameType
  28. want string
  29. }{
  30. {FrameData, "DATA"},
  31. {FramePing, "PING"},
  32. {FrameGoAway, "GOAWAY"},
  33. {0xf, "UNKNOWN_FRAME_TYPE_15"},
  34. }
  35. for i, tt := range tests {
  36. got := tt.ft.String()
  37. if got != tt.want {
  38. t.Errorf("%d. String(FrameType %d) = %q; want %q", i, int(tt.ft), got, tt.want)
  39. }
  40. }
  41. }
  42. func TestWriteRST(t *testing.T) {
  43. fr, buf := testFramer()
  44. var streamID uint32 = 1<<24 + 2<<16 + 3<<8 + 4
  45. var errCode uint32 = 7<<24 + 6<<16 + 5<<8 + 4
  46. fr.WriteRSTStream(streamID, ErrCode(errCode))
  47. const wantEnc = "\x00\x00\x04\x03\x00\x01\x02\x03\x04\x07\x06\x05\x04"
  48. if buf.String() != wantEnc {
  49. t.Errorf("encoded as %q; want %q", buf.Bytes(), wantEnc)
  50. }
  51. f, err := fr.ReadFrame()
  52. if err != nil {
  53. t.Fatal(err)
  54. }
  55. want := &RSTStreamFrame{
  56. FrameHeader: FrameHeader{
  57. valid: true,
  58. Type: 0x3,
  59. Flags: 0x0,
  60. Length: 0x4,
  61. StreamID: 0x1020304,
  62. },
  63. ErrCode: 0x7060504,
  64. }
  65. if !reflect.DeepEqual(f, want) {
  66. t.Errorf("parsed back %#v; want %#v", f, want)
  67. }
  68. }
  69. func TestWriteData(t *testing.T) {
  70. fr, buf := testFramer()
  71. var streamID uint32 = 1<<24 + 2<<16 + 3<<8 + 4
  72. data := []byte("ABC")
  73. fr.WriteData(streamID, true, data)
  74. const wantEnc = "\x00\x00\x03\x00\x01\x01\x02\x03\x04ABC"
  75. if buf.String() != wantEnc {
  76. t.Errorf("encoded as %q; want %q", buf.Bytes(), wantEnc)
  77. }
  78. f, err := fr.ReadFrame()
  79. if err != nil {
  80. t.Fatal(err)
  81. }
  82. df, ok := f.(*DataFrame)
  83. if !ok {
  84. t.Fatalf("got %T; want *DataFrame", f)
  85. }
  86. if !bytes.Equal(df.Data(), data) {
  87. t.Errorf("got %q; want %q", df.Data(), data)
  88. }
  89. if f.Header().Flags&1 == 0 {
  90. t.Errorf("didn't see END_STREAM flag")
  91. }
  92. }
  93. func TestWriteHeaders(t *testing.T) {
  94. tests := []struct {
  95. name string
  96. p HeadersFrameParam
  97. wantEnc string
  98. wantFrame *HeadersFrame
  99. }{
  100. {
  101. "basic",
  102. HeadersFrameParam{
  103. StreamID: 42,
  104. BlockFragment: []byte("abc"),
  105. Priority: PriorityParam{},
  106. },
  107. "\x00\x00\x03\x01\x00\x00\x00\x00*abc",
  108. &HeadersFrame{
  109. FrameHeader: FrameHeader{
  110. valid: true,
  111. StreamID: 42,
  112. Type: FrameHeaders,
  113. Length: uint32(len("abc")),
  114. },
  115. Priority: PriorityParam{},
  116. headerFragBuf: []byte("abc"),
  117. },
  118. },
  119. {
  120. "basic + end flags",
  121. HeadersFrameParam{
  122. StreamID: 42,
  123. BlockFragment: []byte("abc"),
  124. EndStream: true,
  125. EndHeaders: true,
  126. Priority: PriorityParam{},
  127. },
  128. "\x00\x00\x03\x01\x05\x00\x00\x00*abc",
  129. &HeadersFrame{
  130. FrameHeader: FrameHeader{
  131. valid: true,
  132. StreamID: 42,
  133. Type: FrameHeaders,
  134. Flags: FlagHeadersEndStream | FlagHeadersEndHeaders,
  135. Length: uint32(len("abc")),
  136. },
  137. Priority: PriorityParam{},
  138. headerFragBuf: []byte("abc"),
  139. },
  140. },
  141. {
  142. "with padding",
  143. HeadersFrameParam{
  144. StreamID: 42,
  145. BlockFragment: []byte("abc"),
  146. EndStream: true,
  147. EndHeaders: true,
  148. PadLength: 5,
  149. Priority: PriorityParam{},
  150. },
  151. "\x00\x00\t\x01\r\x00\x00\x00*\x05abc\x00\x00\x00\x00\x00",
  152. &HeadersFrame{
  153. FrameHeader: FrameHeader{
  154. valid: true,
  155. StreamID: 42,
  156. Type: FrameHeaders,
  157. Flags: FlagHeadersEndStream | FlagHeadersEndHeaders | FlagHeadersPadded,
  158. Length: uint32(1 + len("abc") + 5), // pad length + contents + padding
  159. },
  160. Priority: PriorityParam{},
  161. headerFragBuf: []byte("abc"),
  162. },
  163. },
  164. {
  165. "with priority",
  166. HeadersFrameParam{
  167. StreamID: 42,
  168. BlockFragment: []byte("abc"),
  169. EndStream: true,
  170. EndHeaders: true,
  171. PadLength: 2,
  172. Priority: PriorityParam{
  173. StreamDep: 15,
  174. Exclusive: true,
  175. Weight: 127,
  176. },
  177. },
  178. "\x00\x00\v\x01-\x00\x00\x00*\x02\x80\x00\x00\x0f\u007fabc\x00\x00",
  179. &HeadersFrame{
  180. FrameHeader: FrameHeader{
  181. valid: true,
  182. StreamID: 42,
  183. Type: FrameHeaders,
  184. Flags: FlagHeadersEndStream | FlagHeadersEndHeaders | FlagHeadersPadded | FlagHeadersPriority,
  185. Length: uint32(1 + 5 + len("abc") + 2), // pad length + priority + contents + padding
  186. },
  187. Priority: PriorityParam{
  188. StreamDep: 15,
  189. Exclusive: true,
  190. Weight: 127,
  191. },
  192. headerFragBuf: []byte("abc"),
  193. },
  194. },
  195. }
  196. for _, tt := range tests {
  197. fr, buf := testFramer()
  198. if err := fr.WriteHeaders(tt.p); err != nil {
  199. t.Errorf("test %q: %v", tt.name, err)
  200. continue
  201. }
  202. if buf.String() != tt.wantEnc {
  203. t.Errorf("test %q: encoded %q; want %q", tt.name, buf.Bytes(), tt.wantEnc)
  204. }
  205. f, err := fr.ReadFrame()
  206. if err != nil {
  207. t.Errorf("test %q: failed to read the frame back: %v", tt.name, err)
  208. continue
  209. }
  210. if !reflect.DeepEqual(f, tt.wantFrame) {
  211. t.Errorf("test %q: mismatch.\n got: %#v\nwant: %#v\n", tt.name, f, tt.wantFrame)
  212. }
  213. }
  214. }
  215. func TestWriteContinuation(t *testing.T) {
  216. const streamID = 42
  217. tests := []struct {
  218. name string
  219. end bool
  220. frag []byte
  221. wantFrame *ContinuationFrame
  222. }{
  223. {
  224. "not end",
  225. false,
  226. []byte("abc"),
  227. &ContinuationFrame{
  228. FrameHeader: FrameHeader{
  229. valid: true,
  230. StreamID: streamID,
  231. Type: FrameContinuation,
  232. Length: uint32(len("abc")),
  233. },
  234. headerFragBuf: []byte("abc"),
  235. },
  236. },
  237. {
  238. "end",
  239. true,
  240. []byte("def"),
  241. &ContinuationFrame{
  242. FrameHeader: FrameHeader{
  243. valid: true,
  244. StreamID: streamID,
  245. Type: FrameContinuation,
  246. Flags: FlagContinuationEndHeaders,
  247. Length: uint32(len("def")),
  248. },
  249. headerFragBuf: []byte("def"),
  250. },
  251. },
  252. }
  253. for _, tt := range tests {
  254. fr, _ := testFramer()
  255. if err := fr.WriteContinuation(streamID, tt.end, tt.frag); err != nil {
  256. t.Errorf("test %q: %v", tt.name, err)
  257. continue
  258. }
  259. fr.AllowIllegalReads = true
  260. f, err := fr.ReadFrame()
  261. if err != nil {
  262. t.Errorf("test %q: failed to read the frame back: %v", tt.name, err)
  263. continue
  264. }
  265. if !reflect.DeepEqual(f, tt.wantFrame) {
  266. t.Errorf("test %q: mismatch.\n got: %#v\nwant: %#v\n", tt.name, f, tt.wantFrame)
  267. }
  268. }
  269. }
  270. func TestWritePriority(t *testing.T) {
  271. const streamID = 42
  272. tests := []struct {
  273. name string
  274. priority PriorityParam
  275. wantFrame *PriorityFrame
  276. }{
  277. {
  278. "not exclusive",
  279. PriorityParam{
  280. StreamDep: 2,
  281. Exclusive: false,
  282. Weight: 127,
  283. },
  284. &PriorityFrame{
  285. FrameHeader{
  286. valid: true,
  287. StreamID: streamID,
  288. Type: FramePriority,
  289. Length: 5,
  290. },
  291. PriorityParam{
  292. StreamDep: 2,
  293. Exclusive: false,
  294. Weight: 127,
  295. },
  296. },
  297. },
  298. {
  299. "exclusive",
  300. PriorityParam{
  301. StreamDep: 3,
  302. Exclusive: true,
  303. Weight: 77,
  304. },
  305. &PriorityFrame{
  306. FrameHeader{
  307. valid: true,
  308. StreamID: streamID,
  309. Type: FramePriority,
  310. Length: 5,
  311. },
  312. PriorityParam{
  313. StreamDep: 3,
  314. Exclusive: true,
  315. Weight: 77,
  316. },
  317. },
  318. },
  319. }
  320. for _, tt := range tests {
  321. fr, _ := testFramer()
  322. if err := fr.WritePriority(streamID, tt.priority); err != nil {
  323. t.Errorf("test %q: %v", tt.name, err)
  324. continue
  325. }
  326. f, err := fr.ReadFrame()
  327. if err != nil {
  328. t.Errorf("test %q: failed to read the frame back: %v", tt.name, err)
  329. continue
  330. }
  331. if !reflect.DeepEqual(f, tt.wantFrame) {
  332. t.Errorf("test %q: mismatch.\n got: %#v\nwant: %#v\n", tt.name, f, tt.wantFrame)
  333. }
  334. }
  335. }
  336. func TestWriteSettings(t *testing.T) {
  337. fr, buf := testFramer()
  338. settings := []Setting{{1, 2}, {3, 4}}
  339. fr.WriteSettings(settings...)
  340. const wantEnc = "\x00\x00\f\x04\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x03\x00\x00\x00\x04"
  341. if buf.String() != wantEnc {
  342. t.Errorf("encoded as %q; want %q", buf.Bytes(), wantEnc)
  343. }
  344. f, err := fr.ReadFrame()
  345. if err != nil {
  346. t.Fatal(err)
  347. }
  348. sf, ok := f.(*SettingsFrame)
  349. if !ok {
  350. t.Fatalf("Got a %T; want a SettingsFrame", f)
  351. }
  352. var got []Setting
  353. sf.ForeachSetting(func(s Setting) error {
  354. got = append(got, s)
  355. valBack, ok := sf.Value(s.ID)
  356. if !ok || valBack != s.Val {
  357. t.Errorf("Value(%d) = %v, %v; want %v, true", s.ID, valBack, ok, s.Val)
  358. }
  359. return nil
  360. })
  361. if !reflect.DeepEqual(settings, got) {
  362. t.Errorf("Read settings %+v != written settings %+v", got, settings)
  363. }
  364. }
  365. func TestWriteSettingsAck(t *testing.T) {
  366. fr, buf := testFramer()
  367. fr.WriteSettingsAck()
  368. const wantEnc = "\x00\x00\x00\x04\x01\x00\x00\x00\x00"
  369. if buf.String() != wantEnc {
  370. t.Errorf("encoded as %q; want %q", buf.Bytes(), wantEnc)
  371. }
  372. }
  373. func TestWriteWindowUpdate(t *testing.T) {
  374. fr, buf := testFramer()
  375. const streamID = 1<<24 + 2<<16 + 3<<8 + 4
  376. const incr = 7<<24 + 6<<16 + 5<<8 + 4
  377. if err := fr.WriteWindowUpdate(streamID, incr); err != nil {
  378. t.Fatal(err)
  379. }
  380. const wantEnc = "\x00\x00\x04\x08\x00\x01\x02\x03\x04\x07\x06\x05\x04"
  381. if buf.String() != wantEnc {
  382. t.Errorf("encoded as %q; want %q", buf.Bytes(), wantEnc)
  383. }
  384. f, err := fr.ReadFrame()
  385. if err != nil {
  386. t.Fatal(err)
  387. }
  388. want := &WindowUpdateFrame{
  389. FrameHeader: FrameHeader{
  390. valid: true,
  391. Type: 0x8,
  392. Flags: 0x0,
  393. Length: 0x4,
  394. StreamID: 0x1020304,
  395. },
  396. Increment: 0x7060504,
  397. }
  398. if !reflect.DeepEqual(f, want) {
  399. t.Errorf("parsed back %#v; want %#v", f, want)
  400. }
  401. }
  402. func TestWritePing(t *testing.T) { testWritePing(t, false) }
  403. func TestWritePingAck(t *testing.T) { testWritePing(t, true) }
  404. func testWritePing(t *testing.T, ack bool) {
  405. fr, buf := testFramer()
  406. if err := fr.WritePing(ack, [8]byte{1, 2, 3, 4, 5, 6, 7, 8}); err != nil {
  407. t.Fatal(err)
  408. }
  409. var wantFlags Flags
  410. if ack {
  411. wantFlags = FlagPingAck
  412. }
  413. var wantEnc = "\x00\x00\x08\x06" + string(wantFlags) + "\x00\x00\x00\x00" + "\x01\x02\x03\x04\x05\x06\x07\x08"
  414. if buf.String() != wantEnc {
  415. t.Errorf("encoded as %q; want %q", buf.Bytes(), wantEnc)
  416. }
  417. f, err := fr.ReadFrame()
  418. if err != nil {
  419. t.Fatal(err)
  420. }
  421. want := &PingFrame{
  422. FrameHeader: FrameHeader{
  423. valid: true,
  424. Type: 0x6,
  425. Flags: wantFlags,
  426. Length: 0x8,
  427. StreamID: 0,
  428. },
  429. Data: [8]byte{1, 2, 3, 4, 5, 6, 7, 8},
  430. }
  431. if !reflect.DeepEqual(f, want) {
  432. t.Errorf("parsed back %#v; want %#v", f, want)
  433. }
  434. }
  435. func TestReadFrameHeader(t *testing.T) {
  436. tests := []struct {
  437. in string
  438. want FrameHeader
  439. }{
  440. {in: "\x00\x00\x00" + "\x00" + "\x00" + "\x00\x00\x00\x00", want: FrameHeader{}},
  441. {in: "\x01\x02\x03" + "\x04" + "\x05" + "\x06\x07\x08\x09", want: FrameHeader{
  442. Length: 66051, Type: 4, Flags: 5, StreamID: 101124105,
  443. }},
  444. // Ignore high bit:
  445. {in: "\xff\xff\xff" + "\xff" + "\xff" + "\xff\xff\xff\xff", want: FrameHeader{
  446. Length: 16777215, Type: 255, Flags: 255, StreamID: 2147483647}},
  447. {in: "\xff\xff\xff" + "\xff" + "\xff" + "\x7f\xff\xff\xff", want: FrameHeader{
  448. Length: 16777215, Type: 255, Flags: 255, StreamID: 2147483647}},
  449. }
  450. for i, tt := range tests {
  451. got, err := readFrameHeader(make([]byte, 9), strings.NewReader(tt.in))
  452. if err != nil {
  453. t.Errorf("%d. readFrameHeader(%q) = %v", i, tt.in, err)
  454. continue
  455. }
  456. tt.want.valid = true
  457. if got != tt.want {
  458. t.Errorf("%d. readFrameHeader(%q) = %+v; want %+v", i, tt.in, got, tt.want)
  459. }
  460. }
  461. }
  462. func TestReadWriteFrameHeader(t *testing.T) {
  463. tests := []struct {
  464. len uint32
  465. typ FrameType
  466. flags Flags
  467. streamID uint32
  468. }{
  469. {len: 0, typ: 255, flags: 1, streamID: 0},
  470. {len: 0, typ: 255, flags: 1, streamID: 1},
  471. {len: 0, typ: 255, flags: 1, streamID: 255},
  472. {len: 0, typ: 255, flags: 1, streamID: 256},
  473. {len: 0, typ: 255, flags: 1, streamID: 65535},
  474. {len: 0, typ: 255, flags: 1, streamID: 65536},
  475. {len: 0, typ: 1, flags: 255, streamID: 1},
  476. {len: 255, typ: 1, flags: 255, streamID: 1},
  477. {len: 256, typ: 1, flags: 255, streamID: 1},
  478. {len: 65535, typ: 1, flags: 255, streamID: 1},
  479. {len: 65536, typ: 1, flags: 255, streamID: 1},
  480. {len: 16777215, typ: 1, flags: 255, streamID: 1},
  481. }
  482. for _, tt := range tests {
  483. fr, buf := testFramer()
  484. fr.startWrite(tt.typ, tt.flags, tt.streamID)
  485. fr.writeBytes(make([]byte, tt.len))
  486. fr.endWrite()
  487. fh, err := ReadFrameHeader(buf)
  488. if err != nil {
  489. t.Errorf("ReadFrameHeader(%+v) = %v", tt, err)
  490. continue
  491. }
  492. if fh.Type != tt.typ || fh.Flags != tt.flags || fh.Length != tt.len || fh.StreamID != tt.streamID {
  493. t.Errorf("ReadFrameHeader(%+v) = %+v; mismatch", tt, fh)
  494. }
  495. }
  496. }
  497. func TestWriteTooLargeFrame(t *testing.T) {
  498. fr, _ := testFramer()
  499. fr.startWrite(0, 1, 1)
  500. fr.writeBytes(make([]byte, 1<<24))
  501. err := fr.endWrite()
  502. if err != ErrFrameTooLarge {
  503. t.Errorf("endWrite = %v; want errFrameTooLarge", err)
  504. }
  505. }
  506. func TestWriteGoAway(t *testing.T) {
  507. const debug = "foo"
  508. fr, buf := testFramer()
  509. if err := fr.WriteGoAway(0x01020304, 0x05060708, []byte(debug)); err != nil {
  510. t.Fatal(err)
  511. }
  512. const wantEnc = "\x00\x00\v\a\x00\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08" + debug
  513. if buf.String() != wantEnc {
  514. t.Errorf("encoded as %q; want %q", buf.Bytes(), wantEnc)
  515. }
  516. f, err := fr.ReadFrame()
  517. if err != nil {
  518. t.Fatal(err)
  519. }
  520. want := &GoAwayFrame{
  521. FrameHeader: FrameHeader{
  522. valid: true,
  523. Type: 0x7,
  524. Flags: 0,
  525. Length: uint32(4 + 4 + len(debug)),
  526. StreamID: 0,
  527. },
  528. LastStreamID: 0x01020304,
  529. ErrCode: 0x05060708,
  530. debugData: []byte(debug),
  531. }
  532. if !reflect.DeepEqual(f, want) {
  533. t.Fatalf("parsed back:\n%#v\nwant:\n%#v", f, want)
  534. }
  535. if got := string(f.(*GoAwayFrame).DebugData()); got != debug {
  536. t.Errorf("debug data = %q; want %q", got, debug)
  537. }
  538. }
  539. func TestWritePushPromise(t *testing.T) {
  540. pp := PushPromiseParam{
  541. StreamID: 42,
  542. PromiseID: 42,
  543. BlockFragment: []byte("abc"),
  544. }
  545. fr, buf := testFramer()
  546. if err := fr.WritePushPromise(pp); err != nil {
  547. t.Fatal(err)
  548. }
  549. const wantEnc = "\x00\x00\x07\x05\x00\x00\x00\x00*\x00\x00\x00*abc"
  550. if buf.String() != wantEnc {
  551. t.Errorf("encoded as %q; want %q", buf.Bytes(), wantEnc)
  552. }
  553. f, err := fr.ReadFrame()
  554. if err != nil {
  555. t.Fatal(err)
  556. }
  557. _, ok := f.(*PushPromiseFrame)
  558. if !ok {
  559. t.Fatalf("got %T; want *PushPromiseFrame", f)
  560. }
  561. want := &PushPromiseFrame{
  562. FrameHeader: FrameHeader{
  563. valid: true,
  564. Type: 0x5,
  565. Flags: 0x0,
  566. Length: 0x7,
  567. StreamID: 42,
  568. },
  569. PromiseID: 42,
  570. headerFragBuf: []byte("abc"),
  571. }
  572. if !reflect.DeepEqual(f, want) {
  573. t.Fatalf("parsed back:\n%#v\nwant:\n%#v", f, want)
  574. }
  575. }
  576. // test checkFrameOrder and that HEADERS and CONTINUATION frames can't be intermingled.
  577. func TestReadFrameOrder(t *testing.T) {
  578. head := func(f *Framer, id uint32, end bool) {
  579. f.WriteHeaders(HeadersFrameParam{
  580. StreamID: id,
  581. BlockFragment: []byte("foo"), // unused, but non-empty
  582. EndHeaders: end,
  583. })
  584. }
  585. cont := func(f *Framer, id uint32, end bool) {
  586. f.WriteContinuation(id, end, []byte("foo"))
  587. }
  588. tests := [...]struct {
  589. name string
  590. w func(*Framer)
  591. atLeast int
  592. wantErr string
  593. }{
  594. 0: {
  595. w: func(f *Framer) {
  596. head(f, 1, true)
  597. },
  598. },
  599. 1: {
  600. w: func(f *Framer) {
  601. head(f, 1, true)
  602. head(f, 2, true)
  603. },
  604. },
  605. 2: {
  606. wantErr: "got HEADERS for stream 2; expected CONTINUATION following HEADERS for stream 1",
  607. w: func(f *Framer) {
  608. head(f, 1, false)
  609. head(f, 2, true)
  610. },
  611. },
  612. 3: {
  613. wantErr: "got DATA for stream 1; expected CONTINUATION following HEADERS for stream 1",
  614. w: func(f *Framer) {
  615. head(f, 1, false)
  616. },
  617. },
  618. 4: {
  619. w: func(f *Framer) {
  620. head(f, 1, false)
  621. cont(f, 1, true)
  622. head(f, 2, true)
  623. },
  624. },
  625. 5: {
  626. wantErr: "got CONTINUATION for stream 2; expected stream 1",
  627. w: func(f *Framer) {
  628. head(f, 1, false)
  629. cont(f, 2, true)
  630. head(f, 2, true)
  631. },
  632. },
  633. 6: {
  634. wantErr: "unexpected CONTINUATION for stream 1",
  635. w: func(f *Framer) {
  636. cont(f, 1, true)
  637. },
  638. },
  639. 7: {
  640. wantErr: "unexpected CONTINUATION for stream 1",
  641. w: func(f *Framer) {
  642. cont(f, 1, false)
  643. },
  644. },
  645. 8: {
  646. wantErr: "HEADERS frame with stream ID 0",
  647. w: func(f *Framer) {
  648. head(f, 0, true)
  649. },
  650. },
  651. 9: {
  652. wantErr: "CONTINUATION frame with stream ID 0",
  653. w: func(f *Framer) {
  654. cont(f, 0, true)
  655. },
  656. },
  657. 10: {
  658. wantErr: "unexpected CONTINUATION for stream 1",
  659. atLeast: 5,
  660. w: func(f *Framer) {
  661. head(f, 1, false)
  662. cont(f, 1, false)
  663. cont(f, 1, false)
  664. cont(f, 1, false)
  665. cont(f, 1, true)
  666. cont(f, 1, false)
  667. },
  668. },
  669. }
  670. for i, tt := range tests {
  671. buf := new(bytes.Buffer)
  672. f := NewFramer(buf, buf)
  673. f.AllowIllegalWrites = true
  674. tt.w(f)
  675. f.WriteData(1, true, nil) // to test transition away from last step
  676. var err error
  677. n := 0
  678. var log bytes.Buffer
  679. for {
  680. var got Frame
  681. got, err = f.ReadFrame()
  682. fmt.Fprintf(&log, " read %v, %v\n", got, err)
  683. if err != nil {
  684. break
  685. }
  686. n++
  687. }
  688. if err == io.EOF {
  689. err = nil
  690. }
  691. ok := tt.wantErr == ""
  692. if ok && err != nil {
  693. t.Errorf("%d. after %d good frames, ReadFrame = %v; want success\n%s", i, n, err, log.Bytes())
  694. continue
  695. }
  696. if !ok && err != ConnectionError(ErrCodeProtocol) {
  697. t.Errorf("%d. after %d good frames, ReadFrame = %v; want ConnectionError(ErrCodeProtocol)\n%s", i, n, err, log.Bytes())
  698. continue
  699. }
  700. if !((f.errDetail == nil && tt.wantErr == "") || (fmt.Sprint(f.errDetail) == tt.wantErr)) {
  701. t.Errorf("%d. framer eror = %q; want %q\n%s", i, f.errDetail, tt.wantErr, log.Bytes())
  702. }
  703. if n < tt.atLeast {
  704. t.Errorf("%d. framer only read %d frames; want at least %d\n%s", i, n, tt.atLeast, log.Bytes())
  705. }
  706. }
  707. }
  708. func TestMetaFrameHeader(t *testing.T) {
  709. write := func(f *Framer, frags ...[]byte) {
  710. for i, frag := range frags {
  711. end := (i == len(frags)-1)
  712. if i == 0 {
  713. f.WriteHeaders(HeadersFrameParam{
  714. StreamID: 1,
  715. BlockFragment: frag,
  716. EndHeaders: end,
  717. })
  718. } else {
  719. f.WriteContinuation(1, end, frag)
  720. }
  721. }
  722. }
  723. want := func(flags Flags, length uint32, pairs ...string) *MetaHeadersFrame {
  724. mh := &MetaHeadersFrame{
  725. HeadersFrame: &HeadersFrame{
  726. FrameHeader: FrameHeader{
  727. Type: FrameHeaders,
  728. Flags: flags,
  729. Length: length,
  730. StreamID: 1,
  731. },
  732. },
  733. Fields: []hpack.HeaderField(nil),
  734. }
  735. for len(pairs) > 0 {
  736. mh.Fields = append(mh.Fields, hpack.HeaderField{
  737. Name: pairs[0],
  738. Value: pairs[1],
  739. })
  740. pairs = pairs[2:]
  741. }
  742. return mh
  743. }
  744. truncated := func(mh *MetaHeadersFrame) *MetaHeadersFrame {
  745. mh.Truncated = true
  746. return mh
  747. }
  748. const noFlags Flags = 0
  749. oneKBString := strings.Repeat("a", 1<<10)
  750. tests := [...]struct {
  751. name string
  752. w func(*Framer)
  753. want interface{} // *MetaHeaderFrame or error
  754. wantErrReason string
  755. maxHeaderListSize uint32
  756. }{
  757. 0: {
  758. name: "single_headers",
  759. w: func(f *Framer) {
  760. var he hpackEncoder
  761. all := he.encodeHeaderRaw(t, ":method", "GET", ":path", "/")
  762. write(f, all)
  763. },
  764. want: want(FlagHeadersEndHeaders, 2, ":method", "GET", ":path", "/"),
  765. },
  766. 1: {
  767. name: "with_continuation",
  768. w: func(f *Framer) {
  769. var he hpackEncoder
  770. all := he.encodeHeaderRaw(t, ":method", "GET", ":path", "/", "foo", "bar")
  771. write(f, all[:1], all[1:])
  772. },
  773. want: want(noFlags, 1, ":method", "GET", ":path", "/", "foo", "bar"),
  774. },
  775. 2: {
  776. name: "with_two_continuation",
  777. w: func(f *Framer) {
  778. var he hpackEncoder
  779. all := he.encodeHeaderRaw(t, ":method", "GET", ":path", "/", "foo", "bar")
  780. write(f, all[:2], all[2:4], all[4:])
  781. },
  782. want: want(noFlags, 2, ":method", "GET", ":path", "/", "foo", "bar"),
  783. },
  784. 3: {
  785. name: "big_string_okay",
  786. w: func(f *Framer) {
  787. var he hpackEncoder
  788. all := he.encodeHeaderRaw(t, ":method", "GET", ":path", "/", "foo", oneKBString)
  789. write(f, all[:2], all[2:])
  790. },
  791. want: want(noFlags, 2, ":method", "GET", ":path", "/", "foo", oneKBString),
  792. },
  793. 4: {
  794. name: "big_string_error",
  795. w: func(f *Framer) {
  796. var he hpackEncoder
  797. all := he.encodeHeaderRaw(t, ":method", "GET", ":path", "/", "foo", oneKBString)
  798. write(f, all[:2], all[2:])
  799. },
  800. maxHeaderListSize: (1 << 10) / 2,
  801. want: ConnectionError(ErrCodeCompression),
  802. },
  803. 5: {
  804. name: "max_header_list_truncated",
  805. w: func(f *Framer) {
  806. var he hpackEncoder
  807. var pairs = []string{":method", "GET", ":path", "/"}
  808. for i := 0; i < 100; i++ {
  809. pairs = append(pairs, "foo", "bar")
  810. }
  811. all := he.encodeHeaderRaw(t, pairs...)
  812. write(f, all[:2], all[2:])
  813. },
  814. maxHeaderListSize: (1 << 10) / 2,
  815. want: truncated(want(noFlags, 2,
  816. ":method", "GET",
  817. ":path", "/",
  818. "foo", "bar",
  819. "foo", "bar",
  820. "foo", "bar",
  821. "foo", "bar",
  822. "foo", "bar",
  823. "foo", "bar",
  824. "foo", "bar",
  825. "foo", "bar",
  826. "foo", "bar",
  827. "foo", "bar",
  828. "foo", "bar", // 11
  829. )),
  830. },
  831. 6: {
  832. name: "pseudo_order",
  833. w: func(f *Framer) {
  834. write(f, encodeHeaderRaw(t,
  835. ":method", "GET",
  836. "foo", "bar",
  837. ":path", "/", // bogus
  838. ))
  839. },
  840. want: StreamError{1, ErrCodeProtocol},
  841. wantErrReason: "pseudo header field after regular",
  842. },
  843. 7: {
  844. name: "pseudo_unknown",
  845. w: func(f *Framer) {
  846. write(f, encodeHeaderRaw(t,
  847. ":unknown", "foo", // bogus
  848. "foo", "bar",
  849. ))
  850. },
  851. want: StreamError{1, ErrCodeProtocol},
  852. wantErrReason: "invalid pseudo-header \":unknown\"",
  853. },
  854. 8: {
  855. name: "pseudo_mix_request_response",
  856. w: func(f *Framer) {
  857. write(f, encodeHeaderRaw(t,
  858. ":method", "GET",
  859. ":status", "100",
  860. ))
  861. },
  862. want: StreamError{1, ErrCodeProtocol},
  863. wantErrReason: "mix of request and response pseudo headers",
  864. },
  865. 9: {
  866. name: "pseudo_dup",
  867. w: func(f *Framer) {
  868. write(f, encodeHeaderRaw(t,
  869. ":method", "GET",
  870. ":method", "POST",
  871. ))
  872. },
  873. want: StreamError{1, ErrCodeProtocol},
  874. wantErrReason: "duplicate pseudo-header \":method\"",
  875. },
  876. 10: {
  877. name: "trailer_okay_no_pseudo",
  878. w: func(f *Framer) { write(f, encodeHeaderRaw(t, "foo", "bar")) },
  879. want: want(FlagHeadersEndHeaders, 8, "foo", "bar"),
  880. },
  881. 11: {
  882. name: "invalid_field_name",
  883. w: func(f *Framer) { write(f, encodeHeaderRaw(t, "CapitalBad", "x")) },
  884. want: StreamError{1, ErrCodeProtocol},
  885. wantErrReason: "invalid header field name \"CapitalBad\"",
  886. },
  887. 12: {
  888. name: "invalid_field_value",
  889. w: func(f *Framer) { write(f, encodeHeaderRaw(t, "key", "bad_null\x00")) },
  890. want: StreamError{1, ErrCodeProtocol},
  891. wantErrReason: "invalid header field value \"bad_null\\x00\"",
  892. },
  893. }
  894. for i, tt := range tests {
  895. buf := new(bytes.Buffer)
  896. f := NewFramer(buf, buf)
  897. f.ReadMetaHeaders = hpack.NewDecoder(initialHeaderTableSize, nil)
  898. f.MaxHeaderListSize = tt.maxHeaderListSize
  899. tt.w(f)
  900. name := tt.name
  901. if name == "" {
  902. name = fmt.Sprintf("test index %d", i)
  903. }
  904. var got interface{}
  905. var err error
  906. got, err = f.ReadFrame()
  907. if err != nil {
  908. got = err
  909. }
  910. if !reflect.DeepEqual(got, tt.want) {
  911. if mhg, ok := got.(*MetaHeadersFrame); ok {
  912. if mhw, ok := tt.want.(*MetaHeadersFrame); ok {
  913. hg := mhg.HeadersFrame
  914. hw := mhw.HeadersFrame
  915. if hg != nil && hw != nil && !reflect.DeepEqual(*hg, *hw) {
  916. t.Errorf("%s: headers differ:\n got: %+v\nwant: %+v\n", name, *hg, *hw)
  917. }
  918. }
  919. }
  920. str := func(v interface{}) string {
  921. if _, ok := v.(error); ok {
  922. return fmt.Sprintf("error %v", v)
  923. } else {
  924. return fmt.Sprintf("value %#v", v)
  925. }
  926. }
  927. t.Errorf("%s:\n got: %v\nwant: %s", name, str(got), str(tt.want))
  928. }
  929. if tt.wantErrReason != "" && tt.wantErrReason != fmt.Sprint(f.errDetail) {
  930. t.Errorf("%s: got error reason %q; want %q", name, f.errDetail, tt.wantErrReason)
  931. }
  932. }
  933. }
  934. func encodeHeaderRaw(t *testing.T, pairs ...string) []byte {
  935. var he hpackEncoder
  936. return he.encodeHeaderRaw(t, pairs...)
  937. }