.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 34 of file proxy.py.

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

◆ 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 112 of file proxy.py.

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

References searx.favicons.proxy.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 195 of file proxy.py.

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

◆ init()

searx.favicons.proxy.init ( FaviconProxyConfig cfg)

Definition at line 29 of file proxy.py.

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

◆ 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 159 of file proxy.py.

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

Referenced by searx.favicons.proxy.favicon_proxy().

+ Here is the caller graph for this function:

Variable Documentation

◆ CFG

FaviconProxyConfig searx.favicons.proxy.CFG = None

Definition at line 26 of file proxy.py.

◆ DEFAULT_FAVICON_URL

dict searx.favicons.proxy.DEFAULT_FAVICON_URL = {}

Definition at line 25 of file proxy.py.