Skip to content

Commit 8f1484c

Browse files
committed
Fix: Request.GetPostData() throws UnicodeEncodeError (cztomczak#517).
1 parent e025351 commit 8f1484c

File tree

4 files changed

+59
-5
lines changed

4 files changed

+59
-5
lines changed

src/cefpython.pyx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,11 @@ IF PY_MAJOR_VERSION == 2:
147147
from urllib import pathname2url as urllib_pathname2url
148148
# noinspection PyUnresolvedReferences
149149
from urllib import urlencode as urllib_urlencode
150+
from urllib import quote as urlparse_quote
150151
ELSE:
151152
# noinspection PyUnresolvedReferences
152153
from urllib import parse as urlparse
154+
from urllib.parse import quote as urlparse_quote
153155
# noinspection PyUnresolvedReferences
154156
from urllib.request import pathname2url as urllib_pathname2url
155157
# noinspection PyUnresolvedReferences
@@ -1027,7 +1029,8 @@ cpdef LoadCrlSetsFile(py_string path):
10271029
CefLoadCRLSetsFile(PyToCefStringValue(path))
10281030

10291031
cpdef GetDataUrl(data, mediatype="html"):
1030-
html = data.encode("utf-8", "replace")
1031-
b64 = base64.b64encode(html).decode("utf-8", "replace")
1032+
if PY_MAJOR_VERSION >= 3:
1033+
data = data.encode("utf-8", "replace")
1034+
b64 = base64.b64encode(data).decode("utf-8", "replace")
10321035
ret = "data:text/html;base64,{data}".format(data=b64)
10331036
return ret

src/request.pyx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,16 @@ cdef class PyRequest:
119119
retMultipart.append(pyData)
120120
else:
121121
# Content-Type: application/x-www-form-urlencoded
122-
retUrlEncoded.update(urlparse.parse_qsl(qs=pyData,
122+
quoted = urlparse_quote(pyData, safe="=")
123+
retUrlEncoded.update(urlparse.parse_qsl(qs=quoted,
123124
keep_blank_values=True))
125+
if PY_MAJOR_VERSION >= 3:
126+
retUrlEncoded_copy = copy.deepcopy(retUrlEncoded)
127+
retUrlEncoded = dict()
128+
for key in retUrlEncoded_copy:
129+
retUrlEncoded[key.encode("utf-8", "replace")] =\
130+
retUrlEncoded_copy[key].encode(
131+
"utf-8", "replace")
124132
elif postDataElement.get().GetType() == cef_types.PDE_TYPE_FILE:
125133
pyFile = CefToPyBytes(postDataElement.get().GetFile())
126134
retMultipart.append(b"@"+pyFile)
@@ -156,7 +164,7 @@ cdef class PyRequest:
156164
postData.get().AddElement(postDataElement)
157165
self.GetCefRequest().get().SetPostData(postData)
158166
elif type(pyPostData) == dict:
159-
pyElement = urllib_urlencode(pyPostData).encode()
167+
pyElement = urllib_urlencode(pyPostData).encode("utf-8", "replace")
160168
postDataElement = CefPostDataElement_Create()
161169
postDataElement.get().SetToBytes(len(pyElement), <char*>pyElement)
162170
postData.get().AddElement(postDataElement)

unittests/issue517.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# coding=utf8
2+
from cefpython3 import cefpython as cef
3+
import sys
4+
5+
html = """
6+
<!DOCTYPE html>
7+
<html lang="en">
8+
<head>
9+
<meta charset="UTF-8">
10+
<title>Title</title>
11+
</head>
12+
<body>
13+
<script>
14+
window.onload = function() {
15+
fetch('http://127.0.0.1:8000', {
16+
method: 'POST',
17+
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
18+
body: 'key=' + encodeURI('🍣 asd'),
19+
}).then().catch();
20+
}
21+
</script>
22+
</body>
23+
</html>
24+
"""
25+
26+
27+
class RequestHandler:
28+
def GetResourceHandler(self, browser, frame, request):
29+
print(request.GetPostData())
30+
return None
31+
32+
def main():
33+
sys.excepthook = cef.ExceptHook
34+
cef.Initialize()
35+
browser = cef.CreateBrowserSync(url=cef.GetDataUrl(html))
36+
browser.SetClientHandler(RequestHandler())
37+
cef.MessageLoop()
38+
del browser
39+
cef.Shutdown()
40+
41+
42+
if __name__ == '__main__':
43+
main()

unittests/main_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ def test_main(self):
235235
req_file = os.path.dirname(os.path.abspath(__file__))
236236
req_file = os.path.join(req_file, "main_test.py")
237237
if sys.version_info.major > 2:
238-
req_file = req_file.encode()
238+
req_file = req_file.encode("utf-8")
239239
req_data = [b"--key=value", b"@"+req_file]
240240
req.SetMethod("POST")
241241
req.SetPostData(req_data)

0 commit comments

Comments
 (0)