frame_test.go 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243
  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 TestWriteDataPadded(t *testing.T) {
  94. tests := [...]struct {
  95. streamID uint32
  96. endStream bool
  97. data []byte
  98. pad []byte
  99. wantHeader FrameHeader
  100. }{
  101. // Unpadded:
  102. 0: {
  103. streamID: 1,
  104. endStream: true,
  105. data: []byte("foo"),
  106. pad: nil,
  107. wantHeader: FrameHeader{
  108. Type: FrameData,
  109. Flags: FlagDataEndStream,
  110. Length: 3,
  111. StreamID: 1,
  112. },
  113. },
  114. // Padded bit set, but no padding:
  115. 1: {
  116. streamID: 1,
  117. endStream: true,
  118. data: []byte("foo"),
  119. pad: []byte{},
  120. wantHeader: FrameHeader{
  121. Type: FrameData,
  122. Flags: FlagDataEndStream | FlagDataPadded,
  123. Length: 4,
  124. StreamID: 1,
  125. },
  126. },
  127. // Padded bit set, with padding:
  128. 2: {
  129. streamID: 1,
  130. endStream: false,
  131. data: []byte("foo"),
  132. pad: []byte{0, 0, 0},
  133. wantHeader: FrameHeader{
  134. Type: FrameData,
  135. Flags: FlagDataPadded,
  136. Length: 7,
  137. StreamID: 1,
  138. },
  139. },
  140. }
  141. for i, tt := range tests {
  142. fr, _ := testFramer()
  143. fr.WriteDataPadded(tt.streamID, tt.endStream, tt.data, tt.pad)
  144. f, err := fr.ReadFrame()
  145. if err != nil {
  146. t.Errorf("%d. ReadFrame: %v", i, err)
  147. continue
  148. }
  149. got := f.Header()
  150. tt.wantHeader.valid = true
  151. if !got.Equal(tt.wantHeader) {
  152. t.Errorf("%d. read %+v; want %+v", i, got, tt.wantHeader)
  153. continue
  154. }
  155. df := f.(*DataFrame)
  156. if !bytes.Equal(df.Data(), tt.data) {
  157. t.Errorf("%d. got %q; want %q", i, df.Data(), tt.data)
  158. }
  159. }
  160. }
  161. func (fh FrameHeader) Equal(b FrameHeader) bool {
  162. return fh.valid == b.valid &&
  163. fh.Type == b.Type &&
  164. fh.Flags == b.Flags &&
  165. fh.Length == b.Length &&
  166. fh.StreamID == b.StreamID
  167. }
  168. func TestWriteHeaders(t *testing.T) {
  169. tests := []struct {
  170. name string
  171. p HeadersFrameParam
  172. wantEnc string
  173. wantFrame *HeadersFrame
  174. }{
  175. {
  176. "basic",
  177. HeadersFrameParam{
  178. StreamID: 42,
  179. BlockFragment: []byte("abc"),
  180. Priority: PriorityParam{},
  181. },
  182. "\x00\x00\x03\x01\x00\x00\x00\x00*abc",
  183. &HeadersFrame{
  184. FrameHeader: FrameHeader{
  185. valid: true,
  186. StreamID: 42,
  187. Type: FrameHeaders,
  188. Length: uint32(len("abc")),
  189. },
  190. Priority: PriorityParam{},
  191. headerFragBuf: []byte("abc"),
  192. },
  193. },
  194. {
  195. "basic + end flags",
  196. HeadersFrameParam{
  197. StreamID: 42,
  198. BlockFragment: []byte("abc"),
  199. EndStream: true,
  200. EndHeaders: true,
  201. Priority: PriorityParam{},
  202. },
  203. "\x00\x00\x03\x01\x05\x00\x00\x00*abc",
  204. &HeadersFrame{
  205. FrameHeader: FrameHeader{
  206. valid: true,
  207. StreamID: 42,
  208. Type: FrameHeaders,
  209. Flags: FlagHeadersEndStream | FlagHeadersEndHeaders,
  210. Length: uint32(len("abc")),
  211. },
  212. Priority: PriorityParam{},
  213. headerFragBuf: []byte("abc"),
  214. },
  215. },
  216. {
  217. "with padding",
  218. HeadersFrameParam{
  219. StreamID: 42,
  220. BlockFragment: []byte("abc"),
  221. EndStream: true,
  222. EndHeaders: true,
  223. PadLength: 5,
  224. Priority: PriorityParam{},
  225. },
  226. "\x00\x00\t\x01\r\x00\x00\x00*\x05abc\x00\x00\x00\x00\x00",
  227. &HeadersFrame{
  228. FrameHeader: FrameHeader{
  229. valid: true,
  230. StreamID: 42,
  231. Type: FrameHeaders,
  232. Flags: FlagHeadersEndStream | FlagHeadersEndHeaders | FlagHeadersPadded,
  233. Length: uint32(1 + len("abc") + 5), // pad length + contents + padding
  234. },
  235. Priority: PriorityParam{},
  236. headerFragBuf: []byte("abc"),
  237. },
  238. },
  239. {
  240. "with priority",
  241. HeadersFrameParam{
  242. StreamID: 42,
  243. BlockFragment: []byte("abc"),
  244. EndStream: true,
  245. EndHeaders: true,
  246. PadLength: 2,
  247. Priority: PriorityParam{
  248. StreamDep: 15,
  249. Exclusive: true,
  250. Weight: 127,
  251. },
  252. },
  253. "\x00\x00\v\x01-\x00\x00\x00*\x02\x80\x00\x00\x0f\u007fabc\x00\x00",
  254. &HeadersFrame{
  255. FrameHeader: FrameHeader{
  256. valid: true,
  257. StreamID: 42,
  258. Type: FrameHeaders,
  259. Flags: FlagHeadersEndStream | FlagHeadersEndHeaders | FlagHeadersPadded | FlagHeadersPriority,
  260. Length: uint32(1 + 5 + len("abc") + 2), // pad length + priority + contents + padding
  261. },
  262. Priority: PriorityParam{
  263. StreamDep: 15,
  264. Exclusive: true,
  265. Weight: 127,
  266. },
  267. headerFragBuf: []byte("abc"),
  268. },
  269. },
  270. {
  271. "with priority stream dep zero", // golang.org/issue/15444
  272. HeadersFrameParam{
  273. StreamID: 42,
  274. BlockFragment: []byte("abc"),
  275. EndStream: true,
  276. EndHeaders: true,
  277. PadLength: 2,
  278. Priority: PriorityParam{
  279. StreamDep: 0,
  280. Exclusive: true,
  281. Weight: 127,
  282. },
  283. },
  284. "\x00\x00\v\x01-\x00\x00\x00*\x02\x80\x00\x00\x00\u007fabc\x00\x00",
  285. &HeadersFrame{
  286. FrameHeader: FrameHeader{
  287. valid: true,
  288. StreamID: 42,
  289. Type: FrameHeaders,
  290. Flags: FlagHeadersEndStream | FlagHeadersEndHeaders | FlagHeadersPadded | FlagHeadersPriority,
  291. Length: uint32(1 + 5 + len("abc") + 2), // pad length + priority + contents + padding
  292. },
  293. Priority: PriorityParam{
  294. StreamDep: 0,
  295. Exclusive: true,
  296. Weight: 127,
  297. },
  298. headerFragBuf: []byte("abc"),
  299. },
  300. },
  301. }
  302. for _, tt := range tests {
  303. fr, buf := testFramer()
  304. if err := fr.WriteHeaders(tt.p); err != nil {
  305. t.Errorf("test %q: %v", tt.name, err)
  306. continue
  307. }
  308. if buf.String() != tt.wantEnc {
  309. t.Errorf("test %q: encoded %q; want %q", tt.name, buf.Bytes(), tt.wantEnc)
  310. }
  311. f, err := fr.ReadFrame()
  312. if err != nil {
  313. t.Errorf("test %q: failed to read the frame back: %v", tt.name, err)
  314. continue
  315. }
  316. if !reflect.DeepEqual(f, tt.wantFrame) {
  317. t.Errorf("test %q: mismatch.\n got: %#v\nwant: %#v\n", tt.name, f, tt.wantFrame)
  318. }
  319. }
  320. }
  321. func TestWriteInvalidStreamDep(t *testing.T) {
  322. fr, _ := testFramer()
  323. err := fr.WriteHeaders(HeadersFrameParam{
  324. StreamID: 42,
  325. Priority: PriorityParam{
  326. StreamDep: 1 << 31,
  327. },
  328. })
  329. if err != errDepStreamID {
  330. t.Errorf("header error = %v; want %q", err, errDepStreamID)
  331. }
  332. err = fr.WritePriority(2, PriorityParam{StreamDep: 1 << 31})
  333. if err != errDepStreamID {
  334. t.Errorf("priority error = %v; want %q", err, errDepStreamID)
  335. }
  336. }
  337. func TestWriteContinuation(t *testing.T) {
  338. const streamID = 42
  339. tests := []struct {
  340. name string
  341. end bool
  342. frag []byte
  343. wantFrame *ContinuationFrame
  344. }{
  345. {
  346. "not end",
  347. false,
  348. []byte("abc"),
  349. &ContinuationFrame{
  350. FrameHeader: FrameHeader{
  351. valid: true,
  352. StreamID: streamID,
  353. Type: FrameContinuation,
  354. Length: uint32(len("abc")),
  355. },
  356. headerFragBuf: []byte("abc"),
  357. },
  358. },
  359. {
  360. "end",
  361. true,
  362. []byte("def"),
  363. &ContinuationFrame{
  364. FrameHeader: FrameHeader{
  365. valid: true,
  366. StreamID: streamID,
  367. Type: FrameContinuation,
  368. Flags: FlagContinuationEndHeaders,
  369. Length: uint32(len("def")),
  370. },
  371. headerFragBuf: []byte("def"),
  372. },
  373. },
  374. }
  375. for _, tt := range tests {
  376. fr, _ := testFramer()
  377. if err := fr.WriteContinuation(streamID, tt.end, tt.frag); err != nil {
  378. t.Errorf("test %q: %v", tt.name, err)
  379. continue
  380. }
  381. fr.AllowIllegalReads = true
  382. f, err := fr.ReadFrame()
  383. if err != nil {
  384. t.Errorf("test %q: failed to read the frame back: %v", tt.name, err)
  385. continue
  386. }
  387. if !reflect.DeepEqual(f, tt.wantFrame) {
  388. t.Errorf("test %q: mismatch.\n got: %#v\nwant: %#v\n", tt.name, f, tt.wantFrame)
  389. }
  390. }
  391. }
  392. func TestWritePriority(t *testing.T) {
  393. const streamID = 42
  394. tests := []struct {
  395. name string
  396. priority PriorityParam
  397. wantFrame *PriorityFrame
  398. }{
  399. {
  400. "not exclusive",
  401. PriorityParam{
  402. StreamDep: 2,
  403. Exclusive: false,
  404. Weight: 127,
  405. },
  406. &PriorityFrame{
  407. FrameHeader{
  408. valid: true,
  409. StreamID: streamID,
  410. Type: FramePriority,
  411. Length: 5,
  412. },
  413. PriorityParam{
  414. StreamDep: 2,
  415. Exclusive: false,
  416. Weight: 127,
  417. },
  418. },
  419. },
  420. {
  421. "exclusive",
  422. PriorityParam{
  423. StreamDep: 3,
  424. Exclusive: true,
  425. Weight: 77,
  426. },
  427. &PriorityFrame{
  428. FrameHeader{
  429. valid: true,
  430. StreamID: streamID,
  431. Type: FramePriority,
  432. Length: 5,
  433. },
  434. PriorityParam{
  435. StreamDep: 3,
  436. Exclusive: true,
  437. Weight: 77,
  438. },
  439. },
  440. },
  441. }
  442. for _, tt := range tests {
  443. fr, _ := testFramer()
  444. if err := fr.WritePriority(streamID, tt.priority); err != nil {
  445. t.Errorf("test %q: %v", tt.name, err)
  446. continue
  447. }
  448. f, err := fr.ReadFrame()
  449. if err != nil {
  450. t.Errorf("test %q: failed to read the frame back: %v", tt.name, err)
  451. continue
  452. }
  453. if !reflect.DeepEqual(f, tt.wantFrame) {
  454. t.Errorf("test %q: mismatch.\n got: %#v\nwant: %#v\n", tt.name, f, tt.wantFrame)
  455. }
  456. }
  457. }
  458. func TestWriteSettings(t *testing.T) {
  459. fr, buf := testFramer()
  460. settings := []Setting{{1, 2}, {3, 4}}
  461. fr.WriteSettings(settings...)
  462. const wantEnc = "\x00\x00\f\x04\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x03\x00\x00\x00\x04"
  463. if buf.String() != wantEnc {
  464. t.Errorf("encoded as %q; want %q", buf.Bytes(), wantEnc)
  465. }
  466. f, err := fr.ReadFrame()
  467. if err != nil {
  468. t.Fatal(err)
  469. }
  470. sf, ok := f.(*SettingsFrame)
  471. if !ok {
  472. t.Fatalf("Got a %T; want a SettingsFrame", f)
  473. }
  474. var got []Setting
  475. sf.ForeachSetting(func(s Setting) error {
  476. got = append(got, s)
  477. valBack, ok := sf.Value(s.ID)
  478. if !ok || valBack != s.Val {
  479. t.Errorf("Value(%d) = %v, %v; want %v, true", s.ID, valBack, ok, s.Val)
  480. }
  481. return nil
  482. })
  483. if !reflect.DeepEqual(settings, got) {
  484. t.Errorf("Read settings %+v != written settings %+v", got, settings)
  485. }
  486. }
  487. func TestWriteSettingsAck(t *testing.T) {
  488. fr, buf := testFramer()
  489. fr.WriteSettingsAck()
  490. const wantEnc = "\x00\x00\x00\x04\x01\x00\x00\x00\x00"
  491. if buf.String() != wantEnc {
  492. t.Errorf("encoded as %q; want %q", buf.Bytes(), wantEnc)
  493. }
  494. }
  495. func TestWriteWindowUpdate(t *testing.T) {
  496. fr, buf := testFramer()
  497. const streamID = 1<<24 + 2<<16 + 3<<8 + 4
  498. const incr = 7<<24 + 6<<16 + 5<<8 + 4
  499. if err := fr.WriteWindowUpdate(streamID, incr); err != nil {
  500. t.Fatal(err)
  501. }
  502. const wantEnc = "\x00\x00\x04\x08\x00\x01\x02\x03\x04\x07\x06\x05\x04"
  503. if buf.String() != wantEnc {
  504. t.Errorf("encoded as %q; want %q", buf.Bytes(), wantEnc)
  505. }
  506. f, err := fr.ReadFrame()
  507. if err != nil {
  508. t.Fatal(err)
  509. }
  510. want := &WindowUpdateFrame{
  511. FrameHeader: FrameHeader{
  512. valid: true,
  513. Type: 0x8,
  514. Flags: 0x0,
  515. Length: 0x4,
  516. StreamID: 0x1020304,
  517. },
  518. Increment: 0x7060504,
  519. }
  520. if !reflect.DeepEqual(f, want) {
  521. t.Errorf("parsed back %#v; want %#v", f, want)
  522. }
  523. }
  524. func TestWritePing(t *testing.T) { testWritePing(t, false) }
  525. func TestWritePingAck(t *testing.T) { testWritePing(t, true) }
  526. func testWritePing(t *testing.T, ack bool) {
  527. fr, buf := testFramer()
  528. if err := fr.WritePing(ack, [8]byte{1, 2, 3, 4, 5, 6, 7, 8}); err != nil {
  529. t.Fatal(err)
  530. }
  531. var wantFlags Flags
  532. if ack {
  533. wantFlags = FlagPingAck
  534. }
  535. var wantEnc = "\x00\x00\x08\x06" + string(wantFlags) + "\x00\x00\x00\x00" + "\x01\x02\x03\x04\x05\x06\x07\x08"
  536. if buf.String() != wantEnc {
  537. t.Errorf("encoded as %q; want %q", buf.Bytes(), wantEnc)
  538. }
  539. f, err := fr.ReadFrame()
  540. if err != nil {
  541. t.Fatal(err)
  542. }
  543. want := &PingFrame{
  544. FrameHeader: FrameHeader{
  545. valid: true,
  546. Type: 0x6,
  547. Flags: wantFlags,
  548. Length: 0x8,
  549. StreamID: 0,
  550. },
  551. Data: [8]byte{1, 2, 3, 4, 5, 6, 7, 8},
  552. }
  553. if !reflect.DeepEqual(f, want) {
  554. t.Errorf("parsed back %#v; want %#v", f, want)
  555. }
  556. }
  557. func TestReadFrameHeader(t *testing.T) {
  558. tests := []struct {
  559. in string
  560. want FrameHeader
  561. }{
  562. {in: "\x00\x00\x00" + "\x00" + "\x00" + "\x00\x00\x00\x00", want: FrameHeader{}},
  563. {in: "\x01\x02\x03" + "\x04" + "\x05" + "\x06\x07\x08\x09", want: FrameHeader{
  564. Length: 66051, Type: 4, Flags: 5, StreamID: 101124105,
  565. }},
  566. // Ignore high bit:
  567. {in: "\xff\xff\xff" + "\xff" + "\xff" + "\xff\xff\xff\xff", want: FrameHeader{
  568. Length: 16777215, Type: 255, Flags: 255, StreamID: 2147483647}},
  569. {in: "\xff\xff\xff" + "\xff" + "\xff" + "\x7f\xff\xff\xff", want: FrameHeader{
  570. Length: 16777215, Type: 255, Flags: 255, StreamID: 2147483647}},
  571. }
  572. for i, tt := range tests {
  573. got, err := readFrameHeader(make([]byte, 9), strings.NewReader(tt.in))
  574. if err != nil {
  575. t.Errorf("%d. readFrameHeader(%q) = %v", i, tt.in, err)
  576. continue
  577. }
  578. tt.want.valid = true
  579. if !got.Equal(tt.want) {
  580. t.Errorf("%d. readFrameHeader(%q) = %+v; want %+v", i, tt.in, got, tt.want)
  581. }
  582. }
  583. }
  584. func TestReadWriteFrameHeader(t *testing.T) {
  585. tests := []struct {
  586. len uint32
  587. typ FrameType
  588. flags Flags
  589. streamID uint32
  590. }{
  591. {len: 0, typ: 255, flags: 1, streamID: 0},
  592. {len: 0, typ: 255, flags: 1, streamID: 1},
  593. {len: 0, typ: 255, flags: 1, streamID: 255},
  594. {len: 0, typ: 255, flags: 1, streamID: 256},
  595. {len: 0, typ: 255, flags: 1, streamID: 65535},
  596. {len: 0, typ: 255, flags: 1, streamID: 65536},
  597. {len: 0, typ: 1, flags: 255, streamID: 1},
  598. {len: 255, typ: 1, flags: 255, streamID: 1},
  599. {len: 256, typ: 1, flags: 255, streamID: 1},
  600. {len: 65535, typ: 1, flags: 255, streamID: 1},
  601. {len: 65536, typ: 1, flags: 255, streamID: 1},
  602. {len: 16777215, typ: 1, flags: 255, streamID: 1},
  603. }
  604. for _, tt := range tests {
  605. fr, buf := testFramer()
  606. fr.startWrite(tt.typ, tt.flags, tt.streamID)
  607. fr.writeBytes(make([]byte, tt.len))
  608. fr.endWrite()
  609. fh, err := ReadFrameHeader(buf)
  610. if err != nil {
  611. t.Errorf("ReadFrameHeader(%+v) = %v", tt, err)
  612. continue
  613. }
  614. if fh.Type != tt.typ || fh.Flags != tt.flags || fh.Length != tt.len || fh.StreamID != tt.streamID {
  615. t.Errorf("ReadFrameHeader(%+v) = %+v; mismatch", tt, fh)
  616. }
  617. }
  618. }
  619. func TestWriteTooLargeFrame(t *testing.T) {
  620. fr, _ := testFramer()
  621. fr.startWrite(0, 1, 1)
  622. fr.writeBytes(make([]byte, 1<<24))
  623. err := fr.endWrite()
  624. if err != ErrFrameTooLarge {
  625. t.Errorf("endWrite = %v; want errFrameTooLarge", err)
  626. }
  627. }
  628. func TestWriteGoAway(t *testing.T) {
  629. const debug = "foo"
  630. fr, buf := testFramer()
  631. if err := fr.WriteGoAway(0x01020304, 0x05060708, []byte(debug)); err != nil {
  632. t.Fatal(err)
  633. }
  634. const wantEnc = "\x00\x00\v\a\x00\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08" + debug
  635. if buf.String() != wantEnc {
  636. t.Errorf("encoded as %q; want %q", buf.Bytes(), wantEnc)
  637. }
  638. f, err := fr.ReadFrame()
  639. if err != nil {
  640. t.Fatal(err)
  641. }
  642. want := &GoAwayFrame{
  643. FrameHeader: FrameHeader{
  644. valid: true,
  645. Type: 0x7,
  646. Flags: 0,
  647. Length: uint32(4 + 4 + len(debug)),
  648. StreamID: 0,
  649. },
  650. LastStreamID: 0x01020304,
  651. ErrCode: 0x05060708,
  652. debugData: []byte(debug),
  653. }
  654. if !reflect.DeepEqual(f, want) {
  655. t.Fatalf("parsed back:\n%#v\nwant:\n%#v", f, want)
  656. }
  657. if got := string(f.(*GoAwayFrame).DebugData()); got != debug {
  658. t.Errorf("debug data = %q; want %q", got, debug)
  659. }
  660. }
  661. func TestWritePushPromise(t *testing.T) {
  662. pp := PushPromiseParam{
  663. StreamID: 42,
  664. PromiseID: 42,
  665. BlockFragment: []byte("abc"),
  666. }
  667. fr, buf := testFramer()
  668. if err := fr.WritePushPromise(pp); err != nil {
  669. t.Fatal(err)
  670. }
  671. const wantEnc = "\x00\x00\x07\x05\x00\x00\x00\x00*\x00\x00\x00*abc"
  672. if buf.String() != wantEnc {
  673. t.Errorf("encoded as %q; want %q", buf.Bytes(), wantEnc)
  674. }
  675. f, err := fr.ReadFrame()
  676. if err != nil {
  677. t.Fatal(err)
  678. }
  679. _, ok := f.(*PushPromiseFrame)
  680. if !ok {
  681. t.Fatalf("got %T; want *PushPromiseFrame", f)
  682. }
  683. want := &PushPromiseFrame{
  684. FrameHeader: FrameHeader{
  685. valid: true,
  686. Type: 0x5,
  687. Flags: 0x0,
  688. Length: 0x7,
  689. StreamID: 42,
  690. },
  691. PromiseID: 42,
  692. headerFragBuf: []byte("abc"),
  693. }
  694. if !reflect.DeepEqual(f, want) {
  695. t.Fatalf("parsed back:\n%#v\nwant:\n%#v", f, want)
  696. }
  697. }
  698. // test checkFrameOrder and that HEADERS and CONTINUATION frames can't be intermingled.
  699. func TestReadFrameOrder(t *testing.T) {
  700. head := func(f *Framer, id uint32, end bool) {
  701. f.WriteHeaders(HeadersFrameParam{
  702. StreamID: id,
  703. BlockFragment: []byte("foo"), // unused, but non-empty
  704. EndHeaders: end,
  705. })
  706. }
  707. cont := func(f *Framer, id uint32, end bool) {
  708. f.WriteContinuation(id, end, []byte("foo"))
  709. }
  710. tests := [...]struct {
  711. name string
  712. w func(*Framer)
  713. atLeast int
  714. wantErr string
  715. }{
  716. 0: {
  717. w: func(f *Framer) {
  718. head(f, 1, true)
  719. },
  720. },
  721. 1: {
  722. w: func(f *Framer) {
  723. head(f, 1, true)
  724. head(f, 2, true)
  725. },
  726. },
  727. 2: {
  728. wantErr: "got HEADERS for stream 2; expected CONTINUATION following HEADERS for stream 1",
  729. w: func(f *Framer) {
  730. head(f, 1, false)
  731. head(f, 2, true)
  732. },
  733. },
  734. 3: {
  735. wantErr: "got DATA for stream 1; expected CONTINUATION following HEADERS for stream 1",
  736. w: func(f *Framer) {
  737. head(f, 1, false)
  738. },
  739. },
  740. 4: {
  741. w: func(f *Framer) {
  742. head(f, 1, false)
  743. cont(f, 1, true)
  744. head(f, 2, true)
  745. },
  746. },
  747. 5: {
  748. wantErr: "got CONTINUATION for stream 2; expected stream 1",
  749. w: func(f *Framer) {
  750. head(f, 1, false)
  751. cont(f, 2, true)
  752. head(f, 2, true)
  753. },
  754. },
  755. 6: {
  756. wantErr: "unexpected CONTINUATION for stream 1",
  757. w: func(f *Framer) {
  758. cont(f, 1, true)
  759. },
  760. },
  761. 7: {
  762. wantErr: "unexpected CONTINUATION for stream 1",
  763. w: func(f *Framer) {
  764. cont(f, 1, false)
  765. },
  766. },
  767. 8: {
  768. wantErr: "HEADERS frame with stream ID 0",
  769. w: func(f *Framer) {
  770. head(f, 0, true)
  771. },
  772. },
  773. 9: {
  774. wantErr: "CONTINUATION frame with stream ID 0",
  775. w: func(f *Framer) {
  776. cont(f, 0, true)
  777. },
  778. },
  779. 10: {
  780. wantErr: "unexpected CONTINUATION for stream 1",
  781. atLeast: 5,
  782. w: func(f *Framer) {
  783. head(f, 1, false)
  784. cont(f, 1, false)
  785. cont(f, 1, false)
  786. cont(f, 1, false)
  787. cont(f, 1, true)
  788. cont(f, 1, false)
  789. },
  790. },
  791. }
  792. for i, tt := range tests {
  793. buf := new(bytes.Buffer)
  794. f := NewFramer(buf, buf)
  795. f.AllowIllegalWrites = true
  796. tt.w(f)
  797. f.WriteData(1, true, nil) // to test transition away from last step
  798. var err error
  799. n := 0
  800. var log bytes.Buffer
  801. for {
  802. var got Frame
  803. got, err = f.ReadFrame()
  804. fmt.Fprintf(&log, " read %v, %v\n", got, err)
  805. if err != nil {
  806. break
  807. }
  808. n++
  809. }
  810. if err == io.EOF {
  811. err = nil
  812. }
  813. ok := tt.wantErr == ""
  814. if ok && err != nil {
  815. t.Errorf("%d. after %d good frames, ReadFrame = %v; want success\n%s", i, n, err, log.Bytes())
  816. continue
  817. }
  818. if !ok && err != ConnectionError(ErrCodeProtocol) {
  819. t.Errorf("%d. after %d good frames, ReadFrame = %v; want ConnectionError(ErrCodeProtocol)\n%s", i, n, err, log.Bytes())
  820. continue
  821. }
  822. if !((f.errDetail == nil && tt.wantErr == "") || (fmt.Sprint(f.errDetail) == tt.wantErr)) {
  823. t.Errorf("%d. framer eror = %q; want %q\n%s", i, f.errDetail, tt.wantErr, log.Bytes())
  824. }
  825. if n < tt.atLeast {
  826. t.Errorf("%d. framer only read %d frames; want at least %d\n%s", i, n, tt.atLeast, log.Bytes())
  827. }
  828. }
  829. }
  830. func TestMetaFrameHeader(t *testing.T) {
  831. write := func(f *Framer, frags ...[]byte) {
  832. for i, frag := range frags {
  833. end := (i == len(frags)-1)
  834. if i == 0 {
  835. f.WriteHeaders(HeadersFrameParam{
  836. StreamID: 1,
  837. BlockFragment: frag,
  838. EndHeaders: end,
  839. })
  840. } else {
  841. f.WriteContinuation(1, end, frag)
  842. }
  843. }
  844. }
  845. want := func(flags Flags, length uint32, pairs ...string) *MetaHeadersFrame {
  846. mh := &MetaHeadersFrame{
  847. HeadersFrame: &HeadersFrame{
  848. FrameHeader: FrameHeader{
  849. Type: FrameHeaders,
  850. Flags: flags,
  851. Length: length,
  852. StreamID: 1,
  853. },
  854. },
  855. Fields: []hpack.HeaderField(nil),
  856. }
  857. for len(pairs) > 0 {
  858. mh.Fields = append(mh.Fields, hpack.HeaderField{
  859. Name: pairs[0],
  860. Value: pairs[1],
  861. })
  862. pairs = pairs[2:]
  863. }
  864. return mh
  865. }
  866. truncated := func(mh *MetaHeadersFrame) *MetaHeadersFrame {
  867. mh.Truncated = true
  868. return mh
  869. }
  870. const noFlags Flags = 0
  871. oneKBString := strings.Repeat("a", 1<<10)
  872. tests := [...]struct {
  873. name string
  874. w func(*Framer)
  875. want interface{} // *MetaHeaderFrame or error
  876. wantErrReason string
  877. maxHeaderListSize uint32
  878. }{
  879. 0: {
  880. name: "single_headers",
  881. w: func(f *Framer) {
  882. var he hpackEncoder
  883. all := he.encodeHeaderRaw(t, ":method", "GET", ":path", "/")
  884. write(f, all)
  885. },
  886. want: want(FlagHeadersEndHeaders, 2, ":method", "GET", ":path", "/"),
  887. },
  888. 1: {
  889. name: "with_continuation",
  890. w: func(f *Framer) {
  891. var he hpackEncoder
  892. all := he.encodeHeaderRaw(t, ":method", "GET", ":path", "/", "foo", "bar")
  893. write(f, all[:1], all[1:])
  894. },
  895. want: want(noFlags, 1, ":method", "GET", ":path", "/", "foo", "bar"),
  896. },
  897. 2: {
  898. name: "with_two_continuation",
  899. w: func(f *Framer) {
  900. var he hpackEncoder
  901. all := he.encodeHeaderRaw(t, ":method", "GET", ":path", "/", "foo", "bar")
  902. write(f, all[:2], all[2:4], all[4:])
  903. },
  904. want: want(noFlags, 2, ":method", "GET", ":path", "/", "foo", "bar"),
  905. },
  906. 3: {
  907. name: "big_string_okay",
  908. w: func(f *Framer) {
  909. var he hpackEncoder
  910. all := he.encodeHeaderRaw(t, ":method", "GET", ":path", "/", "foo", oneKBString)
  911. write(f, all[:2], all[2:])
  912. },
  913. want: want(noFlags, 2, ":method", "GET", ":path", "/", "foo", oneKBString),
  914. },
  915. 4: {
  916. name: "big_string_error",
  917. w: func(f *Framer) {
  918. var he hpackEncoder
  919. all := he.encodeHeaderRaw(t, ":method", "GET", ":path", "/", "foo", oneKBString)
  920. write(f, all[:2], all[2:])
  921. },
  922. maxHeaderListSize: (1 << 10) / 2,
  923. want: ConnectionError(ErrCodeCompression),
  924. },
  925. 5: {
  926. name: "max_header_list_truncated",
  927. w: func(f *Framer) {
  928. var he hpackEncoder
  929. var pairs = []string{":method", "GET", ":path", "/"}
  930. for i := 0; i < 100; i++ {
  931. pairs = append(pairs, "foo", "bar")
  932. }
  933. all := he.encodeHeaderRaw(t, pairs...)
  934. write(f, all[:2], all[2:])
  935. },
  936. maxHeaderListSize: (1 << 10) / 2,
  937. want: truncated(want(noFlags, 2,
  938. ":method", "GET",
  939. ":path", "/",
  940. "foo", "bar",
  941. "foo", "bar",
  942. "foo", "bar",
  943. "foo", "bar",
  944. "foo", "bar",
  945. "foo", "bar",
  946. "foo", "bar",
  947. "foo", "bar",
  948. "foo", "bar",
  949. "foo", "bar",
  950. "foo", "bar", // 11
  951. )),
  952. },
  953. 6: {
  954. name: "pseudo_order",
  955. w: func(f *Framer) {
  956. write(f, encodeHeaderRaw(t,
  957. ":method", "GET",
  958. "foo", "bar",
  959. ":path", "/", // bogus
  960. ))
  961. },
  962. want: streamError(1, ErrCodeProtocol),
  963. wantErrReason: "pseudo header field after regular",
  964. },
  965. 7: {
  966. name: "pseudo_unknown",
  967. w: func(f *Framer) {
  968. write(f, encodeHeaderRaw(t,
  969. ":unknown", "foo", // bogus
  970. "foo", "bar",
  971. ))
  972. },
  973. want: streamError(1, ErrCodeProtocol),
  974. wantErrReason: "invalid pseudo-header \":unknown\"",
  975. },
  976. 8: {
  977. name: "pseudo_mix_request_response",
  978. w: func(f *Framer) {
  979. write(f, encodeHeaderRaw(t,
  980. ":method", "GET",
  981. ":status", "100",
  982. ))
  983. },
  984. want: streamError(1, ErrCodeProtocol),
  985. wantErrReason: "mix of request and response pseudo headers",
  986. },
  987. 9: {
  988. name: "pseudo_dup",
  989. w: func(f *Framer) {
  990. write(f, encodeHeaderRaw(t,
  991. ":method", "GET",
  992. ":method", "POST",
  993. ))
  994. },
  995. want: streamError(1, ErrCodeProtocol),
  996. wantErrReason: "duplicate pseudo-header \":method\"",
  997. },
  998. 10: {
  999. name: "trailer_okay_no_pseudo",
  1000. w: func(f *Framer) { write(f, encodeHeaderRaw(t, "foo", "bar")) },
  1001. want: want(FlagHeadersEndHeaders, 8, "foo", "bar"),
  1002. },
  1003. 11: {
  1004. name: "invalid_field_name",
  1005. w: func(f *Framer) { write(f, encodeHeaderRaw(t, "CapitalBad", "x")) },
  1006. want: streamError(1, ErrCodeProtocol),
  1007. wantErrReason: "invalid header field name \"CapitalBad\"",
  1008. },
  1009. 12: {
  1010. name: "invalid_field_value",
  1011. w: func(f *Framer) { write(f, encodeHeaderRaw(t, "key", "bad_null\x00")) },
  1012. want: streamError(1, ErrCodeProtocol),
  1013. wantErrReason: "invalid header field value \"bad_null\\x00\"",
  1014. },
  1015. }
  1016. for i, tt := range tests {
  1017. buf := new(bytes.Buffer)
  1018. f := NewFramer(buf, buf)
  1019. f.ReadMetaHeaders = hpack.NewDecoder(initialHeaderTableSize, nil)
  1020. f.MaxHeaderListSize = tt.maxHeaderListSize
  1021. tt.w(f)
  1022. name := tt.name
  1023. if name == "" {
  1024. name = fmt.Sprintf("test index %d", i)
  1025. }
  1026. var got interface{}
  1027. var err error
  1028. got, err = f.ReadFrame()
  1029. if err != nil {
  1030. got = err
  1031. // Ignore the StreamError.Cause field, if it matches the wantErrReason.
  1032. // The test table above predates the Cause field.
  1033. if se, ok := err.(StreamError); ok && se.Cause != nil && se.Cause.Error() == tt.wantErrReason {
  1034. se.Cause = nil
  1035. got = se
  1036. }
  1037. }
  1038. if !reflect.DeepEqual(got, tt.want) {
  1039. if mhg, ok := got.(*MetaHeadersFrame); ok {
  1040. if mhw, ok := tt.want.(*MetaHeadersFrame); ok {
  1041. hg := mhg.HeadersFrame
  1042. hw := mhw.HeadersFrame
  1043. if hg != nil && hw != nil && !reflect.DeepEqual(*hg, *hw) {
  1044. t.Errorf("%s: headers differ:\n got: %+v\nwant: %+v\n", name, *hg, *hw)
  1045. }
  1046. }
  1047. }
  1048. str := func(v interface{}) string {
  1049. if _, ok := v.(error); ok {
  1050. return fmt.Sprintf("error %v", v)
  1051. } else {
  1052. return fmt.Sprintf("value %#v", v)
  1053. }
  1054. }
  1055. t.Errorf("%s:\n got: %v\nwant: %s", name, str(got), str(tt.want))
  1056. }
  1057. if tt.wantErrReason != "" && tt.wantErrReason != fmt.Sprint(f.errDetail) {
  1058. t.Errorf("%s: got error reason %q; want %q", name, f.errDetail, tt.wantErrReason)
  1059. }
  1060. }
  1061. }
  1062. func TestSetReuseFrames(t *testing.T) {
  1063. fr, buf := testFramer()
  1064. fr.SetReuseFrames()
  1065. // Check that DataFrames are reused. Note that
  1066. // SetReuseFrames only currently implements reuse of DataFrames.
  1067. firstDf := readAndVerifyDataFrame("ABC", 3, fr, buf, t)
  1068. for i := 0; i < 10; i++ {
  1069. df := readAndVerifyDataFrame("XYZ", 3, fr, buf, t)
  1070. if df != firstDf {
  1071. t.Errorf("Expected Framer to return references to the same DataFrame. Have %v and %v", &df, &firstDf)
  1072. }
  1073. }
  1074. for i := 0; i < 10; i++ {
  1075. df := readAndVerifyDataFrame("", 0, fr, buf, t)
  1076. if df != firstDf {
  1077. t.Errorf("Expected Framer to return references to the same DataFrame. Have %v and %v", &df, &firstDf)
  1078. }
  1079. }
  1080. for i := 0; i < 10; i++ {
  1081. df := readAndVerifyDataFrame("HHH", 3, fr, buf, t)
  1082. if df != firstDf {
  1083. t.Errorf("Expected Framer to return references to the same DataFrame. Have %v and %v", &df, &firstDf)
  1084. }
  1085. }
  1086. }
  1087. func TestSetReuseFramesMoreThanOnce(t *testing.T) {
  1088. fr, buf := testFramer()
  1089. fr.SetReuseFrames()
  1090. firstDf := readAndVerifyDataFrame("ABC", 3, fr, buf, t)
  1091. fr.SetReuseFrames()
  1092. for i := 0; i < 10; i++ {
  1093. df := readAndVerifyDataFrame("XYZ", 3, fr, buf, t)
  1094. // SetReuseFrames should be idempotent
  1095. fr.SetReuseFrames()
  1096. if df != firstDf {
  1097. t.Errorf("Expected Framer to return references to the same DataFrame. Have %v and %v", &df, &firstDf)
  1098. }
  1099. }
  1100. }
  1101. func TestNoSetReuseFrames(t *testing.T) {
  1102. fr, buf := testFramer()
  1103. const numNewDataFrames = 10
  1104. dfSoFar := make([]interface{}, numNewDataFrames)
  1105. // Check that DataFrames are not reused if SetReuseFrames wasn't called.
  1106. // SetReuseFrames only currently implements reuse of DataFrames.
  1107. for i := 0; i < numNewDataFrames; i++ {
  1108. df := readAndVerifyDataFrame("XYZ", 3, fr, buf, t)
  1109. for _, item := range dfSoFar {
  1110. if df == item {
  1111. t.Errorf("Expected Framer to return new DataFrames since SetNoReuseFrames not set.")
  1112. }
  1113. }
  1114. dfSoFar[i] = df
  1115. }
  1116. }
  1117. func readAndVerifyDataFrame(data string, length byte, fr *Framer, buf *bytes.Buffer, t *testing.T) *DataFrame {
  1118. var streamID uint32 = 1<<24 + 2<<16 + 3<<8 + 4
  1119. fr.WriteData(streamID, true, []byte(data))
  1120. wantEnc := "\x00\x00" + string(length) + "\x00\x01\x01\x02\x03\x04" + data
  1121. if buf.String() != wantEnc {
  1122. t.Errorf("encoded as %q; want %q", buf.Bytes(), wantEnc)
  1123. }
  1124. f, err := fr.ReadFrame()
  1125. if err != nil {
  1126. t.Fatal(err)
  1127. }
  1128. df, ok := f.(*DataFrame)
  1129. if !ok {
  1130. t.Fatalf("got %T; want *DataFrame", f)
  1131. }
  1132. if !bytes.Equal(df.Data(), []byte(data)) {
  1133. t.Errorf("got %q; want %q", df.Data(), []byte(data))
  1134. }
  1135. if f.Header().Flags&1 == 0 {
  1136. t.Errorf("didn't see END_STREAM flag")
  1137. }
  1138. return df
  1139. }
  1140. func encodeHeaderRaw(t *testing.T, pairs ...string) []byte {
  1141. var he hpackEncoder
  1142. return he.encodeHeaderRaw(t, pairs...)
  1143. }
  1144. func TestSettingsDuplicates(t *testing.T) {
  1145. tests := []struct {
  1146. settings []Setting
  1147. want bool
  1148. }{
  1149. {nil, false},
  1150. {[]Setting{{ID: 1}}, false},
  1151. {[]Setting{{ID: 1}, {ID: 2}}, false},
  1152. {[]Setting{{ID: 1}, {ID: 2}}, false},
  1153. {[]Setting{{ID: 1}, {ID: 2}, {ID: 3}}, false},
  1154. {[]Setting{{ID: 1}, {ID: 2}, {ID: 3}}, false},
  1155. {[]Setting{{ID: 1}, {ID: 2}, {ID: 3}, {ID: 4}}, false},
  1156. {[]Setting{{ID: 1}, {ID: 2}, {ID: 3}, {ID: 2}}, true},
  1157. {[]Setting{{ID: 4}, {ID: 2}, {ID: 3}, {ID: 4}}, true},
  1158. {[]Setting{
  1159. {ID: 1}, {ID: 2}, {ID: 3}, {ID: 4},
  1160. {ID: 5}, {ID: 6}, {ID: 7}, {ID: 8},
  1161. {ID: 9}, {ID: 10}, {ID: 11}, {ID: 12},
  1162. }, false},
  1163. {[]Setting{
  1164. {ID: 1}, {ID: 2}, {ID: 3}, {ID: 4},
  1165. {ID: 5}, {ID: 6}, {ID: 7}, {ID: 8},
  1166. {ID: 9}, {ID: 10}, {ID: 11}, {ID: 11},
  1167. }, true},
  1168. }
  1169. for i, tt := range tests {
  1170. fr, _ := testFramer()
  1171. fr.WriteSettings(tt.settings...)
  1172. f, err := fr.ReadFrame()
  1173. if err != nil {
  1174. t.Fatalf("%d. ReadFrame: %v", i, err)
  1175. }
  1176. sf := f.(*SettingsFrame)
  1177. got := sf.HasDuplicates()
  1178. if got != tt.want {
  1179. t.Errorf("%d. HasDuplicates = %v; want %v", i, got, tt.want)
  1180. }
  1181. }
  1182. }