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'))