201 lines
8.1 KiB
Python
201 lines
8.1 KiB
Python
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)
|