1
0
mirror of https://github.com/httpie/cli.git synced 2025-08-10 22:42:05 +02:00

Add support for sending secure cookies over localhost (#1327)

* Add support for sending secure cookies over localhost

* Refactor

* Fix the CI

Co-authored-by: Jakub Roztocil <jakub@roztocil.co>
This commit is contained in:
Batuhan Taskaya
2022-04-14 17:42:05 +03:00
committed by GitHub
parent e6d0bfec7c
commit 86f4bf4d0a
9 changed files with 147 additions and 15 deletions

View File

@@ -7,6 +7,7 @@ from pytest_httpbin import certs
from .utils import ( # noqa
HTTPBIN_WITH_CHUNKED_SUPPORT_DOMAIN,
HTTPBIN_WITH_CHUNKED_SUPPORT,
REMOTE_HTTPBIN_DOMAIN,
mock_env
)
from .utils.plugins_cli import ( # noqa
@@ -17,7 +18,7 @@ from .utils.plugins_cli import ( # noqa
httpie_plugins_success,
interface,
)
from .utils.http_server import http_server # noqa
from .utils.http_server import http_server, localhost_http_server # noqa
@pytest.fixture(scope='function', autouse=True)
@@ -58,6 +59,22 @@ def httpbin_with_chunked_support(_httpbin_with_chunked_support_available):
pytest.skip(f'{HTTPBIN_WITH_CHUNKED_SUPPORT_DOMAIN} not resolvable')
@pytest.fixture(scope='session')
def _remote_httpbin_available():
try:
socket.gethostbyname(REMOTE_HTTPBIN_DOMAIN)
return True
except OSError:
return False
@pytest.fixture
def remote_httpbin(_remote_httpbin_available):
if _remote_httpbin_available:
return 'http://' + REMOTE_HTTPBIN_DOMAIN
pytest.skip(f'{REMOTE_HTTPBIN_DOMAIN} not resolvable')
@pytest.fixture(autouse=True, scope='session')
def pyopenssl_inject():
"""

View File

@@ -2,11 +2,6 @@ import pytest
from .utils import http
@pytest.fixture
def remote_httpbin(httpbin_with_chunked_support):
return httpbin_with_chunked_support
def _stringify(fixture):
return fixture + ''

View File

@@ -800,3 +800,37 @@ def test_session_multiple_headers_with_same_name(basic_session, httpbin):
)
assert r.count('Foo: bar') == 2
assert 'Foo: baz' in r
@pytest.mark.parametrize(
'server, expected_cookies',
[
(
pytest.lazy_fixture('localhost_http_server'),
{'secure_cookie': 'foo', 'insecure_cookie': 'bar'}
),
(
pytest.lazy_fixture('remote_httpbin'),
{'insecure_cookie': 'bar'}
)
]
)
def test_secure_cookies_on_localhost(mock_env, tmp_path, server, expected_cookies):
session_path = tmp_path / 'session.json'
http(
'--session', str(session_path),
server + '/cookies/set',
'secure_cookie==foo',
'insecure_cookie==bar'
)
with open_session(session_path, mock_env) as session:
for cookie in session.cookies:
if cookie.name == 'secure_cookie':
cookie.secure = True
r = http(
'--session', str(session_path),
server + '/cookies'
)
assert r.json == {'cookies': expected_cookies}

View File

@@ -21,6 +21,8 @@ from httpie.context import Environment
from httpie.utils import url_as_host
REMOTE_HTTPBIN_DOMAIN = 'pie.dev'
# pytest-httpbin currently does not support chunked requests:
# <https://github.com/kevin1024/pytest-httpbin/issues/33>
# <https://github.com/kevin1024/pytest-httpbin/issues/28>

View File

@@ -1,9 +1,12 @@
import threading
import json
from collections import defaultdict
from contextlib import contextmanager
from http import HTTPStatus
from http.cookies import SimpleCookie
from http.server import HTTPServer, BaseHTTPRequestHandler
from urllib.parse import urlparse
from urllib.parse import urlparse, parse_qs
import pytest
@@ -85,6 +88,34 @@ def status_custom_msg(handler):
handler.end_headers()
@TestHandler.handler('GET', '/cookies')
def get_cookies(handler):
cookies = {
'cookies': {
key: cookie.value
for key, cookie in SimpleCookie(handler.headers.get('Cookie')).items()
}
}
payload = json.dumps(cookies)
handler.send_response(200)
handler.send_header('Content-Length', len(payload))
handler.send_header('Content-Type', 'application/json')
handler.end_headers()
handler.wfile.write(payload.encode('utf-8'))
@TestHandler.handler('GET', '/cookies/set')
def set_cookies(handler):
options = parse_qs(urlparse(handler.path).query)
handler.send_response(200)
for cookie, [value] in options.items():
handler.send_header('Set-Cookie', f'{cookie}={value}')
handler.end_headers()
@TestHandler.handler('GET', '/cookies/set-and-redirect')
def set_cookie_and_redirect(handler):
handler.send_response(302)
@@ -98,15 +129,30 @@ def set_cookie_and_redirect(handler):
handler.end_headers()
@contextmanager
def _http_server():
server = HTTPServer(('localhost', 0), TestHandler)
thread = threading.Thread(target=server.serve_forever)
thread.start()
yield server
server.shutdown()
thread.join()
@pytest.fixture(scope="function")
def http_server():
"""A custom HTTP server implementation for our tests, that is
built on top of the http.server module. Handy when we need to
deal with details which httpbin can not capture."""
server = HTTPServer(('localhost', 0), TestHandler)
thread = threading.Thread(target=server.serve_forever)
thread.start()
yield '{}:{}'.format(*server.socket.getsockname())
server.shutdown()
thread.join(timeout=0.5)
with _http_server() as server:
yield '{0}:{1}'.format(*server.socket.getsockname())
@pytest.fixture(scope="function")
def localhost_http_server():
"""Just like the http_server, but uses the static
`localhost` name for the host."""
with _http_server() as server:
yield 'localhost:{1}'.format(*server.socket.getsockname())