Repository: searx/searx

Issue:
TypeError: key: expected bytes or bytearray, but got 'str'
With searx 0.12.0 I get the following traceback when I set `image_proxy: True` in my `settings.yml`:

```
[2017-07-17 05:26:30,354] ERROR in app: Exception on / [GET]
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/flask/app.py", line 1982, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/lib/python3/dist-packages/flask/app.py", line 1614, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/lib/python3/dist-packages/flask/app.py", line 1517, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/lib/python3/dist-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/usr/lib/python3/dist-packages/flask/app.py", line 1612, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/lib/python3/dist-packages/flask/app.py", line 1598, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/usr/lib/python3/dist-packages/searx/webapp.py", line 572, in index
    favicons=global_favicons[themes.index(get_current_theme_name())]
  File "/usr/lib/python3/dist-packages/searx/webapp.py", line 383, in render
    '{}/{}'.format(kwargs['theme'], template_name), **kwargs)
  File "/usr/lib/python3/dist-packages/flask/templating.py", line 134, in render_template
    context, ctx.app)
  File "/usr/lib/python3/dist-packages/flask/templating.py", line 116, in _render
    rv = template.render(context)
  File "/usr/lib/python3/dist-packages/jinja2/environment.py", line 989, in render
    return self.environment.handle_exception(exc_info, True)
  File "/usr/lib/python3/dist-packages/jinja2/environment.py", line 754, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/lib/python3/dist-packages/jinja2/_compat.py", line 37, in reraise
    raise value.with_traceback(tb)
  File "/usr/share/python3-searx/templates/legacy/results.html", line 1, in top-level template code
    {% extends "legacy/base.html" %}
  File "/usr/share/python3-searx/templates/legacy/base.html", line 25, in top-level template code
    {% block content %}
  File "/usr/share/python3-searx/templates/legacy/results.html", line 65, in block "content"
    {% include get_result_template('legacy', result['template']) %}
  File "/usr/share/python3-searx/templates/legacy/result_templates/images.html", line 3, in top-level template code
    <a href="{{ result.img_src }}" {% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %}><i
mg src="{% if result.thumbnail_src %}{{ image_proxify(result.thumbnail_src) }}{% else %}{{ image_proxify(result.img_src) }}{% endif %}" title="
{{ result.title|striptags }}" alt="{{ result.title|striptags }}" /></a>
  File "/usr/lib/python3/dist-packages/searx/webapp.py", line 291, in image_proxify
    h = hmac.new(settings['server']['secret_key'], url.encode('utf-8'), hashlib.sha256).hexdigest()
  File "/usr/lib/python3.5/hmac.py", line 144, in new
    return HMAC(key, msg, digestmod)
  File "/usr/lib/python3.5/hmac.py", line 42, in __init__
    raise TypeError("key: expected bytes or bytearray, but got %r" % type(key).__name__)
TypeError: key: expected bytes or bytearray, but got 'str'
```


Discussion:

Resolving patch:
diff --git a/searx/utils.py b/searx/utils.py
--- a/searx/utils.py
+++ b/searx/utils.py
@@ -1,4 +1,6 @@
 import csv
+import hashlib
+import hmac
 import os
 import re
 
@@ -321,3 +323,10 @@ def load_module(filename, module_dir):
     module = load_source(modname, filepath)
     module.name = modname
     return module
+
+
+def new_hmac(secret_key, url):
+    if sys.version_info[0] == 2:
+        return hmac.new(bytes(secret_key), url, hashlib.sha256).hexdigest()
+    else:
+        return hmac.new(bytes(secret_key, 'utf-8'), url, hashlib.sha256).hexdigest()
diff --git a/searx/webapp.py b/searx/webapp.py
--- a/searx/webapp.py
+++ b/searx/webapp.py
@@ -69,6 +69,7 @@
 from searx.preferences import Preferences, ValidationException
 from searx.answerers import answerers
 from searx.url_utils import urlencode, urlparse, urljoin
+from searx.utils import new_hmac
 
 # check if the pyopenssl package is installed.
 # It is needed for SSL connection without trouble, see #298
@@ -290,7 +291,7 @@ def image_proxify(url):
     if settings.get('result_proxy'):
         return proxify(url)
 
-    h = hmac.new(settings['server']['secret_key'], url.encode('utf-8'), hashlib.sha256).hexdigest()
+    h = new_hmac(settings['server']['secret_key'], url.encode('utf-8'))
 
     return '{0}?{1}'.format(url_for('image_proxy'),
                             urlencode(dict(url=url.encode('utf-8'), h=h)))
@@ -704,7 +705,7 @@ def image_proxy():
     if not url:
         return '', 400
 
-    h = hmac.new(settings['server']['secret_key'], url, hashlib.sha256).hexdigest()
+    h = new_hmac(settings['server']['secret_key'], url)
 
     if h != request.args.get('h'):
         return '', 400
@@ -731,7 +732,7 @@ def image_proxy():
         logger.debug('image-proxy: wrong content-type: {0}'.format(resp.headers.get('content-type')))
         return '', 400
 
-    img = ''
+    img = b''
     chunk_counter = 0
 
     for chunk in resp.iter_content(1024 * 1024):


Test patch: