v / vlib / net / http / h2_client_test.v
107 lines · 98 sloc · 3.7 KB · 5d739b1b1ac7ec2625d864cbb17d758c6c92f8bc
Raw
1module http
2
3// Tests for the HTTP/2 <-> net.http conversion glue (h2_client.v). The
4// request/response conversions are pure and need no socket; the end-to-end
5// fetch test is opt-in and network-dependent.
6
7fn test_to_h2_request_pseudo_headers_and_body() {
8 req := Request{
9 user_agent: 'v.http'
10 }
11 h2req := req.to_h2_request(.post, 'example.com', '/p?q=1', 'hello', new_header())
12 assert h2req.method == 'POST'
13 assert h2req.scheme == 'https'
14 assert h2req.authority == 'example.com'
15 assert h2req.path == '/p?q=1'
16 assert h2req.body.bytestr() == 'hello'
17 // user-agent (from the request) and a synthesized content-length.
18 assert h2req.headers.any(it.name == 'user-agent' && it.value == 'v.http')
19 assert h2req.headers.any(it.name == 'content-length' && it.value == '5')
20}
21
22fn test_to_h2_request_lowercases_and_keeps_custom_headers() {
23 mut h := new_header()
24 h.add_custom('Accept', 'application/json') or {}
25 h.add(.content_type, 'text/plain')
26 req := Request{}
27 h2req := req.to_h2_request(.get, 'h.example', '/', '', h)
28 assert h2req.headers.any(it.name == 'accept' && it.value == 'application/json')
29 assert h2req.headers.any(it.name == 'content-type' && it.value == 'text/plain')
30}
31
32fn test_to_h2_request_strips_hop_by_hop_and_host() {
33 mut h := new_header()
34 h.add(.connection, 'keep-alive')
35 h.add(.host, 'example.com')
36 h.add_custom('Transfer-Encoding', 'chunked') or {}
37 req := Request{}
38 h2req := req.to_h2_request(.get, 'example.com', '/', '', h)
39 assert !h2req.headers.any(it.name == 'connection')
40 assert !h2req.headers.any(it.name == 'host')
41 assert !h2req.headers.any(it.name == 'transfer-encoding')
42}
43
44fn test_to_h2_request_collapses_cookies() {
45 mut h := new_header()
46 h.add(.cookie, 'a=1')
47 req := Request{
48 cookies: {
49 'sid': 'abc'
50 }
51 }
52 h2req := req.to_h2_request(.get, 'h.example', '/', '', h)
53 cookie := h2req.headers.filter(it.name == 'cookie')
54 assert cookie.len == 1
55 // Both the request cookie map and the Cookie header value are present.
56 assert cookie[0].value.contains('sid=abc')
57 assert cookie[0].value.contains('a=1')
58}
59
60fn test_h2_response_to_http() {
61 h2resp := H2ClientResponse{
62 status: 200
63 headers: [H2HeaderField{'content-type', 'text/plain'},
64 H2HeaderField{'x-foo', 'bar'}]
65 body: 'hi'.bytes()
66 }
67 resp := h2_response_to_http(h2resp)
68 assert resp.status_code == 200
69 assert resp.http_version == '2.0'
70 assert resp.version() == .v2_0
71 assert resp.body == 'hi'
72 assert (resp.header.get_custom('content-type') or { '' }) == 'text/plain'
73 assert (resp.header.get_custom('x-foo') or { '' }) == 'bar'
74}
75
76fn test_h2_authority_omits_default_port() {
77 assert h2_authority('example.com', 443) == 'example.com'
78 assert h2_authority('example.com', 0) == 'example.com'
79 assert h2_authority('example.com', 8443) == 'example.com:8443'
80}
81
82// End-to-end test against a real HTTP/2 server. Run with `-d network`,
83// e.g. `v -d network test vlib/net/http/h2_client_test.v`.
84fn test_http2_fetch_real_server() {
85 $if !network ? {
86 return
87 }
88 // HTTP/2 is negotiated by default for https requests. On Windows this runs
89 // over the SChannel backend's ALPN + HTTP/2 path (vlang/v#27383).
90 resp := get('https://www.google.com/')!
91 assert resp.version() == .v2_0
92 assert resp.status_code == 200
93 assert resp.body.len > 0
94 // Opting out forces HTTP/1.1 against the same server.
95 plain := fetch(url: 'https://www.google.com/', enable_http2: false)!
96 assert plain.version() == .v1_1
97}
98
99fn test_to_h2_request_authority_from_host_header() {
100 mut h := new_header()
101 h.add(.host, 'override.example:8443')
102 req := Request{}
103 // The URL host is origin.example, but an explicit Host header must win.
104 h2req := req.to_h2_request(.get, 'origin.example', '/', '', h)
105 assert h2req.authority == 'override.example:8443'
106 assert !h2req.headers.any(it.name == 'host')
107}
108