.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 201 of file client.py.

201def get_loop():
202 return LOOP
203
204

◆ get_sslcontexts()

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

Definition at line 50 of file client.py.

50def get_sslcontexts(proxy_url=None, cert=None, verify=True, trust_env=True, http2=False):
51 key = (proxy_url, cert, verify, trust_env, http2)
52 if key not in SSLCONTEXTS:
53 SSLCONTEXTS[key] = httpx.create_ssl_context(cert, verify, trust_env, http2)
54 shuffle_ciphers(SSLCONTEXTS[key])
55 return SSLCONTEXTS[key]
56
57

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 140 of file client.py.

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

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 111 of file client.py.

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

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 205 of file client.py.

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

◆ 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 153 of file client.py.

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

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 27 of file client.py.

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

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 22 of file client.py.

◆ LOOP

searx.network.client.LOOP = None

Definition at line 23 of file client.py.

◆ SSLCONTEXTS

dict searx.network.client.SSLCONTEXTS = {}

Definition at line 24 of file client.py.