Skip to content

Commit

Permalink
Fix cookies lost after Host header is used(#119), also add support fo…
Browse files Browse the repository at this point in the history
…r resolve.
  • Loading branch information
perklet committed Sep 13, 2023
1 parent 3cb9778 commit 640d552
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 2 deletions.
9 changes: 9 additions & 0 deletions curl_cffi/curl.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ def __init__(self, cacert: str = DEFAULT_CACERT, debug: bool = False):
"""
self._curl = lib.curl_easy_init()
self._headers = ffi.NULL
self._resolve = ffi.NULL
self._cacert = cacert
self._is_cert_set = False
self._write_handle = None
Expand Down Expand Up @@ -172,6 +173,12 @@ def setopt(self, option: CurlOpt, value: Any):
for header in value:
self._headers = lib.curl_slist_append(self._headers, header)
ret = lib._curl_easy_setopt(self._curl, option, self._headers)
elif option == CurlOpt.RESOLVE:
for resolve in value:
if isinstance(resolve, str):
resolve = resolve.encode()
self._resolve = lib.curl_slist_append(self._resolve, resolve)
ret = lib._curl_easy_setopt(self._curl, option, self._resolve)
else:
ret = lib._curl_easy_setopt(self._curl, option, c_value)
self._check_error(ret, "setopt(%s, %s)" % (option, value))
Expand Down Expand Up @@ -261,6 +268,7 @@ def reset(self):
self._is_cert_set = False
lib.curl_easy_reset(self._curl)
self._set_error_buffer()
self._resolve = ffi.NULL

def parse_cookie_headers(self, headers: List[bytes]) -> SimpleCookie:
"""Extract cookies.SimpleCookie from header lines.
Expand Down Expand Up @@ -308,3 +316,4 @@ def close(self):
lib.curl_easy_cleanup(self._curl)
self._curl = None
ffi.release(self._error_buffer)
self._resolve = ffi.NULL
12 changes: 12 additions & 0 deletions curl_cffi/requests/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,18 @@ def _set_curl_options(
h = Headers(self.headers)
h.update(headers)

# remove Host header if it's unnecessary, otherwise curl maybe confused.
# Host header will be automatically add by curl if it's not present.
# https://github.com/yifeikong/curl_cffi/issues/119
host_header = h.get("Host")
if host_header is not None:
u = urlparse(url)
if host_header == u.netloc or host_header == u.hostname:
try:
del h["Host"]
except KeyError:
pass

header_lines = []
for k, v in h.multi_items():
header_lines.append(f"{k}: {v}")
Expand Down
8 changes: 8 additions & 0 deletions tests/unittest/test_curl.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,3 +301,11 @@ def test_reason(server):
headers = buffer.getvalue()
headers = headers.splitlines()
assert c.get_reason_phrase(headers[0]) == b"OK"


def test_resolve(server):
c = Curl()
url = "http://example.com:8000"
c.setopt(CurlOpt.RESOLVE, ["example.com:8000:127.0.0.1"])
c.setopt(CurlOpt.URL, url)
c.perform()
15 changes: 13 additions & 2 deletions tests/unittest/test_requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import pytest

from curl_cffi import requests
from curl_cffi import requests, CurlOpt
from curl_cffi.const import CurlECode


Expand Down Expand Up @@ -332,13 +332,24 @@ def test_cookies_after_redirect(server):


def test_cookies_with_special_chars(server):
s = requests.Session(debug=True)
s = requests.Session()
r = s.get(str(server.url.copy_with(path="/set_special_cookies")))
assert s.cookies["foo"] == "bar space"
r = s.get(str(server.url.copy_with(path="/echo_cookies")))
assert r.json()["foo"] == "bar space"


def test_cookies_mislead_by_host(server):
s = requests.Session(debug=True)
s.curl.setopt(CurlOpt.RESOLVE, ["example.com:8000:127.0.0.1"])
s.cookies.set("foo", "bar")
print("URL is: ", str(server.url))
# TODO replace hard-coded url with server.url.replace(host="example.com")
r = s.get("http://example.com:8000", headers={"Host": "example.com"})
r = s.get(str(server.url.copy_with(path="/echo_cookies")))
assert r.json()["foo"] == "bar"


# https://github.com/yifeikong/curl_cffi/issues/39
def test_post_body_cleaned(server):
s = requests.Session()
Expand Down

0 comments on commit 640d552

Please sign in to comment.