frame_test.go 25 KB

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