diff options
author | Elizabeth Myers <[email protected]> | 2017-09-16 10:01:15 -0500 |
---|---|---|
committer | Elizabeth Myers <[email protected]> | 2017-09-16 10:05:44 -0500 |
commit | 6067aa460478f8cdc9cb1917f10cc0214a92f009 (patch) | |
tree | b92e3b28f1a6956b85a072e4ab56c049f9ee1af9 | |
parent | 99249d153b355c99adf607afccf4d087bdbe522d (diff) | |
download | mastodon.py-6067aa460478f8cdc9cb1917f10cc0214a92f009.tar.gz |
Workaround Mastodon issue with streaming API redirection
Mastodon can be configured to use another address for streaming
server-side. Such a setup is common with certain deployments.
However, due to a bug, Mastodon does not properly issue HTTP redirects
for anything but the endpoint /api/v1/streaming (including subdirs). It
instead gives a 404, causing the request to fail.
The workaround is to hit this path first, checking for any redirects,
and modifying the URL accordingly.
This commit also includes a workaround for behaviour in requests that
causes it to strip the Authorization header from redirected requests.
This is intentional behaviour on the part of requests, but breaks the
redirection done by Mastodon.
Fixes #84
-rw-r--r-- | mastodon/Mastodon.py | 35 |
1 files changed, 34 insertions, 1 deletions
diff --git a/mastodon/Mastodon.py b/mastodon/Mastodon.py index d427444..7b75776 100644 --- a/mastodon/Mastodon.py +++ b/mastodon/Mastodon.py | |||
@@ -1162,7 +1162,40 @@ class Mastodon: | |||
1162 | headers = {'Authorization': 'Bearer ' + self.access_token} | 1162 | headers = {'Authorization': 'Bearer ' + self.access_token} |
1163 | url = self.api_base_url + endpoint | 1163 | url = self.api_base_url + endpoint |
1164 | 1164 | ||
1165 | connection = requests.get(url, headers = headers, data = params, stream = True) | 1165 | # requests session subclass to disable stripping authorization headers |
1166 | class __no_auth_strip_session(requests.Session): | ||
1167 | def rebuild_auth(self, prepared_request, response): | ||
1168 | return | ||
1169 | |||
1170 | # Mastodon can be configured to use another address for streaming. | ||
1171 | # However, due to a bug, Mastodon does not issue 301 Permanently | ||
1172 | # Moved redirects for anything but /api/v1/streaming (including | ||
1173 | # subdirs), instead returning a 404 with no redirect and causing the | ||
1174 | # entire request to fail. | ||
1175 | # | ||
1176 | # The workaround is to hit /api/v1/streaming and see if there is a | ||
1177 | # redirection, and then use the domain it gives us to do the final | ||
1178 | # request. | ||
1179 | if endpoint.startswith("/api/v1/streaming"): | ||
1180 | print("Hi I'm streaming", endpoint) | ||
1181 | stream_base = self.api_base_url + "/api/v1/streaming" | ||
1182 | |||
1183 | with __no_auth_strip_session() as session: | ||
1184 | connection = session.get(stream_base, headers = headers, data = params) | ||
1185 | |||
1186 | if connection.status_code not in (404, 200): | ||
1187 | # 404 is a normal error, raise on anything else | ||
1188 | raise MastodonNetworkError("Could not connect to streaming server: %s" % connection.reason) | ||
1189 | |||
1190 | url = connection.url.replace("/api/v1/streaming", endpoint) | ||
1191 | print("Url redirected:", url) | ||
1192 | |||
1193 | with __no_auth_strip_session() as session: | ||
1194 | # Prevent stripping of authorisation headers on redirect | ||
1195 | connection = session.get(url, headers = headers, data = params, stream = True) | ||
1196 | |||
1197 | if connection.status_code != 200: | ||
1198 | raise MastodonNetworkError("Could not connect to streaming server: %s" % connection.reason) | ||
1166 | 1199 | ||
1167 | class __stream_handle(): | 1200 | class __stream_handle(): |
1168 | def __init__(self, connection): | 1201 | def __init__(self, connection): |