We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Add ssl to the web server
It should be possible to enable ssl on the web server and pass in paths to the ssl keys in the config.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `opsdroid/web.py`
Content:
```
1 """Submodule to handle web requests in opsdroid."""
2 
3 import json
4 import logging
5 
6 from aiohttp import web
7 
8 from opsdroid.const import __version__
9 
10 
11 _LOGGER = logging.getLogger(__name__)
12 
13 
14 class Web:
15     """Web server for opsdroid."""
16 
17     def __init__(self, opsdroid):
18         """Create web object."""
19         self.opsdroid = opsdroid
20         try:
21             self.config = self.opsdroid.config["web"]
22         except KeyError:
23             self.config = {}
24         self.web_app = web.Application(loop=self.opsdroid.eventloop)
25         self.web_app.router.add_get('/', self.web_index_handler)
26         self.web_app.router.add_get('', self.web_index_handler)
27         self.web_app.router.add_get('/stats', self.web_stats_handler)
28         self.web_app.router.add_get('/stats/', self.web_stats_handler)
29 
30     @property
31     def get_port(self):
32         """Return port from config or the default."""
33         try:
34             port = self.config["port"]
35         except KeyError:
36             port = 8080
37         return port
38 
39     @property
40     def get_host(self):
41         """Return host from config or the default."""
42         try:
43             host = self.config["host"]
44         except KeyError:
45             host = '127.0.0.1'
46         return host
47 
48     def start(self):
49         """Start web servers."""
50         _LOGGER.debug(
51             "Starting web server with host %s and port %s",
52             self.get_host, self.get_port)
53         web.run_app(self.web_app, host=self.get_host,
54                     port=self.get_port, print=_LOGGER.info)
55 
56     @staticmethod
57     def build_response(status, result):
58         """Build a json response object."""
59         return web.Response(text=json.dumps(result), status=status)
60 
61     def web_index_handler(self, request):
62         """Handle root web request."""
63         return self.build_response(200, {
64             "message": "Welcome to the opsdroid API"})
65 
66     def web_stats_handler(self, request):
67         """Handle stats request."""
68         stats = self.opsdroid.stats
69         try:
70             stats["average_response_time"] = \
71                 stats["total_response_time"] / stats["total_responses"]
72         except ZeroDivisionError:
73             stats["average_response_time"] = 0
74 
75         return self.build_response(200, {
76             "version": __version__,
77             "messages": {
78                 "total_parsed": stats["messages_parsed"],
79                 "webhooks_called": stats["webhooks_called"],
80                 "total_response_time": stats["total_response_time"],
81                 "total_responses": stats["total_responses"],
82                 "average_response_time": stats["average_response_time"]
83             },
84             "modules": {
85                 "skills": len(self.opsdroid.skills),
86                 "connectors": len(self.opsdroid.connectors),
87                 "databases": len(self.opsdroid.memory.databases)
88             }
89         })
90
```
--- 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()

```

diff --git a/opsdroid/web.py b/opsdroid/web.py
--- a/opsdroid/web.py
+++ b/opsdroid/web.py
@@ -2,6 +2,7 @@
 
 import json
 import logging
+import ssl
 
 from aiohttp import web
 
@@ -33,7 +34,10 @@
         try:
             port = self.config["port"]
         except KeyError:
-            port = 8080
+            if self.get_ssl_context is not None:
+                port = 8443
+            else:
+                port = 8080
         return port
 
     @property
@@ -45,13 +49,28 @@
             host = '127.0.0.1'
         return host
 
+    @property
+    def get_ssl_context(self):
+        """Return the ssl context or None."""
+        try:
+            ssl_config = self.config["ssl"]
+            sslcontext = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
+            sslcontext.load_cert_chain(ssl_config["cert"], ssl_config["key"])
+            return sslcontext
+        except FileNotFoundError:
+            _LOGGER.error("Cannot find ssl cert or key.")
+            return None
+        except KeyError:
+            return None
+
     def start(self):
         """Start web servers."""
         _LOGGER.debug(
             "Starting web server with host %s and port %s",
             self.get_host, self.get_port)
         web.run_app(self.web_app, host=self.get_host,
-                    port=self.get_port, print=_LOGGER.info)
+                    port=self.get_port, print=_LOGGER.info,
+                    ssl_context=self.get_ssl_context)
 
     @staticmethod
     def build_response(status, result):

{"golden_diff": "diff --git a/opsdroid/web.py b/opsdroid/web.py\n--- a/opsdroid/web.py\n+++ b/opsdroid/web.py\n@@ -2,6 +2,7 @@\n \n import json\n import logging\n+import ssl\n \n from aiohttp import web\n \n@@ -33,7 +34,10 @@\n         try:\n             port = self.config[\"port\"]\n         except KeyError:\n-            port = 8080\n+            if self.get_ssl_context is not None:\n+                port = 8443\n+            else:\n+                port = 8080\n         return port\n \n     @property\n@@ -45,13 +49,28 @@\n             host = '127.0.0.1'\n         return host\n \n+    @property\n+    def get_ssl_context(self):\n+        \"\"\"Return the ssl context or None.\"\"\"\n+        try:\n+            ssl_config = self.config[\"ssl\"]\n+            sslcontext = ssl.SSLContext(ssl.PROTOCOL_SSLv23)\n+            sslcontext.load_cert_chain(ssl_config[\"cert\"], ssl_config[\"key\"])\n+            return sslcontext\n+        except FileNotFoundError:\n+            _LOGGER.error(\"Cannot find ssl cert or key.\")\n+            return None\n+        except KeyError:\n+            return None\n+\n     def start(self):\n         \"\"\"Start web servers.\"\"\"\n         _LOGGER.debug(\n             \"Starting web server with host %s and port %s\",\n             self.get_host, self.get_port)\n         web.run_app(self.web_app, host=self.get_host,\n-                    port=self.get_port, print=_LOGGER.info)\n+                    port=self.get_port, print=_LOGGER.info,\n+                    ssl_context=self.get_ssl_context)\n \n     @staticmethod\n     def build_response(status, result):\n", "issue": "Add ssl to the web server\nIt should be possible to enable ssl on the web server and pass in paths to the ssl keys in the config.\n", "before_files": [{"content": "\"\"\"Submodule to handle web requests in opsdroid.\"\"\"\n\nimport json\nimport logging\n\nfrom aiohttp import web\n\nfrom opsdroid.const import __version__\n\n\n_LOGGER = logging.getLogger(__name__)\n\n\nclass Web:\n    \"\"\"Web server for opsdroid.\"\"\"\n\n    def __init__(self, opsdroid):\n        \"\"\"Create web object.\"\"\"\n        self.opsdroid = opsdroid\n        try:\n            self.config = self.opsdroid.config[\"web\"]\n        except KeyError:\n            self.config = {}\n        self.web_app = web.Application(loop=self.opsdroid.eventloop)\n        self.web_app.router.add_get('/', self.web_index_handler)\n        self.web_app.router.add_get('', self.web_index_handler)\n        self.web_app.router.add_get('/stats', self.web_stats_handler)\n        self.web_app.router.add_get('/stats/', self.web_stats_handler)\n\n    @property\n    def get_port(self):\n        \"\"\"Return port from config or the default.\"\"\"\n        try:\n            port = self.config[\"port\"]\n        except KeyError:\n            port = 8080\n        return port\n\n    @property\n    def get_host(self):\n        \"\"\"Return host from config or the default.\"\"\"\n        try:\n            host = self.config[\"host\"]\n        except KeyError:\n            host = '127.0.0.1'\n        return host\n\n    def start(self):\n        \"\"\"Start web servers.\"\"\"\n        _LOGGER.debug(\n            \"Starting web server with host %s and port %s\",\n            self.get_host, self.get_port)\n        web.run_app(self.web_app, host=self.get_host,\n                    port=self.get_port, print=_LOGGER.info)\n\n    @staticmethod\n    def build_response(status, result):\n        \"\"\"Build a json response object.\"\"\"\n        return web.Response(text=json.dumps(result), status=status)\n\n    def web_index_handler(self, request):\n        \"\"\"Handle root web request.\"\"\"\n        return self.build_response(200, {\n            \"message\": \"Welcome to the opsdroid API\"})\n\n    def web_stats_handler(self, request):\n        \"\"\"Handle stats request.\"\"\"\n        stats = self.opsdroid.stats\n        try:\n            stats[\"average_response_time\"] = \\\n                stats[\"total_response_time\"] / stats[\"total_responses\"]\n        except ZeroDivisionError:\n            stats[\"average_response_time\"] = 0\n\n        return self.build_response(200, {\n            \"version\": __version__,\n            \"messages\": {\n                \"total_parsed\": stats[\"messages_parsed\"],\n                \"webhooks_called\": stats[\"webhooks_called\"],\n                \"total_response_time\": stats[\"total_response_time\"],\n                \"total_responses\": stats[\"total_responses\"],\n                \"average_response_time\": stats[\"average_response_time\"]\n            },\n            \"modules\": {\n                \"skills\": len(self.opsdroid.skills),\n                \"connectors\": len(self.opsdroid.connectors),\n                \"databases\": len(self.opsdroid.memory.databases)\n            }\n        })\n", "path": "opsdroid/web.py"}], "after_files": [{"content": "\"\"\"Submodule to handle web requests in opsdroid.\"\"\"\n\nimport json\nimport logging\nimport ssl\n\nfrom aiohttp import web\n\nfrom opsdroid.const import __version__\n\n\n_LOGGER = logging.getLogger(__name__)\n\n\nclass Web:\n    \"\"\"Web server for opsdroid.\"\"\"\n\n    def __init__(self, opsdroid):\n        \"\"\"Create web object.\"\"\"\n        self.opsdroid = opsdroid\n        try:\n            self.config = self.opsdroid.config[\"web\"]\n        except KeyError:\n            self.config = {}\n        self.web_app = web.Application(loop=self.opsdroid.eventloop)\n        self.web_app.router.add_get('/', self.web_index_handler)\n        self.web_app.router.add_get('', self.web_index_handler)\n        self.web_app.router.add_get('/stats', self.web_stats_handler)\n        self.web_app.router.add_get('/stats/', self.web_stats_handler)\n\n    @property\n    def get_port(self):\n        \"\"\"Return port from config or the default.\"\"\"\n        try:\n            port = self.config[\"port\"]\n        except KeyError:\n            if self.get_ssl_context is not None:\n                port = 8443\n            else:\n                port = 8080\n        return port\n\n    @property\n    def get_host(self):\n        \"\"\"Return host from config or the default.\"\"\"\n        try:\n            host = self.config[\"host\"]\n        except KeyError:\n            host = '127.0.0.1'\n        return host\n\n    @property\n    def get_ssl_context(self):\n        \"\"\"Return the ssl context or None.\"\"\"\n        try:\n            ssl_config = self.config[\"ssl\"]\n            sslcontext = ssl.SSLContext(ssl.PROTOCOL_SSLv23)\n            sslcontext.load_cert_chain(ssl_config[\"cert\"], ssl_config[\"key\"])\n            return sslcontext\n        except FileNotFoundError:\n            _LOGGER.error(\"Cannot find ssl cert or key.\")\n            return None\n        except KeyError:\n            return None\n\n    def start(self):\n        \"\"\"Start web servers.\"\"\"\n        _LOGGER.debug(\n            \"Starting web server with host %s and port %s\",\n            self.get_host, self.get_port)\n        web.run_app(self.web_app, host=self.get_host,\n                    port=self.get_port, print=_LOGGER.info,\n                    ssl_context=self.get_ssl_context)\n\n    @staticmethod\n    def build_response(status, result):\n        \"\"\"Build a json response object.\"\"\"\n        return web.Response(text=json.dumps(result), status=status)\n\n    def web_index_handler(self, request):\n        \"\"\"Handle root web request.\"\"\"\n        return self.build_response(200, {\n            \"message\": \"Welcome to the opsdroid API\"})\n\n    def web_stats_handler(self, request):\n        \"\"\"Handle stats request.\"\"\"\n        stats = self.opsdroid.stats\n        try:\n            stats[\"average_response_time\"] = \\\n                stats[\"total_response_time\"] / stats[\"total_responses\"]\n        except ZeroDivisionError:\n            stats[\"average_response_time\"] = 0\n\n        return self.build_response(200, {\n            \"version\": __version__,\n            \"messages\": {\n                \"total_parsed\": stats[\"messages_parsed\"],\n                \"webhooks_called\": stats[\"webhooks_called\"],\n                \"total_response_time\": stats[\"total_response_time\"],\n                \"total_responses\": stats[\"total_responses\"],\n                \"average_response_time\": stats[\"average_response_time\"]\n            },\n            \"modules\": {\n                \"skills\": len(self.opsdroid.skills),\n                \"connectors\": len(self.opsdroid.connectors),\n                \"databases\": len(self.opsdroid.memory.databases)\n            }\n        })\n", "path": "opsdroid/web.py"}]}