1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
|
import os
import pytest
from .env import H2Conf, H2TestEnv
# The push tests depend on "nghttp"
@pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here")
class TestPush:
@pytest.fixture(autouse=True, scope='class')
def _class_scope(self, env):
H2Conf(env).start_vhost(domains=[f"push.{env.http_tld}"],
port=env.https_port, doc_root="htdocs/test1"
).add(r"""
RewriteEngine on
RewriteRule ^/006-push(.*)?\.html$ /006.html
<Location /006-push.html>
Header add Link "</006/006.css>;rel=preload"
Header add Link "</006/006.js>;rel=preloadX"
</Location>
<Location /006-push2.html>
Header add Link "</006/006.css>;rel=preloadX, </006/006.js>; rel=preload"
</Location>
<Location /006-push3.html>
Header add Link "</006/006.css>;rel=preloa,</006/006.js>;rel=preload"
</Location>
<Location /006-push4.html>
Header add Link "</006/006.css;rel=preload, </006/006.js>; preload"
</Location>
<Location /006-push5.html>
Header add Link '</006/006.css>;rel="preload push"'
</Location>
<Location /006-push6.html>
Header add Link '</006/006.css>;rel="push preload"'
</Location>
<Location /006-push7.html>
Header add Link '</006/006.css>;rel="abc preload push"'
</Location>
<Location /006-push8.html>
Header add Link '</006/006.css>;rel="preload"; nopush'
</Location>
<Location /006-push20.html>
H2PushResource "/006/006.css" critical
H2PushResource "/006/006.js"
</Location>
<Location /006-push30.html>
H2Push off
Header add Link '</006/006.css>;rel="preload"'
</Location>
<Location /006-push31.html>
H2PushResource "/006/006.css" critical
</Location>
<Location /006-push32.html>
Header add Link "</006/006.css>;rel=preload"
</Location>
""").end_vhost(
).install()
assert env.apache_restart() == 0
############################
# Link: header handling, various combinations
# plain resource without configured pushes
def test_h2_400_00(self, env):
url = env.mkurl("https", "push", "/006.html")
r = env.nghttp().get(url)
assert r.response["status"] == 200
promises = r.results["streams"][r.response["id"]]["promises"]
assert 0 == len(promises)
# 2 link headers configured, only 1 triggers push
def test_h2_400_01(self, env):
url = env.mkurl("https", "push", "/006-push.html")
r = env.nghttp().get(url, options=["-Haccept-encoding: none"])
assert r.response["status"] == 200
promises = r.results["streams"][r.response["id"]]["promises"]
assert 1 == len(promises)
assert '/006/006.css' == promises[0]["request"]["header"][":path"]
assert 216 == len(promises[0]["response"]["body"])
# Same as 400_01, but with single header line configured
def test_h2_400_02(self, env):
url = env.mkurl("https", "push", "/006-push2.html")
r = env.nghttp().get(url)
assert r.response["status"] == 200
promises = r.results["streams"][r.response["id"]]["promises"]
assert 1 == len(promises)
assert '/006/006.js' == promises[0]["request"]["header"][":path"]
# 2 Links, only one with correct rel attribute
def test_h2_400_03(self, env):
url = env.mkurl("https", "push", "/006-push3.html")
r = env.nghttp().get(url)
assert r.response["status"] == 200
promises = r.results["streams"][r.response["id"]]["promises"]
assert 1 == len(promises)
assert '/006/006.js' == promises[0]["request"]["header"][":path"]
# Missing > in Link header, PUSH not triggered
def test_h2_400_04(self, env):
url = env.mkurl("https", "push", "/006-push4.html")
r = env.nghttp().get(url)
assert r.response["status"] == 200
promises = r.results["streams"][r.response["id"]]["promises"]
assert 0 == len(promises)
# More than one value in "rel" parameter
def test_h2_400_05(self, env):
url = env.mkurl("https", "push", "/006-push5.html")
r = env.nghttp().get(url)
assert r.response["status"] == 200
promises = r.results["streams"][r.response["id"]]["promises"]
assert 1 == len(promises)
assert '/006/006.css' == promises[0]["request"]["header"][":path"]
# Another "rel" parameter variation
def test_h2_400_06(self, env):
url = env.mkurl("https", "push", "/006-push6.html")
r = env.nghttp().get(url)
assert r.response["status"] == 200
promises = r.results["streams"][r.response["id"]]["promises"]
assert 1 == len(promises)
assert '/006/006.css' == promises[0]["request"]["header"][":path"]
# Another "rel" parameter variation
def test_h2_400_07(self, env):
url = env.mkurl("https", "push", "/006-push7.html")
r = env.nghttp().get(url)
assert r.response["status"] == 200
promises = r.results["streams"][r.response["id"]]["promises"]
assert 1 == len(promises)
assert '/006/006.css' == promises[0]["request"]["header"][":path"]
# Pushable link header with "nopush" attribute
def test_h2_400_08(self, env):
url = env.mkurl("https", "push", "/006-push8.html")
r = env.nghttp().get(url)
assert r.response["status"] == 200
promises = r.results["streams"][r.response["id"]]["promises"]
assert 0 == len(promises)
# 2 H2PushResource config trigger on GET, but not on POST
def test_h2_400_20(self, env):
url = env.mkurl("https", "push", "/006-push20.html")
r = env.nghttp().get(url)
assert r.response["status"] == 200
promises = r.results["streams"][r.response["id"]]["promises"]
assert 2 == len(promises)
fpath = os.path.join(env.gen_dir, "data-400-20")
with open(fpath, 'w') as f:
f.write("test upload data")
r = env.nghttp().upload(url, fpath)
assert r.response["status"] == 200
promises = r.results["streams"][r.response["id"]]["promises"]
assert 0 == len(promises)
# H2Push configured Off in location
def test_h2_400_30(self, env):
url = env.mkurl("https", "push", "/006-push30.html")
r = env.nghttp().get(url)
assert r.response["status"] == 200
promises = r.results["streams"][r.response["id"]]["promises"]
assert 0 == len(promises)
# - suppress PUSH
def test_h2_400_50(self, env):
url = env.mkurl("https", "push", "/006-push.html")
r = env.nghttp().get(url, options=['-H', 'accept-push-policy: none'])
assert r.response["status"] == 200
promises = r.results["streams"][r.response["id"]]["promises"]
assert 0 == len(promises)
# - default pushes desired
def test_h2_400_51(self, env):
url = env.mkurl("https", "push", "/006-push.html")
r = env.nghttp().get(url, options=['-H', 'accept-push-policy: default'])
assert r.response["status"] == 200
promises = r.results["streams"][r.response["id"]]["promises"]
assert 1 == len(promises)
# - HEAD pushes desired
def test_h2_400_52(self, env):
url = env.mkurl("https", "push", "/006-push.html")
r = env.nghttp().get(url, options=['-H', 'accept-push-policy: head'])
assert r.response["status"] == 200
promises = r.results["streams"][r.response["id"]]["promises"]
assert 1 == len(promises)
assert '/006/006.css' == promises[0]["request"]["header"][":path"]
assert b"" == promises[0]["response"]["body"]
assert 0 == len(promises[0]["response"]["body"])
# - fast-load pushes desired
def test_h2_400_53(self, env):
url = env.mkurl("https", "push", "/006-push.html")
r = env.nghttp().get(url, options=['-H', 'accept-push-policy: fast-load'])
assert r.response["status"] == 200
promises = r.results["streams"][r.response["id"]]["promises"]
assert 1 == len(promises)
|