Skip to content

Commit e51e818

Browse files
authored
Fix cURL error 77 on Windows (#647)
1 parent 57cc1ad commit e51e818

File tree

2 files changed

+34
-4
lines changed

2 files changed

+34
-4
lines changed

curl_cffi/curl.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import annotations
22

33
import re
4+
import locale
45
import struct
56
import sys
67
import warnings
@@ -256,7 +257,34 @@ def setopt(self, option: CurlOpt, value: Any) -> int:
256257
lib._curl_easy_setopt(self._curl, CurlOpt.DEBUGFUNCTION, lib.debug_function)
257258
option = CurlOpt.DEBUGDATA
258259
elif value_type == "char*":
259-
c_value = value.encode() if isinstance(value, str) else value
260+
if isinstance(value, str):
261+
# Windows/libcurl expects ANSI code page for file paths (char*).
262+
# Non-ASCII paths encoded as UTF-8 can trigger ErrCode 77.
263+
# Encode file-path-like options using the system encoding on Windows.
264+
filepath_opts = {
265+
CurlOpt.CAINFO,
266+
CurlOpt.CAPATH,
267+
CurlOpt.PROXY_CAINFO,
268+
CurlOpt.PROXY_CAPATH,
269+
CurlOpt.SSLCERT,
270+
CurlOpt.SSLKEY,
271+
CurlOpt.CRLFILE,
272+
CurlOpt.ISSUERCERT,
273+
CurlOpt.SSH_PUBLIC_KEYFILE,
274+
CurlOpt.SSH_PRIVATE_KEYFILE,
275+
CurlOpt.COOKIEFILE,
276+
CurlOpt.COOKIEJAR,
277+
CurlOpt.NETRC_FILE,
278+
CurlOpt.UNIX_SOCKET_PATH,
279+
}
280+
if sys.platform.startswith("win") and option in filepath_opts:
281+
# Use the process ANSI code page to match what CRT fopen expects.
282+
enc = locale.getpreferredencoding(False)
283+
c_value = value.encode(enc, errors="strict")
284+
else:
285+
c_value = value.encode()
286+
else:
287+
c_value = value
260288
# Must keep a reference, otherwise may be GCed.
261289
if option == CurlOpt.POSTFIELDS:
262290
self._body_handle = c_value

docs/faq.rst

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,11 @@ The simplest way is to turn off cert verification by ``verify=False``:
7070
ErrCode: 77, Reason: error setting certificate verify locations
7171
------
7272

73-
Install ``curl_cffi`` and its dependencies in a pure-ASCII path, i.e. no Chinese or any
74-
other characters out of the ASCII table in the path.
75-
73+
On Windows, if your Python environment or CA bundle path contains non-ASCII characters
74+
(e.g. accents), libcurl may fail to open the CA file when passed as a narrow ``char*``.
75+
``curl_cffi`` now encodes file-path options (e.g. ``CAINFO``, ``PROXY_CAINFO``,
76+
``SSLCERT``) using the system's preferred ANSI code page on Windows to ensure correct
77+
file access. This fixes most occurrences of error 77.
7678

7779
How to use with fiddler/charles to intercept content
7880
------

0 commit comments

Comments
 (0)