.oO SearXNG Developer Documentation Oo.
Loading...
Searching...
No Matches
searx.network.client Namespace Reference

Classes

class  AsyncHTTPTransportNoHttp
 
class  AsyncProxyTransportFixed
 

Functions

 shuffle_ciphers (ssl_context)
 
 get_sslcontexts (proxy_url=None, cert=None, verify=True, trust_env=True, http2=False)
 
 get_transport_for_socks_proxy (verify, http2, local_address, proxy_url, limit, retries)
 
 get_transport (verify, http2, local_address, proxy_url, limit, retries)
 
 new_client (enable_http, verify, enable_http2, max_connections, max_keepalive_connections, keepalive_expiry, proxies, local_address, retries, max_redirects, hook_log_response)
 
 get_loop ()
 
 init ()
 

Variables

 logger = logger.getChild('searx.network.client')
 
 LOOP = None
 
dict SSLCONTEXTS = {}
 

Function Documentation

◆ get_loop()

searx.network.client.get_loop ( )

Definition at line 205 of file client.py.

205def get_loop():
206 return LOOP
207
208

◆ get_sslcontexts()

searx.network.client.get_sslcontexts ( proxy_url = None,
cert = None,
verify = True,
trust_env = True,
http2 = False )

Definition at line 54 of file client.py.

54def get_sslcontexts(proxy_url=None, cert=None, verify=True, trust_env=True, http2=False):
55 key = (proxy_url, cert, verify, trust_env, http2)
56 if key not in SSLCONTEXTS:
57 SSLCONTEXTS[key] = httpx.create_ssl_context(cert, verify, trust_env, http2)
58 shuffle_ciphers(SSLCONTEXTS[key])
59 return SSLCONTEXTS[key]
60
61

References searx.network.client.shuffle_ciphers().

Referenced by searx.network.client.get_transport(), and searx.network.client.get_transport_for_socks_proxy().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_transport()

searx.network.client.get_transport ( verify,
http2,
local_address,
proxy_url,
limit,
retries )

Definition at line 144 of file client.py.

144def get_transport(verify, http2, local_address, proxy_url, limit, retries):
145 verify = get_sslcontexts(None, None, verify, True, http2) if verify is True else verify
146 return httpx.AsyncHTTPTransport(
147 # pylint: disable=protected-access
148 verify=verify,
149 http2=http2,
150 limits=limit,
151 proxy=httpx._config.Proxy(proxy_url) if proxy_url else None,
152 local_address=local_address,
153 retries=retries,
154 )
155
156

References searx.network.client.get_sslcontexts().

Referenced by searx.network.client.new_client().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_transport_for_socks_proxy()

searx.network.client.get_transport_for_socks_proxy ( verify,
http2,
local_address,
proxy_url,
limit,
retries )

Definition at line 115 of file client.py.

115def get_transport_for_socks_proxy(verify, http2, local_address, proxy_url, limit, retries):
116 # support socks5h (requests compatibility):
117 # https://requests.readthedocs.io/en/master/user/advanced/#socks
118 # socks5:// hostname is resolved on client side
119 # socks5h:// hostname is resolved on proxy side
120 rdns = False
121 socks5h = 'socks5h://'
122 if proxy_url.startswith(socks5h):
123 proxy_url = 'socks5://' + proxy_url[len(socks5h) :]
124 rdns = True
125
126 proxy_type, proxy_host, proxy_port, proxy_username, proxy_password = parse_proxy_url(proxy_url)
127 verify = get_sslcontexts(proxy_url, None, verify, True, http2) if verify is True else verify
128 return AsyncProxyTransportFixed(
129 proxy_type=proxy_type,
130 proxy_host=proxy_host,
131 proxy_port=proxy_port,
132 username=proxy_username,
133 password=proxy_password,
134 rdns=rdns,
135 loop=get_loop(),
136 verify=verify,
137 http2=http2,
138 local_address=local_address,
139 limits=limit,
140 retries=retries,
141 )
142
143

References searx.network.client.get_sslcontexts().

Referenced by searx.network.client.new_client().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ init()

searx.network.client.init ( )

Definition at line 209 of file client.py.

209def init():
210 # log
211 for logger_name in (
212 'httpx',
213 'httpcore.proxy',
214 'httpcore.connection',
215 'httpcore.http11',
216 'httpcore.http2',
217 'hpack.hpack',
218 'hpack.table',
219 ):
220 logging.getLogger(logger_name).setLevel(logging.WARNING)
221
222 # loop
223 def loop_thread():
224 global LOOP
225 LOOP = asyncio.new_event_loop()
226 LOOP.run_forever()
227
228 thread = threading.Thread(
229 target=loop_thread,
230 name='asyncio_loop',
231 daemon=True,
232 )
233 thread.start()
234
235

References searx.network.client.init().

Referenced by searx.network.client.init().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ new_client()

searx.network.client.new_client ( enable_http,
verify,
enable_http2,
max_connections,
max_keepalive_connections,
keepalive_expiry,
proxies,
local_address,
retries,
max_redirects,
hook_log_response )

Definition at line 157 of file client.py.

170):
171 limit = httpx.Limits(
172 max_connections=max_connections,
173 max_keepalive_connections=max_keepalive_connections,
174 keepalive_expiry=keepalive_expiry,
175 )
176 # See https://www.python-httpx.org/advanced/#routing
177 mounts = {}
178 for pattern, proxy_url in proxies.items():
179 if not enable_http and pattern.startswith('http://'):
180 continue
181 if proxy_url.startswith('socks4://') or proxy_url.startswith('socks5://') or proxy_url.startswith('socks5h://'):
182 mounts[pattern] = get_transport_for_socks_proxy(
183 verify, enable_http2, local_address, proxy_url, limit, retries
184 )
185 else:
186 mounts[pattern] = get_transport(verify, enable_http2, local_address, proxy_url, limit, retries)
187
188 if not enable_http:
189 mounts['http://'] = AsyncHTTPTransportNoHttp()
190
191 transport = get_transport(verify, enable_http2, local_address, None, limit, retries)
192
193 event_hooks = None
194 if hook_log_response:
195 event_hooks = {'response': [hook_log_response]}
196
197 return httpx.AsyncClient(
198 transport=transport,
199 mounts=mounts,
200 max_redirects=max_redirects,
201 event_hooks=event_hooks,
202 )
203
204

References searx.network.client.get_transport(), and searx.network.client.get_transport_for_socks_proxy().

+ Here is the call graph for this function:

◆ shuffle_ciphers()

searx.network.client.shuffle_ciphers ( ssl_context)
Shuffle httpx's default ciphers of a SSL context randomly.

From `What Is TLS Fingerprint and How to Bypass It`_

> When implementing TLS fingerprinting, servers can't operate based on a
> locked-in whitelist database of fingerprints.  New fingerprints appear
> when web clients or TLS libraries release new versions. So, they have to
> live off a blocklist database instead.
> ...
> It's safe to leave the first three as is but shuffle the remaining ciphers
> and you can bypass the TLS fingerprint check.

.. _What Is TLS Fingerprint and How to Bypass It:
   https://www.zenrows.com/blog/what-is-tls-fingerprint#how-to-bypass-tls-fingerprinting

Definition at line 31 of file client.py.

31def shuffle_ciphers(ssl_context):
32 """Shuffle httpx's default ciphers of a SSL context randomly.
33
34 From `What Is TLS Fingerprint and How to Bypass It`_
35
36 > When implementing TLS fingerprinting, servers can't operate based on a
37 > locked-in whitelist database of fingerprints. New fingerprints appear
38 > when web clients or TLS libraries release new versions. So, they have to
39 > live off a blocklist database instead.
40 > ...
41 > It's safe to leave the first three as is but shuffle the remaining ciphers
42 > and you can bypass the TLS fingerprint check.
43
44 .. _What Is TLS Fingerprint and How to Bypass It:
45 https://www.zenrows.com/blog/what-is-tls-fingerprint#how-to-bypass-tls-fingerprinting
46
47 """
48 c_list = httpx._config.DEFAULT_CIPHERS.split(':') # pylint: disable=protected-access
49 sc_list, c_list = c_list[:3], c_list[3:]
50 random.shuffle(c_list)
51 ssl_context.set_ciphers(":".join(sc_list + c_list))
52
53

Referenced by searx.network.client.get_sslcontexts().

+ Here is the caller graph for this function:

Variable Documentation

◆ logger

searx.network.client.logger = logger.getChild('searx.network.client')

Definition at line 26 of file client.py.

◆ LOOP

searx.network.client.LOOP = None

Definition at line 27 of file client.py.

◆ SSLCONTEXTS

dict searx.network.client.SSLCONTEXTS = {}

Definition at line 28 of file client.py.