add a httpheader source

see #175 for use cases.
This commit is contained in:
lilydjwg 2021-01-28 18:05:58 +08:00
parent 9c2d2a39d7
commit 305c329e02
4 changed files with 81 additions and 1 deletions

View File

@ -235,6 +235,34 @@ regex
This source supports :ref:`list options`.
Search in an HTTP header
~~~~~~~~~~~~~~~~~~~~~~~~
::
source = "httpheader"
Send an HTTP request and search through a specific header.
url
The URL of the HTTP request.
header
(*Optional*) The header to look at. Default is ``Location``. Another useful header is ``Content-Disposition``.
regex
A regular expression used to find the version string.
It can have zero or one capture group. The capture group or the whole match is the version string.
When multiple version strings are found, the maximum of those is chosen.
method
(*Optional*) The HTTP method to use. Default is ``HEAD``.
follow_redirects
(*Optional*) Whether to follow 3xx HTTP redirects. Default is ``false``. If you are looking at a ``Location`` header, you shouldn't change this.
Find with a Command
~~~~~~~~~~~~~~~~~~~
::

View File

@ -0,0 +1,39 @@
# MIT licensed
# Copyright (c) 2021 lilydjwg <lilydjwg@gmail.com>, et al.
import re
import sre_constants
from nvchecker.api import session, GetVersionError
async def get_version(name, conf, *, cache, **kwargs):
key = tuple(sorted(conf.items()))
return await cache.get(key, get_version_impl)
async def get_version_impl(info):
conf = dict(info)
url = conf['url']
header = conf.get('header', 'Location')
follow_redirects = conf.get('follow_redirects', False)
method = conf.get('method', 'HEAD')
try:
regex = re.compile(conf['regex'])
except sre_constants.error as e:
raise GetVersionError('bad regex', exc_info=e)
res = await session.request(
url,
method = method,
follow_redirects = follow_redirects,
)
header_value = res.headers.get(header)
if not header_value:
raise GetVersionError('header %s not found or is empty' % header)
try:
version = regex.findall(header_value)
except ValueError:
raise GetVersionError('version string not found.')
return version

View File

@ -25,7 +25,6 @@ async def get_version_impl(info):
try:
version = regex.findall(body)
except ValueError:
version = None
if not conf.get('missing_ok', False):
raise GetVersionError('version string not found.')
return version

14
tests/test_httpheader.py Normal file
View File

@ -0,0 +1,14 @@
# MIT licensed
# Copyright (c) 2021 lilydjwg <lilydjwg@gmail.com>, et al.
import pytest
pytestmark = pytest.mark.asyncio
async def test_redirection(get_version):
assert await get_version("jmeter-plugins-manager", {
"source": "httpheader",
"url": "https://jmeter-plugins.org/get/",
"regex": r'/([\d.]+)/',
}) == "1.6"