21
21
import base64
22
22
import json
23
23
import sys
24
- from urlparse import urlparse , urlunparse
24
+
25
+ from six .moves .urllib import parse as urlparse
25
26
26
27
import nacl .signing
27
28
import requests
@@ -145,7 +146,7 @@ def request_json(method, origin_name, origin_key, destination, path, content):
145
146
146
147
for key , sig in signed_json ["signatures" ][origin_name ].items ():
147
148
header = "X-Matrix origin=%s,key=\" %s\" ,sig=\" %s\" " % (origin_name , key , sig )
148
- authorization_headers .append (bytes ( header ))
149
+ authorization_headers .append (header . encode ( "ascii" ))
149
150
print ("Authorization: %s" % header , file = sys .stderr )
150
151
151
152
dest = "matrix://%s%s" % (destination , path )
@@ -250,7 +251,7 @@ def read_args_from_config(args):
250
251
251
252
class MatrixConnectionAdapter (HTTPAdapter ):
252
253
@staticmethod
253
- def lookup (s ):
254
+ def lookup (s , skip_well_known = False ):
254
255
if s [- 1 ] == ']' :
255
256
# ipv6 literal (with no port)
256
257
return s , 8448
@@ -263,19 +264,51 @@ def lookup(s):
263
264
raise ValueError ("Invalid host:port '%s'" % s )
264
265
return out [0 ], port
265
266
267
+ # try a .well-known lookup
268
+ if not skip_well_known :
269
+ well_known = MatrixConnectionAdapter .get_well_known (s )
270
+ if well_known :
271
+ return MatrixConnectionAdapter .lookup (
272
+ well_known , skip_well_known = True
273
+ )
274
+
266
275
try :
267
276
srv = srvlookup .lookup ("matrix" , "tcp" , s )[0 ]
268
277
return srv .host , srv .port
269
278
except Exception :
270
279
return s , 8448
271
280
281
+ @staticmethod
282
+ def get_well_known (server_name ):
283
+ uri = "https://%s/.well-known/matrix/server" % (server_name , )
284
+ print ("fetching %s" % (uri , ), file = sys .stderr )
285
+
286
+ try :
287
+ resp = requests .get (uri )
288
+ if resp .status_code != 200 :
289
+ print ("%s gave %i" % (uri , resp .status_code ), file = sys .stderr )
290
+ return None
291
+
292
+ parsed_well_known = resp .json ()
293
+ if not isinstance (parsed_well_known , dict ):
294
+ raise Exception ("not a dict" )
295
+ if "m.server" not in parsed_well_known :
296
+ raise Exception ("Missing key 'm.server'" )
297
+ new_name = parsed_well_known ['m.server' ]
298
+ print ("well-known lookup gave %s" % (new_name , ), file = sys .stderr )
299
+ return new_name
300
+
301
+ except Exception as e :
302
+ print ("Invalid response from %s: %s" % (uri , e , ), file = sys .stderr )
303
+ return None
304
+
272
305
def get_connection (self , url , proxies = None ):
273
- parsed = urlparse (url )
306
+ parsed = urlparse . urlparse (url )
274
307
275
308
(host , port ) = self .lookup (parsed .netloc )
276
309
netloc = "%s:%d" % (host , port )
277
310
print ("Connecting to %s" % (netloc ,), file = sys .stderr )
278
- url = urlunparse (
311
+ url = urlparse . urlunparse (
279
312
("https" , netloc , parsed .path , parsed .params , parsed .query , parsed .fragment )
280
313
)
281
314
return super (MatrixConnectionAdapter , self ).get_connection (url , proxies )
0 commit comments