16
16
import logging
17
17
import random
18
18
import time
19
+ from typing import Callable , Dict , Optional , Tuple
19
20
20
21
import attr
21
22
22
23
from twisted .internet import defer
23
24
from twisted .web .client import RedirectAgent , readBody
24
25
from twisted .web .http import stringToDatetime
25
26
from twisted .web .http_headers import Headers
27
+ from twisted .web .iweb import IResponse
26
28
27
29
from synapse .logging .context import make_deferred_yieldable
28
30
from synapse .util import Clock , json_decoder
@@ -99,15 +101,14 @@ def __init__(
99
101
self ._well_known_agent = RedirectAgent (agent )
100
102
self .user_agent = user_agent
101
103
102
- @defer .inlineCallbacks
103
- def get_well_known (self , server_name ):
104
+ async def get_well_known (self , server_name : bytes ) -> WellKnownLookupResult :
104
105
"""Attempt to fetch and parse a .well-known file for the given server
105
106
106
107
Args:
107
- server_name (bytes) : name of the server, from the requested url
108
+ server_name: name of the server, from the requested url
108
109
109
110
Returns:
110
- Deferred[WellKnownLookupResult]: The result of the lookup
111
+ The result of the lookup
111
112
"""
112
113
try :
113
114
prev_result , expiry , ttl = self ._well_known_cache .get_with_expiry (
@@ -124,7 +125,9 @@ def get_well_known(self, server_name):
124
125
# requests for the same server in parallel?
125
126
try :
126
127
with Measure (self ._clock , "get_well_known" ):
127
- result , cache_period = yield self ._fetch_well_known (server_name )
128
+ result , cache_period = await self ._fetch_well_known (
129
+ server_name
130
+ ) # type: Tuple[Optional[bytes], float]
128
131
129
132
except _FetchWellKnownFailure as e :
130
133
if prev_result and e .temporary :
@@ -153,26 +156,25 @@ def get_well_known(self, server_name):
153
156
154
157
return WellKnownLookupResult (delegated_server = result )
155
158
156
- @defer .inlineCallbacks
157
- def _fetch_well_known (self , server_name ):
159
+ async def _fetch_well_known (self , server_name : bytes ) -> Tuple [bytes , float ]:
158
160
"""Actually fetch and parse a .well-known, without checking the cache
159
161
160
162
Args:
161
- server_name (bytes) : name of the server, from the requested url
163
+ server_name: name of the server, from the requested url
162
164
163
165
Raises:
164
166
_FetchWellKnownFailure if we fail to lookup a result
165
167
166
168
Returns:
167
- Deferred[Tuple[bytes,int]]: The lookup result and cache period.
169
+ The lookup result and cache period.
168
170
"""
169
171
170
172
had_valid_well_known = self ._had_valid_well_known_cache .get (server_name , False )
171
173
172
174
# We do this in two steps to differentiate between possibly transient
173
175
# errors (e.g. can't connect to host, 503 response) and more permenant
174
176
# errors (such as getting a 404 response).
175
- response , body = yield self ._make_well_known_request (
177
+ response , body = await self ._make_well_known_request (
176
178
server_name , retry = had_valid_well_known
177
179
)
178
180
@@ -215,20 +217,20 @@ def _fetch_well_known(self, server_name):
215
217
216
218
return result , cache_period
217
219
218
- @defer .inlineCallbacks
219
- def _make_well_known_request (self , server_name , retry ):
220
+ async def _make_well_known_request (
221
+ self , server_name : bytes , retry : bool
222
+ ) -> Tuple [IResponse , bytes ]:
220
223
"""Make the well known request.
221
224
222
225
This will retry the request if requested and it fails (with unable
223
226
to connect or receives a 5xx error).
224
227
225
228
Args:
226
- server_name (bytes)
227
- retry (bool) : Whether to retry the request if it fails.
229
+ server_name: name of the server, from the requested url
230
+ retry: Whether to retry the request if it fails.
228
231
229
232
Returns:
230
- Deferred[tuple[IResponse, bytes]] Returns the response object and
231
- body. Response may be a non-200 response.
233
+ Returns the response object and body. Response may be a non-200 response.
232
234
"""
233
235
uri = b"https://%s/.well-known/matrix/server" % (server_name ,)
234
236
uri_str = uri .decode ("ascii" )
@@ -243,12 +245,12 @@ def _make_well_known_request(self, server_name, retry):
243
245
244
246
logger .info ("Fetching %s" , uri_str )
245
247
try :
246
- response = yield make_deferred_yieldable (
248
+ response = await make_deferred_yieldable (
247
249
self ._well_known_agent .request (
248
250
b"GET" , uri , headers = Headers (headers )
249
251
)
250
252
)
251
- body = yield make_deferred_yieldable (readBody (response ))
253
+ body = await make_deferred_yieldable (readBody (response ))
252
254
253
255
if 500 <= response .code < 600 :
254
256
raise Exception ("Non-200 response %s" % (response .code ,))
@@ -265,21 +267,24 @@ def _make_well_known_request(self, server_name, retry):
265
267
logger .info ("Error fetching %s: %s. Retrying" , uri_str , e )
266
268
267
269
# Sleep briefly in the hopes that they come back up
268
- yield self ._clock .sleep (0.5 )
270
+ await self ._clock .sleep (0.5 )
269
271
270
272
271
- def _cache_period_from_headers (headers , time_now = time .time ):
273
+ def _cache_period_from_headers (
274
+ headers : Headers , time_now : Callable [[], float ] = time .time
275
+ ) -> Optional [float ]:
272
276
cache_controls = _parse_cache_control (headers )
273
277
274
278
if b"no-store" in cache_controls :
275
279
return 0
276
280
277
281
if b"max-age" in cache_controls :
278
- try :
279
- max_age = int (cache_controls [b"max-age" ])
280
- return max_age
281
- except ValueError :
282
- pass
282
+ max_age = cache_controls [b"max-age" ]
283
+ if max_age :
284
+ try :
285
+ return int (max_age )
286
+ except ValueError :
287
+ pass
283
288
284
289
expires = headers .getRawHeaders (b"expires" )
285
290
if expires is not None :
@@ -295,7 +300,7 @@ def _cache_period_from_headers(headers, time_now=time.time):
295
300
return None
296
301
297
302
298
- def _parse_cache_control (headers ) :
303
+ def _parse_cache_control (headers : Headers ) -> Dict [ bytes , Optional [ bytes ]] :
299
304
cache_controls = {}
300
305
for hdr in headers .getRawHeaders (b"cache-control" , []):
301
306
for directive in hdr .split (b"," ):
0 commit comments