aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/pytest-localserver/py3
diff options
context:
space:
mode:
authorrobot-piglet <robot-piglet@yandex-team.com>2025-02-02 10:11:17 +0300
committerrobot-piglet <robot-piglet@yandex-team.com>2025-02-02 10:21:23 +0300
commit637f8bbf610e99859dfbdbde49d99e9c60a7acf7 (patch)
tree3e685433e89f53a34ca2a4635c29865598d12b4f /contrib/python/pytest-localserver/py3
parentbbd3eacdd0520f608b6290efdd0050d7e55ad40d (diff)
downloadydb-637f8bbf610e99859dfbdbde49d99e9c60a7acf7.tar.gz
Intermediate changes
commit_hash:20c3eb2f2d78b5f654ec928c071692413a1bd96d
Diffstat (limited to 'contrib/python/pytest-localserver/py3')
-rw-r--r--contrib/python/pytest-localserver/py3/.dist-info/METADATA14
-rw-r--r--contrib/python/pytest-localserver/py3/AUTHORS3
-rw-r--r--contrib/python/pytest-localserver/py3/README.rst8
-rw-r--r--contrib/python/pytest-localserver/py3/patches/01-arcadia.patch10
-rw-r--r--contrib/python/pytest-localserver/py3/pytest_localserver/_version.py4
-rw-r--r--contrib/python/pytest-localserver/py3/pytest_localserver/cert.crt32
-rw-r--r--contrib/python/pytest-localserver/py3/pytest_localserver/http.py12
-rw-r--r--contrib/python/pytest-localserver/py3/pytest_localserver/https.py25
-rw-r--r--contrib/python/pytest-localserver/py3/pytest_localserver/plugin.py4
-rw-r--r--contrib/python/pytest-localserver/py3/pytest_localserver/server.key (renamed from contrib/python/pytest-localserver/py3/pytest_localserver/server.pem)32
-rw-r--r--contrib/python/pytest-localserver/py3/pytest_localserver/smtp.py12
-rw-r--r--contrib/python/pytest-localserver/py3/tests/test_http.py36
-rw-r--r--contrib/python/pytest-localserver/py3/tests/test_https.py14
-rw-r--r--contrib/python/pytest-localserver/py3/ya.make5
14 files changed, 142 insertions, 69 deletions
diff --git a/contrib/python/pytest-localserver/py3/.dist-info/METADATA b/contrib/python/pytest-localserver/py3/.dist-info/METADATA
index 42c4db02b3..56fa7bf975 100644
--- a/contrib/python/pytest-localserver/py3/.dist-info/METADATA
+++ b/contrib/python/pytest-localserver/py3/.dist-info/METADATA
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: pytest-localserver
-Version: 0.8.1
+Version: 0.9.0.post0
Summary: pytest plugin to test server connections locally.
Home-page: https://github.com/pytest-dev/pytest-localserver
Author: Sebastian Rahlf
@@ -16,7 +16,6 @@ Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
-Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
@@ -24,8 +23,9 @@ Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
+Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Testing
-Requires-Python: >=3.5
+Requires-Python: >=3.6
License-File: LICENSE
License-File: AUTHORS
Requires-Dist: werkzeug >=0.10
@@ -125,12 +125,13 @@ poking around in the code itself.
* ``content`` - content of next response (str, bytes, or iterable of either)
* ``headers`` - response headers (dict)
* ``chunked`` - whether to chunk-encode the response (enumeration)
+ * ``store_request_data`` - whether to store request data for later use
Once these attributes are set, all subsequent requests will be answered with
these values until they are changed or the server is stopped. A more
convenient way to change these is ::
- httpserver.serve_content(content=None, code=200, headers=None, chunked=pytest_localserver.http.Chunked.NO)
+ httpserver.serve_content(content=None, code=200, headers=None, chunked=pytest_localserver.http.Chunked.NO, store_request_data=True)
The ``chunked`` attribute or parameter can be set to
@@ -142,6 +143,11 @@ poking around in the code itself.
If chunk encoding is applied, each str or bytes in ``content`` becomes one
chunk in the response.
+ You can use ``store_request_data=False`` to disable loading the request data into
+ memory. This will make it impossible to check the request data using
+ ``httpserver.requests[index].data`` but may make sense when posting a larger amount of
+ data and you don't need to check this.
+
The server address can be found in property
* ``url``
diff --git a/contrib/python/pytest-localserver/py3/AUTHORS b/contrib/python/pytest-localserver/py3/AUTHORS
index 086e355734..ae651ae25e 100644
--- a/contrib/python/pytest-localserver/py3/AUTHORS
+++ b/contrib/python/pytest-localserver/py3/AUTHORS
@@ -14,3 +14,6 @@ Hasan Ramezani <hasan.r67@gmail.com>
Felix Yan <felixonmars@archlinux.org>
Henri Hulski <henri.hulski@gazeta.pl>
Theodore Ni
+Nicola Coretti <nico.coretti@gmail.com>
+Alissa Gerhard <alissa.gerhard@jonasundderwolf.de>
+Raphael Boidol <boidolr@users.noreply.github.com>
diff --git a/contrib/python/pytest-localserver/py3/README.rst b/contrib/python/pytest-localserver/py3/README.rst
index fbaf2bdb42..41fd5c3257 100644
--- a/contrib/python/pytest-localserver/py3/README.rst
+++ b/contrib/python/pytest-localserver/py3/README.rst
@@ -91,12 +91,13 @@ poking around in the code itself.
* ``content`` - content of next response (str, bytes, or iterable of either)
* ``headers`` - response headers (dict)
* ``chunked`` - whether to chunk-encode the response (enumeration)
+ * ``store_request_data`` - whether to store request data for later use
Once these attributes are set, all subsequent requests will be answered with
these values until they are changed or the server is stopped. A more
convenient way to change these is ::
- httpserver.serve_content(content=None, code=200, headers=None, chunked=pytest_localserver.http.Chunked.NO)
+ httpserver.serve_content(content=None, code=200, headers=None, chunked=pytest_localserver.http.Chunked.NO, store_request_data=True)
The ``chunked`` attribute or parameter can be set to
@@ -108,6 +109,11 @@ poking around in the code itself.
If chunk encoding is applied, each str or bytes in ``content`` becomes one
chunk in the response.
+ You can use ``store_request_data=False`` to disable loading the request data into
+ memory. This will make it impossible to check the request data using
+ ``httpserver.requests[index].data`` but may make sense when posting a larger amount of
+ data and you don't need to check this.
+
The server address can be found in property
* ``url``
diff --git a/contrib/python/pytest-localserver/py3/patches/01-arcadia.patch b/contrib/python/pytest-localserver/py3/patches/01-arcadia.patch
index a89510c6ef..d704d63629 100644
--- a/contrib/python/pytest-localserver/py3/patches/01-arcadia.patch
+++ b/contrib/python/pytest-localserver/py3/patches/01-arcadia.patch
@@ -1,8 +1,8 @@
--- contrib/python/pytest-localserver/py3/pytest_localserver/https.py (index)
+++ contrib/python/pytest-localserver/py3/pytest_localserver/https.py (working tree)
@@ -10,1 +10,1 @@ import os.path
--DEFAULT_CERTIFICATE = os.path.join(os.path.abspath(os.path.dirname(__file__)), "server.pem")
-+DEFAULT_CERTIFICATE = os.path.join(os.getcwd(), "server.pem")
+-_ROOT = os.path.abspath(os.path.dirname(__file__))
++_ROOT = os.getcwd()
--- contrib/python/pytest-localserver/py3/pytest_localserver/plugin.py (index)
+++ contrib/python/pytest-localserver/py3/pytest_localserver/plugin.py (working tree)
@@ -4,6 +4,9 @@
@@ -15,7 +15,7 @@
import pytest
-@@ -62,11 +65,15 @@ def httpsserver(request):
+@@ -62,11 +65,17 @@ def httpsserver(request):
SSL encryption.
"""
from pytest_localserver import https
@@ -25,8 +25,10 @@
- request.addfinalizer(server.stop)
- return server
+ try:
++ with open(https.DEFAULT_KEY, 'wb') as f:
++ f.write(pkgutil.get_data('pytest_localserver', 'server.key'))
+ with open(https.DEFAULT_CERTIFICATE, 'wb') as f:
-+ f.write(pkgutil.get_data('pytest_localserver', 'server.pem'))
++ f.write(pkgutil.get_data('pytest_localserver', 'cert.crt'))
+ server = https.SecureContentServer()
+ server.start()
+ request.addfinalizer(server.stop)
diff --git a/contrib/python/pytest-localserver/py3/pytest_localserver/_version.py b/contrib/python/pytest-localserver/py3/pytest_localserver/_version.py
index 044524b166..372502bdbf 100644
--- a/contrib/python/pytest-localserver/py3/pytest_localserver/_version.py
+++ b/contrib/python/pytest-localserver/py3/pytest_localserver/_version.py
@@ -12,5 +12,5 @@ __version__: str
__version_tuple__: VERSION_TUPLE
version_tuple: VERSION_TUPLE
-__version__ = version = '0.8.1'
-__version_tuple__ = version_tuple = (0, 8, 1)
+__version__ = version = '0.9.0.post0'
+__version_tuple__ = version_tuple = (0, 9, 0)
diff --git a/contrib/python/pytest-localserver/py3/pytest_localserver/cert.crt b/contrib/python/pytest-localserver/py3/pytest_localserver/cert.crt
new file mode 100644
index 0000000000..94f804c513
--- /dev/null
+++ b/contrib/python/pytest-localserver/py3/pytest_localserver/cert.crt
@@ -0,0 +1,32 @@
+-----BEGIN CERTIFICATE-----
+MIIFjzCCA3egAwIBAgIUPaO7CEh5PBQ5WVK10+B+NgkyBv0wDQYJKoZIhvcNAQEL
+BQAwSTESMBAGA1UEAwwJMTI3LjAuMC4xMRswGQYDVQQKDBJweXRlc3QtbG9jYWxz
+ZXJ2ZXIxFjAUBgNVBAsMDVRlc3RpbmcgRGVwdC4wHhcNMjQwMjIwMTQzNTIxWhcN
+MzQwMjE3MTQzNTIxWjBJMRIwEAYDVQQDDAkxMjcuMC4wLjExGzAZBgNVBAoMEnB5
+dGVzdC1sb2NhbHNlcnZlcjEWMBQGA1UECwwNVGVzdGluZyBEZXB0LjCCAiIwDQYJ
+KoZIhvcNAQEBBQADggIPADCCAgoCggIBALfVGVEMw3p4alDNlqq2CTv9zmH3w+g8
+1GkUWhS65YZ1/k+Ue/h8zKbtmbPaWPHUOq60qEghQqpLW+HF3nMwWmF45RNU9V9B
+zl6+BMibUYXSsxJJpBIU9U5fec1caYXX8mr1hZNz+tvaez+z4inXNIoGoOx1FuuS
++lJrtzIKTFhy5i1ijmNFr3fQVufhw2P5oDd3EZd3hsst+dEGlEDRXlLMG/3cy04r
+2SeBDBCGMEkL8v9pwc87l3NAhIGEz01NIIAfjObRKVOITEoOEF0TFJt2MCOcneTz
+aE0UtSpjUkCbjJWW/APe81jiGR/+BbO5B4kiHMryQTgD50PwFnN0eugr3GeemZKV
+Lv8/StpB3dVk9zyzAQPLD0yt0DlRT3lvTuxRWzQszS9aGL6vA0Akd+JDvu3BzRs/
+ueLLL8qD5Rh/ubSL+fK8kUqrvmsc59m+aw82z6A50l9/7LLi+/2mYiaPae6WA6Cs
+avNzggKfHcamgqYYUOr+n6GqT30/3Z0UebB3tzZtgdA2kL0EmHxXOtW7Kd1faYvk
+/78t+YSLy0jToibKTOq2T9Q4MsmSztkisl9iViabtpV2u87VTazXQB+WgJf9lU7u
+7eTiUftK2P78LwCn7kKbhDjqxkY7RnlvzTyngRNygAj8ACU7CkcAyL254uonsnTK
+QIOX8utPI2qtAgMBAAGjbzBtMB0GA1UdDgQWBBRzl1iPBK4XZwChdNhdPHfjAb/z
+BzAfBgNVHSMEGDAWgBRzl1iPBK4XZwChdNhdPHfjAb/zBzAPBgNVHRMBAf8EBTAD
+AQH/MBoGA1UdEQQTMBGCCWxvY2FsaG9zdIcEfwAAATANBgkqhkiG9w0BAQsFAAOC
+AgEASnGC12qCmFLg96ym82dEnRLLDXd0J3t0Zn7Hu2eCvqWjPOkM7nfoSQd+QrbB
+uUxghFHHPbH7opHCPky0pK/+Wvwa+76lUaEnsC4gMOnO5U79BTT+EeFD1L9gQ6jZ
+LixdAaq2iq+4m7MJSkx1gyjwpH/xIaL0Vqh1A8qRlZNppMJ0ccIGK+UuZv3rNnRi
+BP0BRSpdH0WrposQWd+yOtac5bvLH4dnPUkk386e+H46HiGvmusDlUW0oD2TItn5
+fYofeaC1RDrbWRUOLgeKvda5vI1aH2p0asZu+MtUjkpENQKi2CieKCFh2wYTJdJT
+/aFuoeXzPLBgBiOc6SSg/RGAurFntxAYMQJLtwnUvFQ0Gp1XF7HgUh0PGkJNWDV2
+iah8jhvW2ujPf1dgpGIeVAcJ3Iu6KH5qOGWZnXNKm59U7zPwREtkxvqB07rAVXXi
+vKvjoqzu+LySVUtI8I8FWMbypHQGlNxippEVM85X4jfNWY+ufp5jOsgPAUVmyJWd
+VgepbU8kkr9scBasqjYdus0DXWUaDttbxoSpz8NODCS3StC2JJS+NEe1Vb/ZCNOQ
+cYuUuBfeuIF4jQjebJn+XvwLhu/KpemCU5WmcrlIk9NfPxCJ2K2es3nKBj5yWGXN
+XOf2/y5T4suViRRl5A+YO2wyWc8l4egVDKYzC2kSNlCQsIQ=
+-----END CERTIFICATE-----
diff --git a/contrib/python/pytest-localserver/py3/pytest_localserver/http.py b/contrib/python/pytest-localserver/py3/pytest_localserver/http.py
index 0899597f5e..a4c3bef223 100644
--- a/contrib/python/pytest-localserver/py3/pytest_localserver/http.py
+++ b/contrib/python/pytest-localserver/py3/pytest_localserver/http.py
@@ -15,7 +15,6 @@ from werkzeug.wrappers import Response
class WSGIServer(threading.Thread):
-
"""
HTTP server running a WSGI application in its own thread.
"""
@@ -61,7 +60,6 @@ def _encode_chunk(chunk, charset):
class ContentServer(WSGIServer):
-
"""
Small test server which can be taught which content (i.e. string) to serve
with which response code. Try the following snippet for testing API calls::
@@ -89,12 +87,18 @@ class ContentServer(WSGIServer):
self.compress = None
self.requests = []
self.chunked = Chunked.NO
+ self.store_request_data = False
def __call__(self, environ, start_response):
"""
This is the WSGI application.
"""
request = Request(environ)
+
+ if self.store_request_data:
+ # need to invoke this method to cache the data
+ request.get_data(cache=True)
+
self.requests.append(request)
if (
request.content_type == "application/x-www-form-urlencoded"
@@ -129,7 +133,7 @@ class ContentServer(WSGIServer):
return response(environ, start_response)
- def serve_content(self, content, code=200, headers=None, chunked=Chunked.NO):
+ def serve_content(self, content, code=200, headers=None, chunked=Chunked.NO, store_request_data=True):
"""
Serves string content (with specified HTTP error code) as response to
all subsequent request.
@@ -138,6 +142,7 @@ class ContentServer(WSGIServer):
:param code: HTTP status code
:param headers: HTTP headers to be returned
:param chunked: whether to apply chunked transfer encoding to the content
+ :param store_request_data: whether to store data sent as request payload.
"""
if not isinstance(content, (str, bytes, list, tuple)):
# If content is an iterable which is not known to be a string,
@@ -153,6 +158,7 @@ class ContentServer(WSGIServer):
self.content = content
self.code = code
self.chunked = chunked
+ self.store_request_data = store_request_data
if headers:
self.headers = Headers(headers)
diff --git a/contrib/python/pytest-localserver/py3/pytest_localserver/https.py b/contrib/python/pytest-localserver/py3/pytest_localserver/https.py
index 856e222ac5..7339211497 100644
--- a/contrib/python/pytest-localserver/py3/pytest_localserver/https.py
+++ b/contrib/python/pytest-localserver/py3/pytest_localserver/https.py
@@ -6,12 +6,13 @@ import os.path
from pytest_localserver.http import ContentServer
-#: default server certificate
-DEFAULT_CERTIFICATE = os.path.join(os.getcwd(), "server.pem")
+# default key and certificate
+_ROOT = os.getcwd()
+DEFAULT_KEY = os.path.join(_ROOT, "server.key")
+DEFAULT_CERTIFICATE = os.path.join(_ROOT, "cert.crt")
class SecureContentServer(ContentServer):
-
"""
Small test server which works just like :class:`http.Server` over HTTP::
@@ -111,13 +112,27 @@ class SecureContentServer(ContentServer):
.. _pyOpenSSH: https://launchpad.net/pyopenssl
"""
- def __init__(self, host="localhost", port=0, key=DEFAULT_CERTIFICATE, cert=DEFAULT_CERTIFICATE):
+ def __init__(self, host="localhost", port=0, key=DEFAULT_KEY, cert=DEFAULT_CERTIFICATE):
"""
:param key: location of file containing the server private key.
:param cert: location of file containing server certificate.
"""
- super().__init__(host, port, ssl_context=(key, cert))
+ super().__init__(host, port, ssl_context=(cert, key))
+ self._cert = cert
+
+ @property
+ def certificate(self):
+ """
+ Returns the path to the server's SSL/TLS certificate file.
+ Clients can use this path to access and verify the server's identity by
+ incorporating the certificate.
+
+ .. note::
+ Do not rely on having a stable filesystem path for the returned
+ certificate path across different versions or test runs.
+ """
+ return self._cert
if __name__ == "__main__": # pragma: no cover
diff --git a/contrib/python/pytest-localserver/py3/pytest_localserver/plugin.py b/contrib/python/pytest-localserver/py3/pytest_localserver/plugin.py
index 1e6ad2f172..501245eccd 100644
--- a/contrib/python/pytest-localserver/py3/pytest_localserver/plugin.py
+++ b/contrib/python/pytest-localserver/py3/pytest_localserver/plugin.py
@@ -64,8 +64,10 @@ def httpsserver(request):
"""
from pytest_localserver import https
try:
+ with open(https.DEFAULT_KEY, 'wb') as f:
+ f.write(pkgutil.get_data('pytest_localserver', 'server.key'))
with open(https.DEFAULT_CERTIFICATE, 'wb') as f:
- f.write(pkgutil.get_data('pytest_localserver', 'server.pem'))
+ f.write(pkgutil.get_data('pytest_localserver', 'cert.crt'))
server = https.SecureContentServer()
server.start()
request.addfinalizer(server.stop)
diff --git a/contrib/python/pytest-localserver/py3/pytest_localserver/server.pem b/contrib/python/pytest-localserver/py3/pytest_localserver/server.key
index 4f7f1ed322..31a498ede0 100644
--- a/contrib/python/pytest-localserver/py3/pytest_localserver/server.pem
+++ b/contrib/python/pytest-localserver/py3/pytest_localserver/server.key
@@ -50,35 +50,3 @@ lIqpHR4fwrBr4SLStzvBo9UK1YYQ94FyKd7xou3uXLLTlY3G8rD6jjKJE2Gg8Ga/
gGzbRCZWH6AOk1iO/CmOPH6AdFn5axXTx+uAML1Lr2VQ+azrYZCtIhKmW/kuQPQg
apeiobcSY1vsX7eM8mQkM8TxrDLyNjtl
-----END PRIVATE KEY-----
------BEGIN CERTIFICATE-----
-MIIFiTCCA3GgAwIBAgIUUpWEFJm0PzrYTkhLe05yIBhBMuowDQYJKoZIhvcNAQEL
-BQAwSTESMBAGA1UEAwwJMTI3LjAuMC4xMRswGQYDVQQKDBJweXRlc3QtbG9jYWxz
-ZXJ2ZXIxFjAUBgNVBAsMDVRlc3RpbmcgRGVwdC4wHhcNMjEwOTE0MDU1NzAxWhcN
-MzEwOTEyMDU1NzAxWjBJMRIwEAYDVQQDDAkxMjcuMC4wLjExGzAZBgNVBAoMEnB5
-dGVzdC1sb2NhbHNlcnZlcjEWMBQGA1UECwwNVGVzdGluZyBEZXB0LjCCAiIwDQYJ
-KoZIhvcNAQEBBQADggIPADCCAgoCggIBALfVGVEMw3p4alDNlqq2CTv9zmH3w+g8
-1GkUWhS65YZ1/k+Ue/h8zKbtmbPaWPHUOq60qEghQqpLW+HF3nMwWmF45RNU9V9B
-zl6+BMibUYXSsxJJpBIU9U5fec1caYXX8mr1hZNz+tvaez+z4inXNIoGoOx1FuuS
-+lJrtzIKTFhy5i1ijmNFr3fQVufhw2P5oDd3EZd3hsst+dEGlEDRXlLMG/3cy04r
-2SeBDBCGMEkL8v9pwc87l3NAhIGEz01NIIAfjObRKVOITEoOEF0TFJt2MCOcneTz
-aE0UtSpjUkCbjJWW/APe81jiGR/+BbO5B4kiHMryQTgD50PwFnN0eugr3GeemZKV
-Lv8/StpB3dVk9zyzAQPLD0yt0DlRT3lvTuxRWzQszS9aGL6vA0Akd+JDvu3BzRs/
-ueLLL8qD5Rh/ubSL+fK8kUqrvmsc59m+aw82z6A50l9/7LLi+/2mYiaPae6WA6Cs
-avNzggKfHcamgqYYUOr+n6GqT30/3Z0UebB3tzZtgdA2kL0EmHxXOtW7Kd1faYvk
-/78t+YSLy0jToibKTOq2T9Q4MsmSztkisl9iViabtpV2u87VTazXQB+WgJf9lU7u
-7eTiUftK2P78LwCn7kKbhDjqxkY7RnlvzTyngRNygAj8ACU7CkcAyL254uonsnTK
-QIOX8utPI2qtAgMBAAGjaTBnMB0GA1UdDgQWBBRzl1iPBK4XZwChdNhdPHfjAb/z
-BzAfBgNVHSMEGDAWgBRzl1iPBK4XZwChdNhdPHfjAb/zBzAPBgNVHRMBAf8EBTAD
-AQH/MBQGA1UdEQQNMAuCCWxvY2FsaG9zdDANBgkqhkiG9w0BAQsFAAOCAgEATk+Q
-t6psMrtGeFcZKYdmSFqW3SZUba4l76PzvHRf8nMcB1eFuZ4mCdiv0NgcQkE8c9T+
-i/J4wEmJ+mf1033MP1vQmrGqnaYBsVHNBTaTsP+gLg6Z7AGPvPaL2fwmWWNwTT0O
-1352bdz9ORacKSXW3Pq0Vi1pTMho0kAya3VQpl2paqz8qSUG7ijyGQ46VXjgqNZ1
-P5lv+6CWa3AwEQo6Edv1x+HLesRWVqVAkxxhlaGOPQm1cDlpnI4rxuYIMlsb5cNZ
-XTAIxw6Es1eqlPcZ96EoGXyIrG7Ej6Yb9447PrC1ulMnIu74cWLY25eu+oVr7Nvk
-Gjp2I7qbVjz9Ful0o0M9Wps4RzCgrpO4WeirCK/jFIUpmXJdn7V4mX0h2ako+dal
-vczg+bAd4ZedJWHTiqJs9lVMh4/YD7Ck6n+iAZ8Jusq6OhyTY43/Nyp2zQbwQmYv
-y3V6JVX+vY4Cq8pR1i8x5FBHnOCMPoT4sbOjKuoFWVi9wH1d65Q1JOo6/0eYzfwJ
-nuGUJza7+aCxYNlqxtqX0ItM670ClxB7fuWUpKh5WHrHD2dqBhYwtXOl9yBHrFOJ
-O8toKk3PmtlMqVZ8QXmgSqEy7wkfxhjJLgi2AQsqeA6nDrCLtr2pWdqDWoUfxY8r
-r5rc71nFLay/H2CbOYELI+20VFMp8GF3kOZbkRA=
------END CERTIFICATE-----
diff --git a/contrib/python/pytest-localserver/py3/pytest_localserver/smtp.py b/contrib/python/pytest-localserver/py3/pytest_localserver/smtp.py
index 82dbc394b9..0b285eb10a 100644
--- a/contrib/python/pytest-localserver/py3/pytest_localserver/smtp.py
+++ b/contrib/python/pytest-localserver/py3/pytest_localserver/smtp.py
@@ -31,7 +31,6 @@ class Handler:
class Server(aiosmtpd.controller.Controller):
-
"""
Small SMTP test server.
@@ -96,16 +95,7 @@ class Server(aiosmtpd.controller.Controller):
@property
def accepting(self):
- try:
- return self.server.is_serving()
- except AttributeError:
- # asyncio.base_events.Server.is_serving() only exists in Python 3.6
- # and up. For Python 3.5, asyncio.base_events.BaseEventLoop.is_running()
- # is a close approximation; it should mostly return the same value
- # except for brief periods when the server is starting up or shutting
- # down. Once we drop support for Python 3.5, this branch becomes
- # unnecessary.
- return self.loop.is_running()
+ return self.server.is_serving()
# for aiosmtpd <1.4
if not hasattr(aiosmtpd.controller.Controller, "_trigger_server"):
diff --git a/contrib/python/pytest-localserver/py3/tests/test_http.py b/contrib/python/pytest-localserver/py3/tests/test_http.py
index 64859ffd25..904e6aea5e 100644
--- a/contrib/python/pytest-localserver/py3/tests/test_http.py
+++ b/contrib/python/pytest-localserver/py3/tests/test_http.py
@@ -5,6 +5,7 @@ import textwrap
import pytest
import requests
+from werkzeug.exceptions import ClientDisconnected
from pytest_localserver import http
from pytest_localserver import plugin
@@ -90,6 +91,29 @@ def test_HEAD_request(httpserver):
# assert resp.status_code == 200
+def test_POST_request_no_store_data(httpserver):
+ headers = {"Content-type": "text/plain"}
+ httpserver.serve_content("TEST!", store_request_data=False)
+ requests.post(httpserver.url, data=b"testdata", headers=headers)
+
+ request = httpserver.requests[-1]
+ request.input_stream.close()
+
+ with pytest.raises(ClientDisconnected):
+ request.data
+
+
+def test_POST_request_store_data(httpserver):
+ headers = {"Content-type": "text/plain"}
+ httpserver.serve_content("TEST!", store_request_data=True)
+ requests.post(httpserver.url, data=b"testdata", headers=headers)
+
+ request = httpserver.requests[-1]
+ request.input_stream.close()
+
+ assert httpserver.requests[-1].data == b"testdata"
+
+
@pytest.mark.parametrize("chunked_flag", [http.Chunked.YES, http.Chunked.AUTO, http.Chunked.NO])
def test_chunked_attribute_without_header(httpserver, chunked_flag):
"""
@@ -224,7 +248,7 @@ def _compare_chunks(expected, actual):
__tracebackhide__ = True
if expected != actual:
message = [_format_chunk(expected) + " != " + _format_chunk(actual)]
- if type(expected) == type(actual):
+ if type(expected) is type(actual):
for i, (e, a) in enumerate(itertools.zip_longest(expected, actual, fillvalue="<end>")):
if e != a:
message += [
@@ -274,19 +298,23 @@ def test_GET_request_chunked_no_content_length(httpserver, chunked_flag):
def test_httpserver_init_failure_no_stderr_during_cleanup(tmp_path):
"""
Test that, when the server encounters an error during __init__, its cleanup
- does not raise an AttributeError in its __del__ method, which would emit a
+ does not raise an AttributeError in its __del__ method, which would emit a
warning onto stderr.
"""
script_path = tmp_path.joinpath("script.py")
- script_path.write_text(textwrap.dedent("""
+ script_path.write_text(
+ textwrap.dedent(
+ """
from pytest_localserver import http
from unittest.mock import patch
with patch("pytest_localserver.http.make_server", side_effect=RuntimeError("init failure")):
server = http.ContentServer()
- """))
+ """
+ )
+ )
result = subprocess.run([sys.executable, str(script_path)], stderr=subprocess.PIPE)
diff --git a/contrib/python/pytest-localserver/py3/tests/test_https.py b/contrib/python/pytest-localserver/py3/tests/test_https.py
index 4c676d1753..d66450b5bb 100644
--- a/contrib/python/pytest-localserver/py3/tests/test_https.py
+++ b/contrib/python/pytest-localserver/py3/tests/test_https.py
@@ -1,3 +1,4 @@
+import pytest
import requests
from pytest_localserver import https
@@ -41,3 +42,16 @@ def test_HEAD_request(httpsserver):
resp = requests.head(httpsserver.url, verify=False)
assert resp.status_code == 200
assert resp.headers["Content-type"] == "text/plain"
+
+
+def test_client_does_not_trust_self_signed_certificate(httpsserver):
+ httpsserver.serve_content("TEST!", headers={"Content-type": "text/plain"})
+ with pytest.raises(requests.exceptions.SSLError, match="CERTIFICATE_VERIFY_FAILED"):
+ requests.get(httpsserver.url, verify=True)
+
+
+def test_add_server_certificate_to_client_trust_chain(httpsserver):
+ httpsserver.serve_content("TEST!", headers={"Content-type": "text/plain"})
+ resp = requests.get(httpsserver.url, verify=httpsserver.certificate)
+ assert resp.status_code == 200
+ assert resp.headers["Content-type"] == "text/plain"
diff --git a/contrib/python/pytest-localserver/py3/ya.make b/contrib/python/pytest-localserver/py3/ya.make
index 0a1b91f6c3..f066c6f5f1 100644
--- a/contrib/python/pytest-localserver/py3/ya.make
+++ b/contrib/python/pytest-localserver/py3/ya.make
@@ -2,7 +2,7 @@
PY3_LIBRARY()
-VERSION(0.8.1)
+VERSION(0.9.0.post0)
LICENSE(MIT)
@@ -31,7 +31,8 @@ RESOURCE_FILES(
.dist-info/METADATA
.dist-info/entry_points.txt
.dist-info/top_level.txt
- pytest_localserver/server.pem
+ pytest_localserver/cert.crt
+ pytest_localserver/server.key
)
END()