prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  The Source Interface's /journalist-key endpoint returns a 404 instead of the Submission Key
  ## Description
  
  The submission key should be available via the Source Interface at the URL http://[Onion address]/journalist-key, but said URL returns a 404 instead.
  
  ## Steps to Reproduce
  
  - set up a production SecureDrop instance on HW or VMs
  - visit the source interface, click through to the submission page, and click the ``public key`` link.
  
  ## Expected Behavior
  The Source Interface responds with the Submission Key
  
  ## Actual Behavior
  The Source Interface responds with a 404, and the following errors are recorded if logging is enabled:
  ```
  [Thu Jun 13 17:22:12.285962 2019] [authz_core:debug] [pid 7030:tid 3881911650048] mod_authz_core.c(835): [client 127.0.0.1:45900] AH01628: authorization result: granted (no directives), referer: http://fehpa6pmg6ke4i3u.onion/lookup
  [Thu Jun 13 17:22:12.286129 2019] [authz_core:debug] [pid 7030:tid 3881911650048] mod_authz_core.c(835): [client 127.0.0.1:45900] AH01628: authorization result: granted (no directives), referer: http://fehpa6pmg6ke4i3u.onion/lookup
  [Thu Jun 13 17:22:12.415949 2019] [wsgi:error] [pid 7028:tid 3882000488192] [remote 127.0.0.1:20954] mod_wsgi (pid=7028): Exception occurred processing WSGI script '/var/www/source.wsgi'.
  [Thu Jun 13 17:22:12.416036 2019] [wsgi:error] [pid 7028:tid 3882000488192] [remote 127.0.0.1:20954] TypeError: file like object yielded non string type
  [Thu Jun 13 17:22:12.416281 2019] [authz_core:debug] [pid 7030:tid 3881911650048] mod_authz_core.c(835): [client 127.0.0.1:45900] AH01628: authorization result: granted (no directives), referer: http://fehpa6pmg6ke4i3u.onion/lookup
  [Thu Jun 13 17:22:12.416360 2019] [authz_core:debug] [pid 7030:tid 3881911650048] mod_authz_core.c(835): [client 127.0.0.1:45900] AH01628: authorization result: granted (no directives), referer: http://fehpa6pmg6ke4i3u.onion/lookup
  [Thu Jun 13 17:22:13.812032 2019] [authz_core:debug] [pid 7031:tid 3882000144128] mod_authz_core.c(835): [client 127.0.0.1:45902] AH01628: authorization result: granted (no directives), referer: http://fehpa6pmg6ke4i3u.onion/journalist-key
  [Thu Jun 13 17:22:14.587228 2019] [authz_core:debug] [pid 7031:tid 3881991599872] mod_authz_core.c(835): [client 127.0.0.1:45902] AH01628: authorization result: granted (no directives), referer: http://fehpa6pmg6ke4i3u.onion/journalist-key
  [Thu Jun 13 17:22:14.587409 2019] [authz_core:debug] [pid 7031:tid 3881991599872] mod_authz_core.c(835): [client 127.0.0.1:45902] AH01628: authorization result: granted (no directives), referer: http://fehpa6pmg6ke4i3u.onion/journalist-key
  [Thu Jun 13 17:22:15.296269 2019] [authz_core:debug] [pid 7031:tid 3881911961344] mod_authz_core.c(835): [client 127.0.0.1:45902] AH01628: authorization result: granted (no directives), referer: http://fehpa6pmg6ke4i3u.onion/journalist-key
  ```
  
  
  Please provide screenshots where appropriate.
  
  ## Comments
  
  Suggestions to fix, any other relevant information.
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `securedrop/source_app/info.py`
  Content:
  ```
  1 # -*- coding: utf-8 -*-
  2 
  3 from io import StringIO
  4 from flask import Blueprint, render_template, send_file, current_app
  5 
  6 
  7 def make_blueprint(config):
  8     view = Blueprint('info', __name__)
  9 
  10     @view.route('/tor2web-warning')
  11     def tor2web_warning():
  12         return render_template("tor2web-warning.html")
  13 
  14     @view.route('/use-tor')
  15     def recommend_tor_browser():
  16         return render_template("use-tor-browser.html")
  17 
  18     @view.route('/journalist-key')
  19     def download_journalist_pubkey():
  20         journalist_pubkey = current_app.crypto_util.gpg.export_keys(
  21             config.JOURNALIST_KEY)
  22         return send_file(StringIO(journalist_pubkey),
  23                          mimetype="application/pgp-keys",
  24                          attachment_filename=config.JOURNALIST_KEY + ".asc",
  25                          as_attachment=True)
  26 
  27     @view.route('/why-journalist-key')
  28     def why_download_journalist_pubkey():
  29         return render_template("why-journalist-key.html")
  30 
  31     return view
  32
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/securedrop/source_app/info.py b/securedrop/source_app/info.py
  --- a/securedrop/source_app/info.py
  +++ b/securedrop/source_app/info.py
  @@ -1,8 +1,12 @@
   # -*- coding: utf-8 -*-
  -
  -from io import StringIO
  +import six
   from flask import Blueprint, render_template, send_file, current_app
   
  +if six.PY2:
  +    from cStringIO import StringIO  # noqa
  +else:
  +    from io import BytesIO  # noqa
  +
   
   def make_blueprint(config):
       view = Blueprint('info', __name__)
  @@ -19,7 +23,11 @@
       def download_journalist_pubkey():
           journalist_pubkey = current_app.crypto_util.gpg.export_keys(
               config.JOURNALIST_KEY)
  -        return send_file(StringIO(journalist_pubkey),
  +        if six.PY2:
  +            data = StringIO(journalist_pubkey)
  +        else:
  +            data = BytesIO(journalist_pubkey.encode('utf-8'))
  +        return send_file(data,
                            mimetype="application/pgp-keys",
                            attachment_filename=config.JOURNALIST_KEY + ".asc",
                            as_attachment=True)
  
verification_info: {"golden_diff": "diff --git a/securedrop/source_app/info.py b/securedrop/source_app/info.py\n--- a/securedrop/source_app/info.py\n+++ b/securedrop/source_app/info.py\n@@ -1,8 +1,12 @@\n # -*- coding: utf-8 -*-\n-\n-from io import StringIO\n+import six\n from flask import Blueprint, render_template, send_file, current_app\n \n+if six.PY2:\n+    from cStringIO import StringIO  # noqa\n+else:\n+    from io import BytesIO  # noqa\n+\n \n def make_blueprint(config):\n     view = Blueprint('info', __name__)\n@@ -19,7 +23,11 @@\n     def download_journalist_pubkey():\n         journalist_pubkey = current_app.crypto_util.gpg.export_keys(\n             config.JOURNALIST_KEY)\n-        return send_file(StringIO(journalist_pubkey),\n+        if six.PY2:\n+            data = StringIO(journalist_pubkey)\n+        else:\n+            data = BytesIO(journalist_pubkey.encode('utf-8'))\n+        return send_file(data,\n                          mimetype=\"application/pgp-keys\",\n                          attachment_filename=config.JOURNALIST_KEY + \".asc\",\n                          as_attachment=True)\n", "issue": "The Source Interface's /journalist-key endpoint returns a 404 instead of the Submission Key\n## Description\r\n\r\nThe submission key should be available via the Source Interface at the URL http://[Onion address]/journalist-key, but said URL returns a 404 instead.\r\n\r\n## Steps to Reproduce\r\n\r\n- set up a production SecureDrop instance on HW or VMs\r\n- visit the source interface, click through to the submission page, and click the ``public key`` link.\r\n\r\n## Expected Behavior\r\nThe Source Interface responds with the Submission Key\r\n\r\n## Actual Behavior\r\nThe Source Interface responds with a 404, and the following errors are recorded if logging is enabled:\r\n```\r\n[Thu Jun 13 17:22:12.285962 2019] [authz_core:debug] [pid 7030:tid 3881911650048] mod_authz_core.c(835): [client 127.0.0.1:45900] AH01628: authorization result: granted (no directives), referer: http://fehpa6pmg6ke4i3u.onion/lookup\r\n[Thu Jun 13 17:22:12.286129 2019] [authz_core:debug] [pid 7030:tid 3881911650048] mod_authz_core.c(835): [client 127.0.0.1:45900] AH01628: authorization result: granted (no directives), referer: http://fehpa6pmg6ke4i3u.onion/lookup\r\n[Thu Jun 13 17:22:12.415949 2019] [wsgi:error] [pid 7028:tid 3882000488192] [remote 127.0.0.1:20954] mod_wsgi (pid=7028): Exception occurred processing WSGI script '/var/www/source.wsgi'.\r\n[Thu Jun 13 17:22:12.416036 2019] [wsgi:error] [pid 7028:tid 3882000488192] [remote 127.0.0.1:20954] TypeError: file like object yielded non string type\r\n[Thu Jun 13 17:22:12.416281 2019] [authz_core:debug] [pid 7030:tid 3881911650048] mod_authz_core.c(835): [client 127.0.0.1:45900] AH01628: authorization result: granted (no directives), referer: http://fehpa6pmg6ke4i3u.onion/lookup\r\n[Thu Jun 13 17:22:12.416360 2019] [authz_core:debug] [pid 7030:tid 3881911650048] mod_authz_core.c(835): [client 127.0.0.1:45900] AH01628: authorization result: granted (no directives), referer: http://fehpa6pmg6ke4i3u.onion/lookup\r\n[Thu Jun 13 17:22:13.812032 2019] [authz_core:debug] [pid 7031:tid 3882000144128] mod_authz_core.c(835): [client 127.0.0.1:45902] AH01628: authorization result: granted (no directives), referer: http://fehpa6pmg6ke4i3u.onion/journalist-key\r\n[Thu Jun 13 17:22:14.587228 2019] [authz_core:debug] [pid 7031:tid 3881991599872] mod_authz_core.c(835): [client 127.0.0.1:45902] AH01628: authorization result: granted (no directives), referer: http://fehpa6pmg6ke4i3u.onion/journalist-key\r\n[Thu Jun 13 17:22:14.587409 2019] [authz_core:debug] [pid 7031:tid 3881991599872] mod_authz_core.c(835): [client 127.0.0.1:45902] AH01628: authorization result: granted (no directives), referer: http://fehpa6pmg6ke4i3u.onion/journalist-key\r\n[Thu Jun 13 17:22:15.296269 2019] [authz_core:debug] [pid 7031:tid 3881911961344] mod_authz_core.c(835): [client 127.0.0.1:45902] AH01628: authorization result: granted (no directives), referer: http://fehpa6pmg6ke4i3u.onion/journalist-key\r\n```\r\n\r\n\r\nPlease provide screenshots where appropriate.\r\n\r\n## Comments\r\n\r\nSuggestions to fix, any other relevant information.\r\n\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n\nfrom io import StringIO\nfrom flask import Blueprint, render_template, send_file, current_app\n\n\ndef make_blueprint(config):\n    view = Blueprint('info', __name__)\n\n    @view.route('/tor2web-warning')\n    def tor2web_warning():\n        return render_template(\"tor2web-warning.html\")\n\n    @view.route('/use-tor')\n    def recommend_tor_browser():\n        return render_template(\"use-tor-browser.html\")\n\n    @view.route('/journalist-key')\n    def download_journalist_pubkey():\n        journalist_pubkey = current_app.crypto_util.gpg.export_keys(\n            config.JOURNALIST_KEY)\n        return send_file(StringIO(journalist_pubkey),\n                         mimetype=\"application/pgp-keys\",\n                         attachment_filename=config.JOURNALIST_KEY + \".asc\",\n                         as_attachment=True)\n\n    @view.route('/why-journalist-key')\n    def why_download_journalist_pubkey():\n        return render_template(\"why-journalist-key.html\")\n\n    return view\n", "path": "securedrop/source_app/info.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\nimport six\nfrom flask import Blueprint, render_template, send_file, current_app\n\nif six.PY2:\n    from cStringIO import StringIO  # noqa\nelse:\n    from io import BytesIO  # noqa\n\n\ndef make_blueprint(config):\n    view = Blueprint('info', __name__)\n\n    @view.route('/tor2web-warning')\n    def tor2web_warning():\n        return render_template(\"tor2web-warning.html\")\n\n    @view.route('/use-tor')\n    def recommend_tor_browser():\n        return render_template(\"use-tor-browser.html\")\n\n    @view.route('/journalist-key')\n    def download_journalist_pubkey():\n        journalist_pubkey = current_app.crypto_util.gpg.export_keys(\n            config.JOURNALIST_KEY)\n        if six.PY2:\n            data = StringIO(journalist_pubkey)\n        else:\n            data = BytesIO(journalist_pubkey.encode('utf-8'))\n        return send_file(data,\n                         mimetype=\"application/pgp-keys\",\n                         attachment_filename=config.JOURNALIST_KEY + \".asc\",\n                         as_attachment=True)\n\n    @view.route('/why-journalist-key')\n    def why_download_journalist_pubkey():\n        return render_template(\"why-journalist-key.html\")\n\n    return view\n", "path": "securedrop/source_app/info.py"}]}