http2_test.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699
  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. // See https://code.google.com/p/go/source/browse/CONTRIBUTORS
  5. // Licensed under the same terms as Go itself:
  6. // https://code.google.com/p/go/source/browse/LICENSE
  7. package http2
  8. import (
  9. "bytes"
  10. "crypto/tls"
  11. "errors"
  12. "flag"
  13. "fmt"
  14. "io"
  15. "log"
  16. "net"
  17. "net/http"
  18. "net/http/httptest"
  19. "os"
  20. "os/exec"
  21. "reflect"
  22. "strconv"
  23. "strings"
  24. "sync/atomic"
  25. "testing"
  26. "time"
  27. "github.com/bradfitz/http2/hpack"
  28. )
  29. func init() {
  30. DebugGoroutines = true
  31. flag.BoolVar(&VerboseLogs, "verboseh2", false, "Verbose HTTP/2 debug logging")
  32. }
  33. type serverTester struct {
  34. cc net.Conn // client conn
  35. t *testing.T
  36. ts *httptest.Server
  37. fr *Framer
  38. logBuf *bytes.Buffer
  39. }
  40. func newServerTester(t *testing.T, handler http.HandlerFunc) *serverTester {
  41. logBuf := new(bytes.Buffer)
  42. ts := httptest.NewUnstartedServer(handler)
  43. ConfigureServer(ts.Config, &Server{})
  44. ts.TLS = ts.Config.TLSConfig // the httptest.Server has its own copy of this TLS config
  45. ts.Config.ErrorLog = log.New(io.MultiWriter(twriter{t: t}, logBuf), "", log.LstdFlags)
  46. ts.StartTLS()
  47. if VerboseLogs {
  48. t.Logf("Running test server at: %s", ts.URL)
  49. }
  50. cc, err := tls.Dial("tcp", ts.Listener.Addr().String(), &tls.Config{
  51. InsecureSkipVerify: true,
  52. NextProtos: []string{npnProto},
  53. })
  54. if err != nil {
  55. t.Fatal(err)
  56. }
  57. log.SetOutput(twriter{t})
  58. return &serverTester{
  59. t: t,
  60. ts: ts,
  61. cc: cc,
  62. fr: NewFramer(cc, cc),
  63. logBuf: logBuf,
  64. }
  65. }
  66. func (st *serverTester) Close() {
  67. st.ts.Close()
  68. st.cc.Close()
  69. log.SetOutput(os.Stderr)
  70. }
  71. // greet initiates the client's HTTP/2 connection into a state where
  72. // frames may be sent.
  73. func (st *serverTester) greet() {
  74. st.writePreface()
  75. st.writeInitialSettings()
  76. st.wantSettings()
  77. st.writeSettingsAck()
  78. st.wantSettingsAck()
  79. }
  80. func (st *serverTester) writePreface() {
  81. n, err := st.cc.Write(clientPreface)
  82. if err != nil {
  83. st.t.Fatalf("Error writing client preface: %v", err)
  84. }
  85. if n != len(clientPreface) {
  86. st.t.Fatalf("Writing client preface, wrote %d bytes; want %d", n, len(clientPreface))
  87. }
  88. }
  89. func (st *serverTester) writeInitialSettings() {
  90. if err := st.fr.WriteSettings(); err != nil {
  91. st.t.Fatalf("Error writing initial SETTINGS frame from client to server: %v", err)
  92. }
  93. }
  94. func (st *serverTester) writeSettingsAck() {
  95. if err := st.fr.WriteSettingsAck(); err != nil {
  96. st.t.Fatalf("Error writing ACK of server's SETTINGS: %v", err)
  97. }
  98. }
  99. func (st *serverTester) writeHeaders(p HeadersFrameParam) {
  100. if err := st.fr.WriteHeaders(p); err != nil {
  101. st.t.Fatalf("Error writing HEADERS: %v", err)
  102. }
  103. }
  104. // bodylessReq1 writes a HEADERS frames with StreamID 1 and EndStream and EndHeaders set.
  105. func (st *serverTester) bodylessReq1(headers ...string) {
  106. st.writeHeaders(HeadersFrameParam{
  107. StreamID: 1, // clients send odd numbers
  108. BlockFragment: encodeHeader(st.t, headers...),
  109. EndStream: true,
  110. EndHeaders: true,
  111. })
  112. }
  113. func (st *serverTester) writeData(streamID uint32, endStream bool, data []byte) {
  114. if err := st.fr.WriteData(streamID, endStream, data); err != nil {
  115. st.t.Fatalf("Error writing DATA: %v", err)
  116. }
  117. }
  118. func (st *serverTester) readFrame() (Frame, error) {
  119. frc := make(chan Frame, 1)
  120. errc := make(chan error, 1)
  121. go func() {
  122. fr, err := st.fr.ReadFrame()
  123. if err != nil {
  124. errc <- err
  125. } else {
  126. frc <- fr
  127. }
  128. }()
  129. t := time.NewTimer(2 * time.Second)
  130. defer t.Stop()
  131. select {
  132. case f := <-frc:
  133. return f, nil
  134. case err := <-errc:
  135. return nil, err
  136. case <-t.C:
  137. return nil, errors.New("timeout waiting for frame")
  138. }
  139. }
  140. func (st *serverTester) wantSettings() *SettingsFrame {
  141. f, err := st.readFrame()
  142. if err != nil {
  143. st.t.Fatalf("Error while expecting a SETTINGS frame: %v", err)
  144. }
  145. sf, ok := f.(*SettingsFrame)
  146. if !ok {
  147. st.t.Fatalf("got a %T; want *SettingsFrame", f)
  148. }
  149. return sf
  150. }
  151. func (st *serverTester) wantPing() *PingFrame {
  152. f, err := st.readFrame()
  153. if err != nil {
  154. st.t.Fatalf("Error while expecting a PING frame: %v", err)
  155. }
  156. pf, ok := f.(*PingFrame)
  157. if !ok {
  158. st.t.Fatalf("got a %T; want *PingFrame", f)
  159. }
  160. return pf
  161. }
  162. func (st *serverTester) wantRSTStream(streamID uint32, errCode ErrCode) {
  163. f, err := st.readFrame()
  164. if err != nil {
  165. st.t.Fatalf("Error while expecting an RSTStream frame: %v", err)
  166. }
  167. rs, ok := f.(*RSTStreamFrame)
  168. if !ok {
  169. st.t.Fatalf("got a %T; want *RSTStream", f)
  170. }
  171. if rs.FrameHeader.StreamID != streamID {
  172. st.t.Fatalf("RSTStream StreamID = %d; want %d", rs.FrameHeader.StreamID, streamID)
  173. }
  174. if rs.ErrCode != uint32(errCode) {
  175. st.t.Fatalf("RSTStream ErrCode = %d (%s); want %d (%s)", rs.ErrCode, rs.ErrCode, errCode, errCode)
  176. }
  177. }
  178. func (st *serverTester) wantSettingsAck() {
  179. f, err := st.readFrame()
  180. if err != nil {
  181. st.t.Fatal(err)
  182. }
  183. sf, ok := f.(*SettingsFrame)
  184. if !ok {
  185. st.t.Fatalf("Wanting a settings ACK, received a %T", f)
  186. }
  187. if !sf.Header().Flags.Has(FlagSettingsAck) {
  188. st.t.Fatal("Settings Frame didn't have ACK set")
  189. }
  190. }
  191. func TestServer(t *testing.T) {
  192. gotReq := make(chan bool, 1)
  193. st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
  194. w.Header().Set("Foo", "Bar")
  195. gotReq <- true
  196. })
  197. defer st.Close()
  198. covers("3.5", `
  199. The server connection preface consists of a potentially empty
  200. SETTINGS frame ([SETTINGS]) that MUST be the first frame the
  201. server sends in the HTTP/2 connection.
  202. `)
  203. st.writePreface()
  204. st.writeInitialSettings()
  205. st.wantSettings().ForeachSetting(func(s Setting) {
  206. t.Logf("Server sent setting %v = %v", s.ID, s.Val)
  207. })
  208. st.writeSettingsAck()
  209. st.wantSettingsAck()
  210. st.writeHeaders(HeadersFrameParam{
  211. StreamID: 1, // clients send odd numbers
  212. BlockFragment: encodeHeader(t),
  213. EndStream: true, // no DATA frames
  214. EndHeaders: true,
  215. })
  216. select {
  217. case <-gotReq:
  218. case <-time.After(2 * time.Second):
  219. t.Error("timeout waiting for request")
  220. }
  221. }
  222. func TestServer_Request_Get(t *testing.T) {
  223. testServerRequest(t, func(st *serverTester) {
  224. st.writeHeaders(HeadersFrameParam{
  225. StreamID: 1, // clients send odd numbers
  226. BlockFragment: encodeHeader(t, "foo-bar", "some-value"),
  227. EndStream: true, // no DATA frames
  228. EndHeaders: true,
  229. })
  230. }, func(r *http.Request) {
  231. if r.Method != "GET" {
  232. t.Errorf("Method = %q; want GET", r.Method)
  233. }
  234. if r.ContentLength != 0 {
  235. t.Errorf("ContentLength = %v; want 0", r.ContentLength)
  236. }
  237. if r.Close {
  238. t.Error("Close = true; want false")
  239. }
  240. if !strings.Contains(r.RemoteAddr, ":") {
  241. t.Errorf("RemoteAddr = %q; want something with a colon", r.RemoteAddr)
  242. }
  243. if r.Proto != "HTTP/2.0" || r.ProtoMajor != 2 || r.ProtoMinor != 0 {
  244. t.Errorf("Proto = %q Major=%v,Minor=%v; want HTTP/2.0", r.Proto, r.ProtoMajor, r.ProtoMinor)
  245. }
  246. wantHeader := http.Header{
  247. "Foo-Bar": []string{"some-value"},
  248. }
  249. if !reflect.DeepEqual(r.Header, wantHeader) {
  250. t.Errorf("Header = %#v; want %#v", r.Header, wantHeader)
  251. }
  252. if n, err := r.Body.Read([]byte(" ")); err != io.EOF || n != 0 {
  253. t.Errorf("Read = %d, %v; want 0, EOF", n, err)
  254. }
  255. })
  256. }
  257. // TODO: add a test with EndStream=true on the HEADERS but setting a
  258. // Content-Length anyway. Should we just omit it and force it to
  259. // zero?
  260. func TestServer_Request_Post_NoContentLength_EndStream(t *testing.T) {
  261. testServerRequest(t, func(st *serverTester) {
  262. st.writeHeaders(HeadersFrameParam{
  263. StreamID: 1, // clients send odd numbers
  264. BlockFragment: encodeHeader(t, ":method", "POST"),
  265. EndStream: true,
  266. EndHeaders: true,
  267. })
  268. }, func(r *http.Request) {
  269. if r.Method != "POST" {
  270. t.Errorf("Method = %q; want POST", r.Method)
  271. }
  272. if r.ContentLength != 0 {
  273. t.Errorf("ContentLength = %v; want 0", r.ContentLength)
  274. }
  275. if n, err := r.Body.Read([]byte(" ")); err != io.EOF || n != 0 {
  276. t.Errorf("Read = %d, %v; want 0, EOF", n, err)
  277. }
  278. })
  279. }
  280. func TestServer_Request_Post_Body(t *testing.T) {
  281. t.Skip("TODO: post bodies not yet implemented")
  282. testServerRequest(t, func(st *serverTester) {
  283. st.writeHeaders(HeadersFrameParam{
  284. StreamID: 1, // clients send odd numbers
  285. BlockFragment: encodeHeader(t, ":method", "POST"),
  286. EndStream: false, // migth be DATA frames
  287. EndHeaders: true,
  288. })
  289. st.writeData(1, true, nil)
  290. }, func(r *http.Request) {
  291. if r.Method != "POST" {
  292. t.Errorf("Method = %q; want POST", r.Method)
  293. }
  294. if r.ContentLength != -1 {
  295. t.Errorf("ContentLength = %v; want -1", r.ContentLength)
  296. }
  297. if n, err := r.Body.Read([]byte(" ")); err != io.EOF || n != 0 {
  298. t.Errorf("Read = %d, %v; want 0, EOF", n, err)
  299. }
  300. })
  301. }
  302. // Using a Host header, instead of :authority
  303. func TestServer_Request_Get_Host(t *testing.T) {
  304. const host = "example.com"
  305. testServerRequest(t, func(st *serverTester) {
  306. st.writeHeaders(HeadersFrameParam{
  307. StreamID: 1, // clients send odd numbers
  308. BlockFragment: encodeHeader(t, "host", host),
  309. EndStream: true,
  310. EndHeaders: true,
  311. })
  312. }, func(r *http.Request) {
  313. if r.Host != host {
  314. t.Errorf("Host = %q; want %q", r.Host, host)
  315. }
  316. })
  317. }
  318. // Using an :authority pseudo-header, instead of Host
  319. func TestServer_Request_Get_Authority(t *testing.T) {
  320. const host = "example.com"
  321. testServerRequest(t, func(st *serverTester) {
  322. st.writeHeaders(HeadersFrameParam{
  323. StreamID: 1, // clients send odd numbers
  324. BlockFragment: encodeHeader(t, ":authority", host),
  325. EndStream: true,
  326. EndHeaders: true,
  327. })
  328. }, func(r *http.Request) {
  329. if r.Host != host {
  330. t.Errorf("Host = %q; want %q", r.Host, host)
  331. }
  332. })
  333. }
  334. func TestServer_Request_WithContinuation(t *testing.T) {
  335. wantHeader := http.Header{
  336. "Foo-One": []string{"value-one"},
  337. "Foo-Two": []string{"value-two"},
  338. "Foo-Three": []string{"value-three"},
  339. }
  340. testServerRequest(t, func(st *serverTester) {
  341. fullHeaders := encodeHeader(t,
  342. "foo-one", "value-one",
  343. "foo-two", "value-two",
  344. "foo-three", "value-three",
  345. )
  346. remain := fullHeaders
  347. chunks := 0
  348. for len(remain) > 0 {
  349. const maxChunkSize = 5
  350. chunk := remain
  351. if len(chunk) > maxChunkSize {
  352. chunk = chunk[:maxChunkSize]
  353. }
  354. remain = remain[len(chunk):]
  355. if chunks == 0 {
  356. st.writeHeaders(HeadersFrameParam{
  357. StreamID: 1, // clients send odd numbers
  358. BlockFragment: chunk,
  359. EndStream: true, // no DATA frames
  360. EndHeaders: false, // we'll have continuation frames
  361. })
  362. } else {
  363. err := st.fr.WriteContinuation(1, len(remain) == 0, chunk)
  364. if err != nil {
  365. t.Fatal(err)
  366. }
  367. }
  368. chunks++
  369. }
  370. if chunks < 2 {
  371. t.Fatal("too few chunks")
  372. }
  373. }, func(r *http.Request) {
  374. if !reflect.DeepEqual(r.Header, wantHeader) {
  375. t.Errorf("Header = %#v; want %#v", r.Header, wantHeader)
  376. }
  377. })
  378. }
  379. // Concatenated cookie headers. ("8.1.2.5 Compressing the Cookie Header Field")
  380. func TestServer_Request_CookieConcat(t *testing.T) {
  381. const host = "example.com"
  382. testServerRequest(t, func(st *serverTester) {
  383. st.bodylessReq1(
  384. ":authority", host,
  385. "cookie", "a=b",
  386. "cookie", "c=d",
  387. "cookie", "e=f",
  388. )
  389. }, func(r *http.Request) {
  390. const want = "a=b; c=d; e=f"
  391. if got := r.Header.Get("Cookie"); got != want {
  392. t.Errorf("Cookie = %q; want %q", got, want)
  393. }
  394. })
  395. }
  396. func TestServer_Request_Reject_CapitalHeader(t *testing.T) {
  397. testRejectRequest(t, func(st *serverTester) { st.bodylessReq1("UPPER", "v") })
  398. }
  399. func TestServer_Request_Reject_Pseudo_Missing_method(t *testing.T) {
  400. testRejectRequest(t, func(st *serverTester) { st.bodylessReq1(":method", "") })
  401. }
  402. func TestServer_Request_Reject_Pseudo_ExactlyOne(t *testing.T) {
  403. // 8.1.2.3 Request Pseudo-Header Fields
  404. // "All HTTP/2 requests MUST include exactly one valid value" ...
  405. testRejectRequest(t, func(st *serverTester) { st.bodylessReq1(":method", "GET", ":method", "POST") })
  406. }
  407. func TestServer_Request_Reject_Pseudo_AfterRegular(t *testing.T) {
  408. // 8.1.2.3 Request Pseudo-Header Fields
  409. // "All pseudo-header fields MUST appear in the header block
  410. // before regular header fields. Any request or response that
  411. // contains a pseudo-header field that appears in a header
  412. // block after a regular header field MUST be treated as
  413. // malformed (Section 8.1.2.6)."
  414. testRejectRequest(t, func(st *serverTester) {
  415. var buf bytes.Buffer
  416. enc := hpack.NewEncoder(&buf)
  417. enc.WriteField(hpack.HeaderField{Name: ":method", Value: "GET"})
  418. enc.WriteField(hpack.HeaderField{Name: "regular", Value: "foobar"})
  419. enc.WriteField(hpack.HeaderField{Name: ":path", Value: "/"})
  420. enc.WriteField(hpack.HeaderField{Name: ":scheme", Value: "https"})
  421. st.writeHeaders(HeadersFrameParam{
  422. StreamID: 1, // clients send odd numbers
  423. BlockFragment: buf.Bytes(),
  424. EndStream: true,
  425. EndHeaders: true,
  426. })
  427. })
  428. }
  429. func TestServer_Request_Reject_Pseudo_Missing_path(t *testing.T) {
  430. testRejectRequest(t, func(st *serverTester) { st.bodylessReq1(":path", "") })
  431. }
  432. func TestServer_Request_Reject_Pseudo_Missing_scheme(t *testing.T) {
  433. testRejectRequest(t, func(st *serverTester) { st.bodylessReq1(":scheme", "") })
  434. }
  435. func TestServer_Request_Reject_Pseudo_scheme_invalid(t *testing.T) {
  436. testRejectRequest(t, func(st *serverTester) { st.bodylessReq1(":scheme", "bogus") })
  437. }
  438. func TestServer_Request_Reject_Pseudo_Unknown(t *testing.T) {
  439. testRejectRequest(t, func(st *serverTester) { st.bodylessReq1(":unknown_thing", "") })
  440. }
  441. func testRejectRequest(t *testing.T, send func(*serverTester)) {
  442. st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
  443. t.Fatal("server request made it to handler; should've been rejected")
  444. })
  445. defer st.Close()
  446. st.greet()
  447. send(st)
  448. st.wantRSTStream(1, ErrCodeProtocol)
  449. }
  450. func TestServer_Ping(t *testing.T) {
  451. st := newServerTester(t, nil)
  452. defer st.Close()
  453. st.greet()
  454. // Server should ignore this one, since it has ACK set.
  455. ackPingData := [8]byte{1, 2, 4, 8, 16, 32, 64, 128}
  456. if err := st.fr.WritePing(true, ackPingData); err != nil {
  457. t.Fatal(err)
  458. }
  459. // But the server should reply to this one, since ACK is false.
  460. pingData := [8]byte{1, 2, 3, 4, 5, 6, 7, 8}
  461. if err := st.fr.WritePing(false, pingData); err != nil {
  462. t.Fatal(err)
  463. }
  464. pf := st.wantPing()
  465. if !pf.Flags.Has(FlagPingAck) {
  466. t.Error("response ping doesn't have ACK set")
  467. }
  468. if pf.Data != pingData {
  469. t.Errorf("response ping has data %q; want %q", pf.Data, pingData)
  470. }
  471. }
  472. // TODO: test HEADERS w/o EndHeaders + another HEADERS (should get rejected)
  473. // TODO: test HEADERS w/ EndHeaders + a continuation HEADERS (should get rejected)
  474. // testServerRequest sets up an idle HTTP/2 connection and lets you
  475. // write a single request with writeReq, and then verify that the
  476. // *http.Request is built correctly in checkReq.
  477. func testServerRequest(t *testing.T, writeReq func(*serverTester), checkReq func(*http.Request)) {
  478. gotReq := make(chan bool, 1)
  479. st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
  480. if r.Body == nil {
  481. t.Fatal("nil Body")
  482. }
  483. checkReq(r)
  484. gotReq <- true
  485. })
  486. defer st.Close()
  487. st.greet()
  488. writeReq(st)
  489. select {
  490. case <-gotReq:
  491. case <-time.After(2 * time.Second):
  492. t.Error("timeout waiting for request")
  493. }
  494. }
  495. func TestServerWithCurl(t *testing.T) {
  496. requireCurl(t)
  497. ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  498. // TODO: add a bunch of different tests with different
  499. // behavior, as a function of r or a table.
  500. // -- with request body, without.
  501. // -- no interaction with w.
  502. // -- panic
  503. // -- modify Header only, but no writes or writeheader (this test)
  504. // -- WriteHeader only
  505. // -- Write only
  506. // -- WriteString
  507. // -- both
  508. // -- huge headers over a frame size so we get continuation headers.
  509. // Look at net/http's Server tests for inspiration.
  510. w.Header().Set("Foo", "Bar")
  511. }))
  512. ConfigureServer(ts.Config, &Server{})
  513. ts.TLS = ts.Config.TLSConfig // the httptest.Server has its own copy of this TLS config
  514. ts.StartTLS()
  515. defer ts.Close()
  516. var gotConn int32
  517. testHookOnConn = func() { atomic.StoreInt32(&gotConn, 1) }
  518. t.Logf("Running test server for curl to hit at: %s", ts.URL)
  519. container := curl(t, "--silent", "--http2", "--insecure", "-v", ts.URL)
  520. defer kill(container)
  521. resc := make(chan interface{}, 1)
  522. go func() {
  523. res, err := dockerLogs(container)
  524. if err != nil {
  525. resc <- err
  526. } else {
  527. resc <- res
  528. }
  529. }()
  530. select {
  531. case res := <-resc:
  532. if err, ok := res.(error); ok {
  533. t.Fatal(err)
  534. }
  535. if !strings.Contains(string(res.([]byte)), "< foo:Bar") {
  536. t.Errorf("didn't see foo:Bar header")
  537. t.Logf("Got: %s", res)
  538. }
  539. case <-time.After(3 * time.Second):
  540. t.Errorf("timeout waiting for curl")
  541. }
  542. if atomic.LoadInt32(&gotConn) == 0 {
  543. t.Error("never saw an http2 connection")
  544. }
  545. }
  546. func dockerLogs(container string) ([]byte, error) {
  547. out, err := exec.Command("docker", "wait", container).CombinedOutput()
  548. if err != nil {
  549. return out, err
  550. }
  551. exitStatus, err := strconv.Atoi(strings.TrimSpace(string(out)))
  552. if err != nil {
  553. return out, errors.New("unexpected exit status from docker wait")
  554. }
  555. out, err = exec.Command("docker", "logs", container).CombinedOutput()
  556. exec.Command("docker", "rm", container).Run()
  557. if err == nil && exitStatus != 0 {
  558. err = fmt.Errorf("exit status %d", exitStatus)
  559. }
  560. return out, err
  561. }
  562. func kill(container string) {
  563. exec.Command("docker", "kill", container).Run()
  564. exec.Command("docker", "rm", container).Run()
  565. }
  566. // Verify that curl has http2.
  567. func requireCurl(t *testing.T) {
  568. out, err := dockerLogs(curl(t, "--version"))
  569. if err != nil {
  570. t.Skipf("failed to determine curl features; skipping test")
  571. }
  572. if !strings.Contains(string(out), "HTTP2") {
  573. t.Skip("curl doesn't support HTTP2; skipping test")
  574. }
  575. }
  576. func curl(t *testing.T, args ...string) (container string) {
  577. out, err := exec.Command("docker", append([]string{"run", "-d", "--net=host", "gohttp2/curl"}, args...)...).CombinedOutput()
  578. if err != nil {
  579. t.Skipf("Failed to run curl in docker: %v, %s", err, out)
  580. }
  581. return strings.TrimSpace(string(out))
  582. }
  583. type twriter struct {
  584. t testing.TB
  585. }
  586. func (w twriter) Write(p []byte) (n int, err error) {
  587. w.t.Logf("%s", p)
  588. return len(p), nil
  589. }
  590. // encodeHeader encodes headers and returns their HPACK bytes. headers
  591. // must contain an even number of key/value pairs. There may be
  592. // multiple pairs for keys (e.g. "cookie"). The :method, :path, and
  593. // :scheme headers default to GET, / and https.
  594. func encodeHeader(t *testing.T, headers ...string) []byte {
  595. pseudoCount := map[string]int{}
  596. if len(headers)%2 == 1 {
  597. panic("odd number of kv args")
  598. }
  599. keys := []string{":method", ":path", ":scheme"}
  600. vals := map[string][]string{
  601. ":method": {"GET"},
  602. ":path": {"/"},
  603. ":scheme": {"https"},
  604. }
  605. for len(headers) > 0 {
  606. k, v := headers[0], headers[1]
  607. headers = headers[2:]
  608. if _, ok := vals[k]; !ok {
  609. keys = append(keys, k)
  610. }
  611. if strings.HasPrefix(k, ":") {
  612. pseudoCount[k]++
  613. if pseudoCount[k] == 1 {
  614. vals[k] = []string{v}
  615. } else {
  616. // Allows testing of invalid headers w/ dup pseudo fields.
  617. vals[k] = append(vals[k], v)
  618. }
  619. } else {
  620. vals[k] = append(vals[k], v)
  621. }
  622. }
  623. var buf bytes.Buffer
  624. enc := hpack.NewEncoder(&buf)
  625. for _, k := range keys {
  626. for _, v := range vals[k] {
  627. if err := enc.WriteField(hpack.HeaderField{Name: k, Value: v}); err != nil {
  628. t.Fatalf("HPACK encoding error for %q/%q: %v", k, v, err)
  629. }
  630. }
  631. }
  632. return buf.Bytes()
  633. }