|
1 | 1 | from datetime import datetime |
2 | | -from email.utils import encode_rfc2231 |
3 | 2 | from urllib.parse import quote |
4 | 3 |
|
5 | | -from requests import Request |
6 | | - |
7 | 4 | from ..exceptions import AnymailError, AnymailRequestsAPIError |
8 | 5 | from ..message import AnymailRecipientStatus |
9 | 6 | from ..utils import get_anymail_setting, rfc2822date |
10 | 7 | from .base_requests import AnymailRequestsBackend, RequestsPayload |
11 | 8 |
|
12 | 9 |
|
13 | | -# Feature-detect whether requests (urllib3) correctly uses RFC 7578 encoding for non- |
14 | | -# ASCII filenames in Content-Disposition headers. (This was fixed in urllib3 v1.25.) |
15 | | -# See MailgunPayload.get_request_params for info (and a workaround on older versions). |
16 | | -# (Note: when this workaround is removed, please also remove "old_urllib3" tox envs.) |
17 | | -def is_requests_rfc_5758_compliant(): |
18 | | - request = Request( |
19 | | - method="POST", |
20 | | - url="https://www.example.com", |
21 | | - files=[("attachment", ("\N{NOT SIGN}.txt", "test", "text/plain"))], |
22 | | - ) |
23 | | - prepared = request.prepare() |
24 | | - form_data = prepared.body # bytes |
25 | | - return b"filename*=" not in form_data |
26 | | - |
27 | | - |
28 | | -REQUESTS_IS_RFC_7578_COMPLIANT = is_requests_rfc_5758_compliant() |
29 | | - |
30 | | - |
31 | 10 | class EmailBackend(AnymailRequestsBackend): |
32 | 11 | """ |
33 | 12 | Mailgun API Email Backend |
@@ -163,37 +142,6 @@ def get_api_endpoint(self): |
163 | 142 | ) |
164 | 143 | return "%s/messages" % quote(self.sender_domain, safe="") |
165 | 144 |
|
166 | | - def get_request_params(self, api_url): |
167 | | - params = super().get_request_params(api_url) |
168 | | - non_ascii_filenames = [ |
169 | | - filename |
170 | | - for (field, (filename, content, mimetype)) in params["files"] |
171 | | - if filename is not None and not isascii(filename) |
172 | | - ] |
173 | | - if non_ascii_filenames and not REQUESTS_IS_RFC_7578_COMPLIANT: |
174 | | - # Workaround https://github.com/requests/requests/issues/4652: |
175 | | - # Mailgun expects RFC 7578 compliant multipart/form-data, and is confused |
176 | | - # by Requests/urllib3's improper use of RFC 2231 encoded filename parameters |
177 | | - # ("filename*=utf-8''...") in Content-Disposition headers. |
178 | | - # The workaround is to pre-generate the (non-compliant) form-data body, and |
179 | | - # replace 'filename*={RFC 2231 encoded}' with 'filename="{UTF-8 bytes}"'. |
180 | | - # Replace _only_ filenames that will be problems (not all "filename*=...") |
181 | | - # to minimize potential side effects--e.g., in attached messages that might |
182 | | - # have their own attachments with (correctly) RFC 2231 encoded filenames. |
183 | | - prepared = Request(**params).prepare() |
184 | | - form_data = prepared.body # bytes |
185 | | - for filename in non_ascii_filenames: # text |
186 | | - rfc2231_filename = encode_rfc2231(filename, charset="utf-8") |
187 | | - form_data = form_data.replace( |
188 | | - b"filename*=" + rfc2231_filename.encode("utf-8"), |
189 | | - b'filename="' + filename.encode("utf-8") + b'"', |
190 | | - ) |
191 | | - params["data"] = form_data |
192 | | - # Content-Type: multipart/form-data; boundary=... |
193 | | - params["headers"]["Content-Type"] = prepared.headers["Content-Type"] |
194 | | - params["files"] = None # these are now in the form_data body |
195 | | - return params |
196 | | - |
197 | 145 | def serialize_data(self): |
198 | 146 | self.populate_recipient_variables() |
199 | 147 | return self.data |
|
0 commit comments