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)
|