Skip to content

Commit

Permalink
Fixes #1118: Add check for HTTP versions (#1241)
Browse files Browse the repository at this point in the history
* Fix #1118: Add check for HTTP version

* Fix 'curl: (48) An unknown option was passed in to libcurl'

* Fix issue not caught in unit tests because of mocking :(

* Remove useless package in container
  • Loading branch information
leplatrem authored May 25, 2023
1 parent a479ea7 commit dbbb4c6
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 1 deletion.
8 changes: 7 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,15 @@ RUN groupadd --gid 10001 app \
&& useradd -m -g app --uid 10001 -s /usr/sbin/nologin app

RUN apt-get update && \
apt-get install --yes build-essential curl && \
apt-get install --yes --no-install-recommends wget build-essential libssl-dev && \
pip install --progress-bar=off -U pip && \
pip install poetry && \
# curl with http3 support
wget https://curl.se/download/curl-8.1.1.tar.gz && \
tar -xvf curl-*.tar.gz && cd curl-* && \
./configure --with-openssl --disable-shared && make && make install && \
cd .. && \
# cleanup
apt-get -q --yes autoremove && \
apt-get clean && \
rm -rf /root/.cache
Expand Down
32 changes: 32 additions & 0 deletions checks/core/http_versions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""
URL should support the specified versions.
"""
import subprocess

from telescope.typings import CheckResult


EXPOSED_PARAMETERS = ["url", "versions"]

CURL_VERSION_FLAGS = ["--http1.0", "--http1.1", "--http2", "--http3"]


async def run(url: str, versions: list[str] = ["1", "1.1", "2", "3"]) -> CheckResult:
supported_versions = set()
for flag in CURL_VERSION_FLAGS:
result = subprocess.run(
["curl", "-sI", flag, url, "-o/dev/null", "-w", "%{http_version}\n"],
capture_output=True,
)
supported_versions.add(result.stdout.strip().decode())

if missing_versions := set(versions).difference(supported_versions):
return False, f"HTTP version(s) {', '.join(missing_versions)} unsupported"

if extra_versions := supported_versions.difference(set(versions)):
return (
False,
f"HTTP version(s) {', '.join(extra_versions)} unexpectedly supported",
)

return True, list(supported_versions)
56 changes: 56 additions & 0 deletions tests/checks/core/test_http_versions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
from unittest import mock

import pytest

from checks.core.http_versions import run


MODULE = "checks.core.http_versions"


@pytest.fixture
def mocked_curl():
with mock.patch(f"{MODULE}.subprocess.run") as mocked_curl:
yield mocked_curl


async def test_positive(mocked_curl):
mocked_curl.side_effect = [
mock.Mock(stdout=b"1\n"),
mock.Mock(stdout=b"1.1\n"),
mock.Mock(stdout=b"2\n"),
mock.Mock(stdout=b"3\n"),
]

status, data = await run("http://server.local")

assert status is True
assert sorted(data) == ["1", "1.1", "2", "3"]


async def test_negative_missing(mocked_curl):
mocked_curl.side_effect = [
mock.Mock(stdout=b"1\n"),
mock.Mock(stdout=b"1.1\n"),
mock.Mock(stdout=b"2\n"),
mock.Mock(stdout=b"2\n"),
]

status, data = await run("http://server.local")

assert status is False
assert data == "HTTP version(s) 3 unsupported"


async def test_negative_extra(mocked_curl):
mocked_curl.side_effect = [
mock.Mock(stdout=b"1\n"),
mock.Mock(stdout=b"1.1\n"),
mock.Mock(stdout=b"2\n"),
mock.Mock(stdout=b"3\n"),
]

status, data = await run("http://server.local", versions=["1", "1.1", "2"])

assert status is False
assert data == "HTTP version(s) 3 unexpectedly supported"

0 comments on commit dbbb4c6

Please sign in to comment.