From 168d17f0d5ac00d0d6b99fc41b484c61f5b218b5c70e55bb0c0a7addc17cf5b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20S=C3=BAkup?= Date: Thu, 19 Oct 2023 10:27:36 +0000 Subject: [PATCH 1/2] Accepting request 1118866 from home:mcalabkova:branches:devel:languages:python - Repackage, new active upstream * In their words: We were unable to get ahold of the folks at postmanlabs to maintain the original project, and httpbin is used for other packages within the python ecosystem, such as pytest-httpbin which is in turn used by packages such as requests so we have forked this package. That means that httpbin.org is not actually backed by this repo, but the httpbin package is. Confusing right? * Drop now unneeded _service, changes in the *spec - Update to 0.10.1 * Override docker image port with HTTPBIN_PORT * A number of fixes for code rot, thanks @mgorny and @tjni - Drop upstreamed/no-longer-needed patches: * fix-setup-py.patch * httpbin-pr674-wekzeug2.1.patch * werkzeug.patch * support-werkzeug-2.3.patch - Add flask3.patch to support Flask 3.0 OBS-URL: https://build.opensuse.org/request/show/1118866 OBS-URL: https://build.opensuse.org/package/show/devel:languages:python/python-httpbin?expand=0&rev=27 --- _service | 14 --- fix-setup-py.patch | 14 --- flask3.patch | 109 ++++++++++++++++++ httpbin-0.10.1.tar.gz | 3 + httpbin-pr674-wekzeug2.1.patch | 32 ----- ...n-httpbin-0.7.0+git20181107.f8ec666.tar.xz | 3 - python-httpbin.changes | 21 ++++ python-httpbin.spec | 42 +++---- support-werkzeug-2.3.patch | 40 ------- werkzeug.patch | 34 ------ 10 files changed, 149 insertions(+), 163 deletions(-) delete mode 100644 _service delete mode 100644 fix-setup-py.patch create mode 100644 flask3.patch create mode 100644 httpbin-0.10.1.tar.gz delete mode 100644 httpbin-pr674-wekzeug2.1.patch delete mode 100644 python-httpbin-0.7.0+git20181107.f8ec666.tar.xz delete mode 100644 support-werkzeug-2.3.patch delete mode 100644 werkzeug.patch diff --git a/_service b/_service deleted file mode 100644 index 23914e1..0000000 --- a/_service +++ /dev/null @@ -1,14 +0,0 @@ - - - python-httpbin - https://github.com/postmanlabs/httpbin.git - git - enable - 0.7.0+git%cd.%h - - - xz - *.tar - - - diff --git a/fix-setup-py.patch b/fix-setup-py.patch deleted file mode 100644 index e81092f..0000000 --- a/fix-setup-py.patch +++ /dev/null @@ -1,14 +0,0 @@ -Index: python-httpbin-0.7.0+git20181107.f8ec666/setup.py -=================================================================== ---- python-httpbin-0.7.0+git20181107.f8ec666.orig/setup.py -+++ python-httpbin-0.7.0+git20181107.f8ec666/setup.py -@@ -35,7 +35,7 @@ setup( - packages=find_packages(), - include_package_data = True, # include files listed in MANIFEST.in - install_requires=[ -- 'Flask', 'MarkupSafe', 'decorator', 'itsdangerous', 'six', 'brotlipy', -- 'raven[flask]', 'werkzeug>=0.14.1', 'gevent', 'flasgger' -+ 'Flask>=2.1', 'MarkupSafe', 'decorator', 'itsdangerous', 'six', 'brotli', -+ 'werkzeug>=2.0', 'gevent', 'flasgger' - ], - ) diff --git a/flask3.patch b/flask3.patch new file mode 100644 index 0000000..24ab8c8 --- /dev/null +++ b/flask3.patch @@ -0,0 +1,109 @@ +From c1d9e33049263fed3cb27806a97f094acc350905 Mon Sep 17 00:00:00 2001 +From: Nate Prewitt +Date: Thu, 12 Oct 2023 08:30:42 -0700 +Subject: [PATCH] Support Flask 3.0 (#29) + +--- + httpbin/core.py | 8 +++----- + httpbin/helpers.py | 21 ++++++++++++++++----- + pyproject.toml | 3 +-- + 3 files changed, 20 insertions(+), 12 deletions(-) + +diff --git a/httpbin/core.py b/httpbin/core.py +index 5c1783a1..a82c1b88 100644 +--- a/httpbin/core.py ++++ b/httpbin/core.py +@@ -32,7 +32,7 @@ + from werkzeug.wrappers import Response + except ImportError: # werkzeug < 2.1 + from werkzeug.wrappers import BaseResponse as Response +-from werkzeug.http import parse_authorization_header ++ + from flasgger import Swagger, NO_SANITIZER + + from . import filters +@@ -47,6 +47,7 @@ + H, + ROBOT_TXT, + ANGRY_ASCII, ++ parse_authorization_header, + parse_multi_value_header, + next_stale_after_value, + digest_challenge_response, +@@ -636,16 +637,13 @@ def redirect_to(): + args_dict = request.args.items() + args = CaseInsensitiveDict(args_dict) + +- # We need to build the response manually and convert to UTF-8 to prevent +- # werkzeug from "fixing" the URL. This endpoint should set the Location +- # header to the exact string supplied. + response = app.make_response("") + response.status_code = 302 + if "status_code" in args: + status_code = int(args["status_code"]) + if status_code >= 300 and status_code < 400: + response.status_code = status_code +- response.headers["Location"] = args["url"].encode("utf-8") ++ response.headers["Location"] = args["url"] + + return response + +diff --git a/httpbin/helpers.py b/httpbin/helpers.py +index b29e1835..836c8026 100644 +--- a/httpbin/helpers.py ++++ b/httpbin/helpers.py +@@ -13,8 +13,14 @@ + import time + import os + from hashlib import md5, sha256, sha512 +-from werkzeug.http import parse_authorization_header + from werkzeug.datastructures import WWWAuthenticate ++from werkzeug.http import dump_header ++ ++try: ++ from werkzeug.http import parse_authorization_header ++except ImportError: # werkzeug < 2.3 ++ from werkzeug.datastructures import Authorization ++ parse_authorization_header = Authorization.from_header + + from flask import request, make_response + from six.moves.urllib.parse import urlparse, urlunparse +@@ -466,9 +472,14 @@ def digest_challenge_response(app, qop, algorithm, stale = False): + ]), algorithm) + opaque = H(os.urandom(10), algorithm) + +- auth = WWWAuthenticate("digest") +- auth.set_digest('me@kennethreitz.com', nonce, opaque=opaque, +- qop=('auth', 'auth-int') if qop is None else (qop,), algorithm=algorithm) +- auth.stale = stale ++ values = { ++ 'realm': 'me@kennethreitz.com', ++ 'nonce': nonce, ++ 'opaque': opaque, ++ 'qop': dump_header(('auth', 'auth-int') if qop is None else (qop,)), ++ 'algorithm': algorithm, ++ 'stale': stale, ++ } ++ auth = WWWAuthenticate("digest", values=values) + response.headers['WWW-Authenticate'] = auth.to_header() + return response +diff --git a/pyproject.toml b/pyproject.toml +index 020457ec..9454e569 100644 +--- a/pyproject.toml ++++ b/pyproject.toml +@@ -31,14 +31,13 @@ classifiers = [ + "Programming Language :: Python :: 3.12", + ] + dependencies = [ +- "Flask", ++ "flask >= 2.2.4", + "brotlicffi", + "decorator", + "flasgger", + 'greenlet < 3.0; python_version<"3.12"', + 'greenlet >= 3.0.0a1; python_version>="3.12.0rc0"', + 'importlib-metadata; python_version<"3.8"', +- "werkzeug >= 0.14.1", + "six", + ] + diff --git a/httpbin-0.10.1.tar.gz b/httpbin-0.10.1.tar.gz new file mode 100644 index 0000000..74844d4 --- /dev/null +++ b/httpbin-0.10.1.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7b8596beb0e75a7b653c39d1f3cf263d6d5c476d29e1df6f7bb2b70bf9f06a3d +size 107058 diff --git a/httpbin-pr674-wekzeug2.1.patch b/httpbin-pr674-wekzeug2.1.patch deleted file mode 100644 index 5696f4c..0000000 --- a/httpbin-pr674-wekzeug2.1.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 5cc81ce87a3c447a127e4a1a707faf9f3b1c9b6b Mon Sep 17 00:00:00 2001 -From: Maximino BOGADO -Date: Wed, 30 Mar 2022 16:26:31 +0200 -Subject: [PATCH] Replace BaseResponse to Response class (new werkzeug version - 2.1.0) - ---- - httpbin/core.py | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/httpbin/core.py b/httpbin/core.py -index 305c9882..2bad408e 100644 ---- a/httpbin/core.py -+++ b/httpbin/core.py -@@ -29,7 +29,7 @@ - from six.moves import range as xrange - from werkzeug.datastructures import WWWAuthenticate, MultiDict - from werkzeug.http import http_date --from werkzeug.wrappers import BaseResponse -+from werkzeug.wrappers import Response - from werkzeug.http import parse_authorization_header - from flasgger import Swagger, NO_SANITIZER - -@@ -77,7 +77,7 @@ def jsonify(*args, **kwargs): - - - # Prevent WSGI from correcting the casing of the Location header --BaseResponse.autocorrect_location_header = False -+Response.autocorrect_location_header = False - - # Find the correct template folder when running from a different location - tmpl_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "templates") diff --git a/python-httpbin-0.7.0+git20181107.f8ec666.tar.xz b/python-httpbin-0.7.0+git20181107.f8ec666.tar.xz deleted file mode 100644 index fa67ec8..0000000 --- a/python-httpbin-0.7.0+git20181107.f8ec666.tar.xz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6ca690b5d5d0b1e75a947559663400492c48be4713502f9466da658d4270f638 -size 98088 diff --git a/python-httpbin.changes b/python-httpbin.changes index 2e25630..50f183e 100644 --- a/python-httpbin.changes +++ b/python-httpbin.changes @@ -1,3 +1,24 @@ +------------------------------------------------------------------- +Thu Oct 19 08:11:44 UTC 2023 - Markéta Machová + +- Repackage, new active upstream + * In their words: We were unable to get ahold of the folks at postmanlabs to + maintain the original project, and httpbin is used for other packages + within the python ecosystem, such as pytest-httpbin which is in turn used + by packages such as requests so we have forked this package. That means + that httpbin.org is not actually backed by this repo, but the httpbin + package is. Confusing right? + * Drop now unneeded _service, changes in the *spec +- Update to 0.10.1 + * Override docker image port with HTTPBIN_PORT + * A number of fixes for code rot, thanks @mgorny and @tjni +- Drop upstreamed/no-longer-needed patches: + * fix-setup-py.patch + * httpbin-pr674-wekzeug2.1.patch + * werkzeug.patch + * support-werkzeug-2.3.patch +- Add flask3.patch to support Flask 3.0 + ------------------------------------------------------------------- Wed Jun 21 08:35:31 UTC 2023 - Steve Kowalik diff --git a/python-httpbin.spec b/python-httpbin.spec index 60bf3a3..5d28db7 100644 --- a/python-httpbin.spec +++ b/python-httpbin.spec @@ -16,44 +16,35 @@ # -# The PyPI version is 0.7.0 but the metadata reads an internal file with version 0.9.2 -%define internalversion 0.9.2 +%define modname httpbin %{?sle15_python_module_pythons} Name: python-httpbin -Version: 0.7.0+git20181107.f8ec666 +Version: 0.10.1 Release: 0 Summary: HTTP Request and Response Service License: MIT -URL: https://github.com/Runscope/httpbin -Source: python-httpbin-%{version}.tar.xz -# PATCH-FIX-UPSTREAM werkzeug.patch -- gh#postmanlabs/httpbin#555 -Patch0: werkzeug.patch -# PATCH-FIX-UPSTREAM fix-setup-py.patch -- gh#postmanlabs/httpbin#553 -Patch1: fix-setup-py.patch -# PATCH-FIX-UPSTREAM httpbin-pr674-wekzeug2.1.patch -- gh#postmanlabs/httpbin#674 -Patch2: httpbin-pr674-wekzeug2.1.patch -# PATCH-FIX-OPENSUSE Support Werkzeug >= 2.3 -Patch3: support-werkzeug-2.3.patch -BuildRequires: %{python_module Brotli} -BuildRequires: %{python_module Flask >= 2.1} -BuildRequires: %{python_module MarkupSafe} +URL: https://github.com/psf/httpbin +Source: https://files.pythonhosted.org/packages/source/h/%{modname}/%{modname}-%{version}.tar.gz +# PATCH-FIX-UPSTREAM https://github.com/psf/httpbin/pull/29 Support Flask 3.0 +Patch: flask3.patch +BuildRequires: %{python_module Flask >= 2.2.4} BuildRequires: %{python_module Werkzeug >= 2.0} +BuildRequires: %{python_module brotlicffi} BuildRequires: %{python_module decorator} BuildRequires: %{python_module flasgger} BuildRequires: %{python_module gevent} -BuildRequires: %{python_module itsdangerous} +BuildRequires: %{python_module pip} BuildRequires: %{python_module pytest} BuildRequires: %{python_module setuptools} +BuildRequires: %{python_module wheel} BuildRequires: fdupes BuildRequires: python-rpm-macros -Requires: python-Brotli -Requires: python-Flask >= 2.1 -Requires: python-MarkupSafe +Requires: python-Flask >= 2.2.4 Requires: python-Werkzeug >= 2.0 +Requires: python-brotlicffi Requires: python-decorator Requires: python-flasgger Requires: python-gevent -Requires: python-itsdangerous Requires: python-six BuildArch: noarch %python_subpackages @@ -69,16 +60,15 @@ all kinds of HTTP scenarios. Additional endpoints are being considered. All endpoint responses are JSON-encoded. %prep -%autosetup -p1 -chmod -x httpbin/templates/forms-post.html +%autosetup -p1 -n %{modname}-%{version} %build export LANG=en_US.UTF-8 -%python_build +%pyproject_wheel %install export LANG=en_US.UTF-8 -%python_install +%pyproject_install %python_expand %fdupes %{buildroot}%{$python_sitelib} %check @@ -88,6 +78,6 @@ export LANG=en_US.UTF-8 %doc README.md %license LICENSE %{python_sitelib}/httpbin -%{python_sitelib}/httpbin-%{internalversion}*-info +%{python_sitelib}/httpbin-%{version}*-info %changelog diff --git a/support-werkzeug-2.3.patch b/support-werkzeug-2.3.patch deleted file mode 100644 index db72fdf..0000000 --- a/support-werkzeug-2.3.patch +++ /dev/null @@ -1,40 +0,0 @@ -Index: python-httpbin-0.7.0+git20181107.f8ec666/test_httpbin.py -=================================================================== ---- python-httpbin-0.7.0+git20181107.f8ec666.orig/test_httpbin.py -+++ python-httpbin-0.7.0+git20181107.f8ec666/test_httpbin.py -@@ -167,8 +167,8 @@ class HttpbinTestCase(unittest.TestCase) - - def test_base64(self): - greeting = u'Здравствуй, мир!' -- b64_encoded = _string_to_base64(greeting) -- response = self.app.get(b'/base64/' + b64_encoded) -+ b64_encoded = _string_to_base64(greeting).decode('utf-8') -+ response = self.app.get('/base64/' + b64_encoded) - content = response.data.decode('utf-8') - self.assertEqual(greeting, content) - -@@ -422,7 +422,7 @@ class HttpbinTestCase(unittest.TestCase) - body, stale_after + 1) - self.assertEqual(stale_response.status_code, 401) - header = stale_response.headers.get('WWW-Authenticate') -- self.assertIn('stale=TRUE', header) -+ self.assertIn('stale=True', header) - - def _test_digest_response_for_auth_request(self, header, username, password, qop, uri, body, nc=1, nonce=None): - auth_type, auth_info = header.split(None, 1) -@@ -474,13 +474,13 @@ class HttpbinTestCase(unittest.TestCase) - wrong_pass_response, nonce = self._test_digest_response_for_auth_request(header, username, "wrongPassword", qop, uri, body) - self.assertEqual(wrong_pass_response.status_code, 401) - header = wrong_pass_response.headers.get('WWW-Authenticate') -- self.assertNotIn('stale=TRUE', header) -+ self.assertNotIn('stale=True', header) - - reused_nonce_response, nonce = self._test_digest_response_for_auth_request(header, username, password, qop, uri, \ - body, nonce=nonce) - self.assertEqual(reused_nonce_response.status_code, 401) - header = reused_nonce_response.headers.get('WWW-Authenticate') -- self.assertIn('stale=TRUE', header) -+ self.assertIn('stale=True', header) - - def test_drip(self): - response = self.app.get('/drip?numbytes=400&duration=2&delay=1') diff --git a/werkzeug.patch b/werkzeug.patch deleted file mode 100644 index d369db0..0000000 --- a/werkzeug.patch +++ /dev/null @@ -1,34 +0,0 @@ -From b6cb2b47a3813da5df8dbffada284b72d7fe099e Mon Sep 17 00:00:00 2001 -From: Simon Kowallik -Date: Sat, 18 May 2019 13:10:08 +0200 -Subject: [PATCH] fix #554: update tests, Pipfile, Pipfile.lock for - werkzeug>=0.15.1 - -- update test_httpbin.py to reflect new behaviour of werkzeug -- require werkzeug>=0.15.1 ---- - Pipfile | 2 +- - Pipfile.lock | 6 +++--- - test_httpbin.py | 2 -- - 3 files changed, 4 insertions(+), 6 deletions(-) - -Index: python-httpbin-0.7.0+git20181107.f8ec666/test_httpbin.py -=================================================================== ---- python-httpbin-0.7.0+git20181107.f8ec666.orig/test_httpbin.py -+++ python-httpbin-0.7.0+git20181107.f8ec666/test_httpbin.py -@@ -148,7 +148,6 @@ class HttpbinTestCase(unittest.TestCase) - data = json.loads(response.data.decode('utf-8')) - self.assertEqual(data['args'], {}) - self.assertEqual(data['headers']['Host'], 'localhost') -- self.assertEqual(data['headers']['Content-Length'], '0') - self.assertEqual(data['headers']['User-Agent'], 'test') - # self.assertEqual(data['origin'], None) - self.assertEqual(data['url'], 'http://localhost/get') -@@ -162,7 +161,6 @@ class HttpbinTestCase(unittest.TestCase) - data = json.loads(response.data.decode('utf-8')) - self.assertEqual(data['args'], {}) - self.assertEqual(data['headers']['Host'], 'localhost') -- self.assertEqual(data['headers']['Content-Length'], '0') - self.assertEqual(data['url'], 'http://localhost/anything/foo/bar') - self.assertEqual(data['method'], 'GET') - self.assertTrue(response.data.endswith(b'\n')) From ee0105265bcb080ff29d9621d66db7d9c3297070d3587768a22769a0d1c0c968 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mark=C3=A9ta=20Machov=C3=A1?= Date: Tue, 24 Oct 2023 13:34:23 +0000 Subject: [PATCH 2/2] Accepting request 1119998 from home:mcalabkova:branches:devel:languages:python - Use Brotli instead of dropped brotlicffi OBS-URL: https://build.opensuse.org/request/show/1119998 OBS-URL: https://build.opensuse.org/package/show/devel:languages:python/python-httpbin?expand=0&rev=28 --- python-httpbin.changes | 5 +++++ python-httpbin.spec | 6 ++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/python-httpbin.changes b/python-httpbin.changes index 50f183e..1bda103 100644 --- a/python-httpbin.changes +++ b/python-httpbin.changes @@ -1,3 +1,8 @@ +------------------------------------------------------------------- +Tue Oct 24 13:30:26 UTC 2023 - Markéta Machová + +- Use Brotli instead of dropped brotlicffi + ------------------------------------------------------------------- Thu Oct 19 08:11:44 UTC 2023 - Markéta Machová diff --git a/python-httpbin.spec b/python-httpbin.spec index 5d28db7..b88f608 100644 --- a/python-httpbin.spec +++ b/python-httpbin.spec @@ -27,9 +27,9 @@ URL: https://github.com/psf/httpbin Source: https://files.pythonhosted.org/packages/source/h/%{modname}/%{modname}-%{version}.tar.gz # PATCH-FIX-UPSTREAM https://github.com/psf/httpbin/pull/29 Support Flask 3.0 Patch: flask3.patch +BuildRequires: %{python_module Brotli} BuildRequires: %{python_module Flask >= 2.2.4} BuildRequires: %{python_module Werkzeug >= 2.0} -BuildRequires: %{python_module brotlicffi} BuildRequires: %{python_module decorator} BuildRequires: %{python_module flasgger} BuildRequires: %{python_module gevent} @@ -39,9 +39,9 @@ BuildRequires: %{python_module setuptools} BuildRequires: %{python_module wheel} BuildRequires: fdupes BuildRequires: python-rpm-macros +Requires: python-Brotli Requires: python-Flask >= 2.2.4 Requires: python-Werkzeug >= 2.0 -Requires: python-brotlicffi Requires: python-decorator Requires: python-flasgger Requires: python-gevent @@ -61,6 +61,8 @@ All endpoint responses are JSON-encoded. %prep %autosetup -p1 -n %{modname}-%{version} +# we are running CPython, let us use Brotli instead of brotlicffi (they should be compatible) +sed -i 's/brotlicffi/brotli/' httpbin/filters.py %build export LANG=en_US.UTF-8