The reconcile package is used for DOM reconcilation in Isomorphic Go web applications.

frame_test.go 29KB

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