@@ -36,30 +36,32 @@ async def get_shared_client() -> httpx.AsyncClient:
3636 if _shared_client is not None :
3737 await _shared_client .aclose ()
3838 timeout = httpx .Timeout (connect = 10.0 , read = 30.0 , write = 10.0 , pool = 10.0 )
39+ # follow_redirects=True: Mikan mirrors and some CDNs respond with 302 to the
40+ # canonical host; without this, raise_for_status treats the redirect as an
41+ # error and the RSS pull fails (#983).
42+ common_kwargs = {
43+ "timeout" : timeout ,
44+ "limits" : _CONNECTION_LIMITS ,
45+ "follow_redirects" : True ,
46+ }
3947 if settings .proxy .enable :
4048 if "http" in settings .proxy .type :
4149 if settings .proxy .username :
4250 proxy_url = f"http://{ settings .proxy .username } :{ settings .proxy .password } @{ settings .proxy .host } :{ settings .proxy .port } "
4351 else :
4452 proxy_url = f"http://{ settings .proxy .host } :{ settings .proxy .port } "
45- _shared_client = httpx .AsyncClient (
46- proxy = proxy_url , timeout = timeout , limits = _CONNECTION_LIMITS
47- )
53+ _shared_client = httpx .AsyncClient (proxy = proxy_url , ** common_kwargs )
4854 elif settings .proxy .type == "socks5" :
4955 if settings .proxy .username :
5056 socks_url = f"socks5://{ settings .proxy .username } :{ settings .proxy .password } @{ settings .proxy .host } :{ settings .proxy .port } "
5157 else :
5258 socks_url = f"socks5://{ settings .proxy .host } :{ settings .proxy .port } "
5359 transport = AsyncProxyTransport .from_url (socks_url , rdns = True )
54- _shared_client = httpx .AsyncClient (
55- transport = transport , timeout = timeout , limits = _CONNECTION_LIMITS
56- )
60+ _shared_client = httpx .AsyncClient (transport = transport , ** common_kwargs )
5761 else :
58- _shared_client = httpx .AsyncClient (
59- timeout = timeout , limits = _CONNECTION_LIMITS
60- )
62+ _shared_client = httpx .AsyncClient (** common_kwargs )
6163 else :
62- _shared_client = httpx .AsyncClient (timeout = timeout , limits = _CONNECTION_LIMITS )
64+ _shared_client = httpx .AsyncClient (** common_kwargs )
6365 _shared_client_proxy_key = current_key
6466 return _shared_client
6567
@@ -91,7 +93,9 @@ def _get_headers(self, url: str) -> dict:
9193 }
9294 # For torrent files, use different Accept header
9395 if url .endswith (".torrent" ) or "/download/" in url :
94- base_headers ["Accept" ] = "application/x-bittorrent, application/octet-stream, */*"
96+ base_headers ["Accept" ] = (
97+ "application/x-bittorrent, application/octet-stream, */*"
98+ )
9599 else :
96100 base_headers ["Accept" ] = "application/xml, text/xml, */*"
97101 return base_headers
@@ -102,7 +106,11 @@ async def get_url(self, url, retry=3):
102106 while True :
103107 try :
104108 req = await self ._client .get (url = url , headers = headers )
105- logger .debug ("[Network] Successfully connected to %s. Status: %s" , url , req .status_code )
109+ logger .debug (
110+ "[Network] Successfully connected to %s. Status: %s" ,
111+ url ,
112+ req .status_code ,
113+ )
106114 req .raise_for_status ()
107115 return req
108116 except httpx .HTTPStatusError as e :
@@ -122,16 +130,16 @@ async def get_url(self, url, retry=3):
122130 except Exception as e :
123131 logger .warning (f"[Network] Unexpected error for { url } : { e } " )
124132 break
125- logger .error (f"[Network] Unable to connect to { url } , Please check your network settings" )
133+ logger .error (
134+ f"[Network] Unable to connect to { url } , Please check your network settings"
135+ )
126136 return None
127137
128138 async def post_url (self , url : str , data : dict , retry = 3 ):
129139 try_time = 0
130140 while True :
131141 try :
132- req = await self ._client .post (
133- url = url , headers = self .header , data = data
134- )
142+ req = await self ._client .post (url = url , headers = self .header , data = data )
135143 req .raise_for_status ()
136144 return req
137145 except httpx .RequestError :
0 commit comments