.oO SearXNG Developer Documentation Oo.
Loading...
Searching...
No Matches
searx.favicons.proxy Namespace Reference

Classes

class  FaviconProxyConfig
 

Functions

 init (FaviconProxyConfig cfg)
 
 _initial_resolver_map ()
 
 favicon_proxy ()
 
tuple[None|bytes, None|str] search_favicon (str resolver, str authority)
 
str favicon_url (str authority)
 

Variables

dict DEFAULT_FAVICON_URL = {}
 
FaviconProxyConfig CFG = None
 

Detailed Description

Implementations for a favicon proxy

Function Documentation

◆ _initial_resolver_map()

searx.favicons.proxy._initial_resolver_map ( )
protected

Definition at line 35 of file proxy.py.

35def _initial_resolver_map():
36 d = {}
37 name: str = get_setting("search.favicon_resolver", None) # type: ignore
38 if name:
39 func = DEFAULT_RESOLVER_MAP.get(name)
40 if func:
41 d = {name: f"searx.favicons.resolvers.{func.__name__}"}
42 return d
43
44

References searx.get_setting().

+ Here is the call graph for this function:

◆ favicon_proxy()

searx.favicons.proxy.favicon_proxy ( )
REST API of SearXNG's favicon proxy service

::

    /favicon_proxy?authority=<...>&h=<...>

``authority``:
  Domain name :rfc:`3986` / see :py:obj:`favicon_url`

``h``:
  HMAC :rfc:`2104`, build up from the :ref:`server.secret_key <settings
  server>` setting.

Definition at line 113 of file proxy.py.

113def favicon_proxy():
114 """REST API of SearXNG's favicon proxy service
115
116 ::
117
118 /favicon_proxy?authority=<...>&h=<...>
119
120 ``authority``:
121 Domain name :rfc:`3986` / see :py:obj:`favicon_url`
122
123 ``h``:
124 HMAC :rfc:`2104`, build up from the :ref:`server.secret_key <settings
125 server>` setting.
126
127 """
128 authority = sxng_request.args.get('authority')
129
130 # malformed request or RFC 3986 authority
131 if not authority or "/" in authority:
132 return '', 400
133
134 # malformed request / does not have authorisation
135 if not is_hmac_of(
136 CFG.secret_key,
137 authority.encode(),
138 sxng_request.args.get('h', ''),
139 ):
140 return '', 400
141
142 resolver = sxng_request.preferences.get_value('favicon_resolver') # type: ignore
143 # if resolver is empty or not valid, just return HTTP 400.
144 if not resolver or resolver not in CFG.resolver_map.keys():
145 return "", 400
146
147 data, mime = search_favicon(resolver, authority)
148
149 if data is not None and mime is not None:
150 resp = flask.Response(data, mimetype=mime) # type: ignore
151 resp.headers['Cache-Control'] = f"max-age={CFG.max_age}"
152 return resp
153
154 # return default favicon from static path
155 theme = sxng_request.preferences.get_value("theme") # type: ignore
156 fav, mimetype = CFG.favicon(theme=theme)
157 return flask.send_from_directory(fav.parent, fav.name, mimetype=mimetype)
158
159

References search_favicon().

+ Here is the call graph for this function:

◆ favicon_url()

str searx.favicons.proxy.favicon_url ( str authority)
Function to generate the image URL used for favicons in SearXNG's result
lists.  The ``authority`` argument (aka netloc / :rfc:`3986`) is usually a
(sub-) domain name.  This function is used in the HTML (jinja) templates.

.. code:: html

   <div class="favicon">
      <img src="{{ favicon_url(result.parsed_url.netloc) }}">
   </div>

The returned URL is a route to :py:obj:`favicon_proxy` REST API.

If the favicon is already in the cache, the returned URL is a `data URL`_
(something like ``data:image/png;base64,...``).  By generating a data url from
the :py:obj:`.cache.FaviconCache`, additional HTTP roundtripps via the
:py:obj:`favicon_proxy` are saved.  However, it must also be borne in mind
that data urls are not cached in the client (web browser).

.. _data URL: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs

Definition at line 196 of file proxy.py.

196def favicon_url(authority: str) -> str:
197 """Function to generate the image URL used for favicons in SearXNG's result
198 lists. The ``authority`` argument (aka netloc / :rfc:`3986`) is usually a
199 (sub-) domain name. This function is used in the HTML (jinja) templates.
200
201 .. code:: html
202
203 <div class="favicon">
204 <img src="{{ favicon_url(result.parsed_url.netloc) }}">
205 </div>
206
207 The returned URL is a route to :py:obj:`favicon_proxy` REST API.
208
209 If the favicon is already in the cache, the returned URL is a `data URL`_
210 (something like ``data:image/png;base64,...``). By generating a data url from
211 the :py:obj:`.cache.FaviconCache`, additional HTTP roundtripps via the
212 :py:obj:`favicon_proxy` are saved. However, it must also be borne in mind
213 that data urls are not cached in the client (web browser).
214
215 .. _data URL: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs
216
217 """
218
219 resolver = sxng_request.preferences.get_value('favicon_resolver') # type: ignore
220 # if resolver is empty or not valid, just return nothing.
221 if not resolver or resolver not in CFG.resolver_map.keys():
222 return ""
223
224 data_mime = cache.CACHE(resolver, authority)
225
226 if data_mime == (None, None):
227 # we have already checked, the resolver does not have a favicon
228 theme = sxng_request.preferences.get_value("theme") # type: ignore
229 return CFG.favicon_data_url(theme=theme)
230
231 if data_mime is not None:
232 data, mime = data_mime
233 return f"data:{mime};base64,{str(base64.b64encode(data), 'utf-8')}" # type: ignore
234
235 h = new_hmac(CFG.secret_key, authority.encode())
236 proxy_url = flask.url_for('favicon_proxy')
237 query = urllib.parse.urlencode({"authority": authority, "h": h})
238 return f"{proxy_url}?{query}"

◆ init()

searx.favicons.proxy.init ( FaviconProxyConfig cfg)

Definition at line 30 of file proxy.py.

30def init(cfg: FaviconProxyConfig):
31 global CFG # pylint: disable=global-statement
32 CFG = cfg
33
34

◆ search_favicon()

tuple[None | bytes, None | str] searx.favicons.proxy.search_favicon ( str resolver,
str authority )
Sends the request to the favicon resolver and returns a tuple for the
favicon.  The tuple consists of ``(data, mime)``, if the resolver has not
determined a favicon, both values are ``None``.

``data``:
  Binary data of the favicon.

``mime``:
  Mime type of the favicon.

Definition at line 160 of file proxy.py.

160def search_favicon(resolver: str, authority: str) -> tuple[None | bytes, None | str]:
161 """Sends the request to the favicon resolver and returns a tuple for the
162 favicon. The tuple consists of ``(data, mime)``, if the resolver has not
163 determined a favicon, both values are ``None``.
164
165 ``data``:
166 Binary data of the favicon.
167
168 ``mime``:
169 Mime type of the favicon.
170
171 """
172
173 data, mime = (None, None)
174
175 func = CFG.get_resolver(resolver)
176 if func is None:
177 return data, mime
178
179 # to avoid superfluous requests to the resolver, first look in the cache
180 data_mime = cache.CACHE(resolver, authority)
181 if data_mime is not None:
182 return data_mime
183
184 try:
185 data, mime = func(authority, timeout=CFG.resolver_timeout)
186 if data is None or mime is None:
187 data, mime = (None, None)
188
189 except (HTTPError, SearxEngineResponseException):
190 pass
191
192 cache.CACHE.set(resolver, authority, mime, data)
193 return data, mime
194
195

Referenced by favicon_proxy().

+ Here is the caller graph for this function:

Variable Documentation

◆ CFG

FaviconProxyConfig searx.favicons.proxy.CFG = None

Definition at line 27 of file proxy.py.

◆ DEFAULT_FAVICON_URL

dict searx.favicons.proxy.DEFAULT_FAVICON_URL = {}

Definition at line 26 of file proxy.py.