Better handling of HTTP exceptions, and loop through server list URLs. See #86
This commit is contained in:
		
							parent
							
								
									b0e1e58a0b
								
							
						
					
					
						commit
						3ee45cace8
					
				|  | @ -139,6 +139,13 @@ else: | |||
|     del builtins | ||||
| 
 | ||||
| 
 | ||||
| class SpeedtestCliServerListError(Exception): | ||||
|     """Internal Exception class used to indicate to move on to the next | ||||
|     URL for retrieving speedtest.net server details | ||||
| 
 | ||||
|     """ | ||||
| 
 | ||||
| 
 | ||||
| def bound_socket(*args, **kwargs): | ||||
|     """Bind socket to a specified source IP address""" | ||||
| 
 | ||||
|  | @ -177,6 +184,19 @@ def build_request(url, data=None, headers={}): | |||
|     return Request(url, data=data, headers=headers) | ||||
| 
 | ||||
| 
 | ||||
| def catch_request(request): | ||||
|     """Helper function to catch common exceptions encountered when | ||||
|     establishing a connection with a HTTP/HTTPS request | ||||
| 
 | ||||
|     """ | ||||
| 
 | ||||
|     try: | ||||
|         uh = urlopen(request) | ||||
|         return uh | ||||
|     except (HTTPError, URLError, socket.error): | ||||
|         return False | ||||
| 
 | ||||
| 
 | ||||
| class FileGetter(threading.Thread): | ||||
|     """Thread class for retrieving a URL""" | ||||
| 
 | ||||
|  | @ -320,7 +340,10 @@ def getConfig(): | |||
|     """ | ||||
| 
 | ||||
|     request = build_request('http://www.speedtest.net/speedtest-config.php') | ||||
|     uh = urlopen(request) | ||||
|     uh = catch_request(request) | ||||
|     if uh is False: | ||||
|         print_('Could not retrieve speedtest.net configuration') | ||||
|         sys.exit(1) | ||||
|     configxml = [] | ||||
|     while 1: | ||||
|         configxml.append(uh.read(10240)) | ||||
|  | @ -337,7 +360,7 @@ def getConfig(): | |||
|                 'times': root.find('times').attrib, | ||||
|                 'download': root.find('download').attrib, | ||||
|                 'upload': root.find('upload').attrib} | ||||
|         except AttributeError: | ||||
|         except AttributeError:  # Python3 branch | ||||
|             root = DOM.parseString(''.join(configxml)) | ||||
|             config = { | ||||
|                 'client': getAttributesByTagName(root, 'client'), | ||||
|  | @ -357,35 +380,44 @@ def closestServers(client, all=False): | |||
|     distance | ||||
|     """ | ||||
| 
 | ||||
|     url = 'http://www.speedtest.net/speedtest-servers-static.php' | ||||
|     urls = [ | ||||
|         'http://c.speedtest.net/speedtest-servers-static.php', | ||||
|         'http://www.speedtest.net/speedtest-servers-static.php', | ||||
|     ] | ||||
|     servers = {} | ||||
|     for url in urls: | ||||
|         try: | ||||
|             request = build_request(url) | ||||
|     uh = urlopen(request) | ||||
|             uh = catch_request(request) | ||||
|             if uh is False: | ||||
|                 raise SpeedtestCliServerListError | ||||
|             serversxml = [] | ||||
|             while 1: | ||||
|                 serversxml.append(uh.read(10240)) | ||||
|                 if len(serversxml[-1]) == 0: | ||||
|                     break | ||||
|             if int(uh.code) != 200: | ||||
|         return None | ||||
|                 uh.close() | ||||
|                 raise SpeedtestCliServerListError | ||||
|             uh.close() | ||||
|             try: | ||||
|                 try: | ||||
|                     root = ET.fromstring(''.encode().join(serversxml)) | ||||
|                     elements = root.getiterator('server') | ||||
|         except AttributeError: | ||||
|                 except AttributeError:  # Python3 branch | ||||
|                     root = DOM.parseString(''.join(serversxml)) | ||||
|                     elements = root.getElementsByTagName('server') | ||||
|             except SyntaxError: | ||||
|         print_('Failed to parse list of speedtest.net servers') | ||||
|         sys.exit(1) | ||||
|     servers = {} | ||||
|                 raise SpeedtestCliServerListError | ||||
|             for server in elements: | ||||
|                 try: | ||||
|                     attrib = server.attrib | ||||
|                 except AttributeError: | ||||
|                     attrib = dict(list(server.attributes.items())) | ||||
|         d = distance([float(client['lat']), float(client['lon'])], | ||||
|                      [float(attrib.get('lat')), float(attrib.get('lon'))]) | ||||
|                 d = distance([float(client['lat']), | ||||
|                               float(client['lon'])], | ||||
|                              [float(attrib.get('lat')), | ||||
|                               float(attrib.get('lon'))]) | ||||
|                 attrib['d'] = d | ||||
|                 if d not in servers: | ||||
|                     servers[d] = [attrib] | ||||
|  | @ -394,6 +426,12 @@ def closestServers(client, all=False): | |||
|             del root | ||||
|             del serversxml | ||||
|             del elements | ||||
|         except SpeedtestCliServerListError: | ||||
|             continue | ||||
| 
 | ||||
|     if not servers: | ||||
|         print_('Failed to retrieve list of speedtest.net servers') | ||||
|         sys.exit(1) | ||||
| 
 | ||||
|     closest = [] | ||||
|     for d in sorted(servers.keys()): | ||||
|  | @ -688,7 +726,10 @@ def speedtest(): | |||
|         request = build_request('http://www.speedtest.net/api/api.php', | ||||
|                                 data='&'.join(apiData).encode(), | ||||
|                                 headers=headers) | ||||
|         f = urlopen(request) | ||||
|         f = catch_request(request) | ||||
|         if f is False: | ||||
|             print_('Could not submit results to speedtest.net') | ||||
|             sys.exit(1) | ||||
|         response = f.read() | ||||
|         code = f.code | ||||
|         f.close() | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue