Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file.
36 changes: 36 additions & 0 deletions test/modules/session/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import logging
import os

import pytest
import sys

from .env import SessionTestEnv
from pyhttpd.env import HttpdTestEnv

sys.path.append(os.path.join(os.path.dirname(__file__), '../..'))


def pytest_report_header(config, start_path):
env = SessionTestEnv()
return f"mod_session [apache: {env.get_httpd_version()}, mpm: {env.mpm_module}, {env.prefix}]"


@pytest.fixture(scope="package")
def env(pytestconfig) -> SessionTestEnv:
level = logging.INFO
console = logging.StreamHandler()
console.setLevel(level)
console.setFormatter(logging.Formatter('%(levelname)s: %(message)s'))
logging.getLogger('').addHandler(console)
logging.getLogger('').setLevel(level=level)
env = SessionTestEnv(pytestconfig=pytestconfig)
env.setup_httpd()
env.apache_access_log_clear()
env.httpd_error_log.clear_log()
return env


@pytest.fixture(autouse=True, scope="package")
def _stop_package_scope(env):
yield
assert env.apache_stop() == 0
24 changes: 24 additions & 0 deletions test/modules/session/env.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import inspect
import logging
import os

from pyhttpd.env import HttpdTestEnv, HttpdTestSetup

log = logging.getLogger(__name__)


class SessionTestSetup(HttpdTestSetup):

def __init__(self, env: 'HttpdTestEnv'):
super().__init__(env=env)
self.add_source_dir(os.path.dirname(inspect.getfile(SessionTestSetup)))
self.add_modules(["cgid", "session", "session_cookie"])


class SessionTestEnv(HttpdTestEnv):

def __init__(self, pytestconfig=None):
super().__init__(pytestconfig=pytestconfig)

def setup_httpd(self, setup: HttpdTestSetup = None):
super().setup_httpd(setup=SessionTestSetup(env=self))
10 changes: 10 additions & 0 deletions test/modules/session/htdocs/test1/cgi/session.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env python3

import os

print("Content-Type: text/plain")
print("X-Replace-Session: key1=foo&key2=&key3=bar")
print()

for key, value in sorted(os.environ.items()):
print(f"{key}={value}")
61 changes: 61 additions & 0 deletions test/modules/session/test_001_session_expiry.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import os
import re
import time
import pytest

from pyhttpd.conf import HttpdConf


class TestSessionExpiry:
@pytest.fixture(autouse=True, scope='class')
def _class_scope(self, env):
cgi_dir = os.path.join(env.server_dir, "htdocs", "test1", "cgi")
conf = HttpdConf(env, extras={
f"test1.{env.http_tld}": f"""
<Directory "{cgi_dir}">
Options +ExecCGI
AddHandler cgi-script .py
</Directory>
<Location />
Session On
SessionEnv On
SessionCookieName session path=/
SessionHeader X-Replace-Session
SessionMaxAge 5
</Location>
""",
})
conf.add_vhost_test1()
conf.install()
assert env.apache_restart() == 0

def test_session_001_01(self, env):
unix_time = int(time.time())
url = env.mkurl("http", "test1", "/cgi/session.py")
r = env.curl_raw(url, options=[
'--cookie', f'session=key1=foo&key3=bar&expiry={unix_time}',
])
assert r.exit_code == 0
body = r.stdout if r.stdout else ""
assert "HTTP_SESSION=expiry=" in body, \
f"Expected expired session output, got: {body}"
assert "HTTP_SESSION=key1=foo&key3=bar&expiry=" not in body, \
"Expired session data should not pass through to CGI"

def test_session_001_02(self, env):
start_pos = env.httpd_error_log.current_pos()
unix_time = int(time.time())
url = env.mkurl("http", "test1", "/cgi/session.py")
r = env.curl_raw(url, options=[
'-j', '--cookie', f'session=key1=foo&=&expiry={unix_time}',
])
assert r.exit_code == 0
crash = env.httpd_error_log.wait_for(
re.compile(r'.*exit signal Segmentation fault.*'),
start_pos, timeout=3)
assert not crash, "Empty session key should not cause a segfault"
body = r.stdout if r.stdout else ""
assert "HTTP_SESSION=expiry=" in body, \
f"Expected session output, got: {body}"
assert "HTTP_SESSION=key1=foo&expiry=" not in body, \
"Session data with empty key should not leak through"