We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Resources loading on Windows (follow-up from #8159)

## Observed behavior
After Promise.polyfill issue was fixed to restore IE11 compatibility in #8159, resources (HTML5, videos) are not loading on all browsers on Windows, but those on Ubuntu Linux are not affected.

HTML on IE11 | HTML on Firefox | videos on FF &  Chrome
--- | --- | --- 
![Win7 (start)  Running  - Oracle VM VirtualBox_039](https://user-images.githubusercontent.com/1457929/122480445-2ae79f00-cfcd-11eb-9cdf-70c5eb78bdfe.jpg) | ![Win7 (start)  Running  - Oracle VM VirtualBox_040](https://user-images.githubusercontent.com/1457929/122480490-3aff7e80-cfcd-11eb-877c-634961f72953.jpg) | ![Win7 (start)  Running  - Oracle VM VirtualBox_041](https://user-images.githubusercontent.com/1457929/122480548-536f9900-cfcd-11eb-8d28-45ebd1a9dc0b.jpg) <br> ![Win7 (start)  Running  - Oracle VM VirtualBox_042](https://user-images.githubusercontent.com/1457929/122480570-5ff3f180-cfcd-11eb-8cb1-b806e5abede3.jpg)

## Errors and logs
…

## Expected behavior
Resources loading correctly on IE11, Firefox and Chrome on Windows.

## User-facing consequences
...

## Steps to reproduce
…

## Context
 * Kolibri version: 0.15/develop
 * Operating system: Windows 7
 * Browser: all

cc @rtibbles 


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `kolibri/utils/kolibri_whitenoise.py`
Content:
```
1 import os
2 import re
3 import stat
4 from collections import OrderedDict
5 
6 from django.contrib.staticfiles import finders
7 from django.core.files.storage import FileSystemStorage
8 from whitenoise import WhiteNoise
9 from whitenoise.string_utils import decode_path_info
10 
11 
12 class FileFinder(finders.FileSystemFinder):
13     """
14     A modified version of the Django FileSystemFinder class
15     which allows us to pass in arbitrary locations to find files
16     """
17 
18     def __init__(self, locations):
19         # List of locations with static files
20         self.locations = []
21         self.prefixes = set()
22         # Maps dir paths to an appropriate storage instance
23         self.storages = OrderedDict()
24         if not isinstance(locations, (list, tuple)):
25             raise TypeError("locations argument is not a tuple or list")
26         for root in locations:
27             prefix, root = root
28             # Django requires paths, even on Windows, to use forward slashes
29             # do this substitution that will be idempotent on Unix
30             root = root.replace(os.sep, "/")
31             if not prefix:
32                 raise ValueError(
33                     "Cannot use unprefixed locations for dynamic locations"
34                 )
35             else:
36                 prefix = prefix.rstrip("/")
37             if (prefix, root) not in self.locations:
38                 self.locations.append((prefix, root))
39             self.prefixes.add(prefix)
40         for prefix, root in self.locations:
41             filesystem_storage = FileSystemStorage(location=root)
42             filesystem_storage.prefix = prefix
43             self.storages[root] = filesystem_storage
44 
45     def find(self, path, all=False):
46         path = path.replace("/", os.sep)
47         return super(FileFinder, self).find(path, all=all)
48 
49 
50 class DynamicWhiteNoise(WhiteNoise):
51     def __init__(self, application, dynamic_locations=None, **kwargs):
52         whitenoise_settings = {
53             # Use 1 day as the default cache time for static assets
54             "max_age": 24 * 60 * 60,
55             # Add a test for any file name that contains a semantic version number
56             # or a 32 digit number (assumed to be a file hash)
57             # these files will be cached indefinitely
58             "immutable_file_test": r"((0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)|[a-f0-9]{32})",
59             "autorefresh": os.environ.get("KOLIBRI_DEVELOPER_MODE", False),
60         }
61         kwargs.update(whitenoise_settings)
62         super(DynamicWhiteNoise, self).__init__(application, **kwargs)
63         self.dynamic_finder = FileFinder(dynamic_locations or [])
64         # Generate a regex to check if a path matches one of our dynamic
65         # location prefixes
66         self.dynamic_check = (
67             re.compile("^({})".format("|".join(self.dynamic_finder.prefixes)))
68             if self.dynamic_finder.prefixes
69             else None
70         )
71 
72     def __call__(self, environ, start_response):
73         path = decode_path_info(environ.get("PATH_INFO", ""))
74         if self.autorefresh:
75             static_file = self.find_file(path)
76         else:
77             static_file = self.files.get(path)
78         if static_file is None:
79             static_file = self.find_and_cache_dynamic_file(path)
80         if static_file is None:
81             return self.application(environ, start_response)
82         else:
83             return self.serve(static_file, environ, start_response)
84 
85     def find_and_cache_dynamic_file(self, url):
86         path = self.get_dynamic_path(url)
87         if path:
88             file_stat = os.stat(path)
89             # Only try to do matches for regular files.
90             if stat.S_ISREG(file_stat.st_mode):
91                 stat_cache = {path: os.stat(path)}
92                 self.add_file_to_dictionary(url, path, stat_cache=stat_cache)
93                 return self.files.get(url)
94 
95     def get_dynamic_path(self, url):
96         if self.dynamic_check is not None and self.dynamic_check.match(url):
97             return self.dynamic_finder.find(url)
98 
99     def candidate_paths_for_url(self, url):
100         paths = super(DynamicWhiteNoise, self).candidate_paths_for_url(url)
101         for path in paths:
102             yield path
103         path = self.get_dynamic_path(url)
104         if path:
105             yield path
106 
107 
108 class DjangoWhiteNoise(DynamicWhiteNoise):
109     def __init__(self, application, static_prefix=None, **kwargs):
110         super(DjangoWhiteNoise, self).__init__(application, **kwargs)
111         self.static_prefix = static_prefix
112         if not self.autorefresh and self.static_prefix:
113             self.add_files_from_finders()
114 
115     def add_files_from_finders(self):
116         files = {}
117         for finder in finders.get_finders():
118             for path, storage in finder.list(None):
119                 prefix = (getattr(storage, "prefix", None) or "").strip("/")
120                 url = u"".join(
121                     (
122                         self.static_prefix,
123                         prefix,
124                         "/" if prefix else "",
125                         path.replace("\\", "/"),
126                     )
127                 )
128                 # Use setdefault as only first matching file should be used
129                 files.setdefault(url, storage.path(path))
130         stat_cache = {path: os.stat(path) for path in files.values()}
131         for url, path in files.items():
132             self.add_file_to_dictionary(url, path, stat_cache=stat_cache)
133 
134     def candidate_paths_for_url(self, url):
135         paths = super(DjangoWhiteNoise, self).candidate_paths_for_url(url)
136         for path in paths:
137             yield path
138         if self.autorefresh and url.startswith(self.static_prefix):
139             path = finders.find(url[len(self.static_prefix) :])
140             if path:
141                 yield path
142
```
--- 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/kolibri/utils/kolibri_whitenoise.py b/kolibri/utils/kolibri_whitenoise.py
--- a/kolibri/utils/kolibri_whitenoise.py
+++ b/kolibri/utils/kolibri_whitenoise.py
@@ -5,6 +5,7 @@
 
 from django.contrib.staticfiles import finders
 from django.core.files.storage import FileSystemStorage
+from django.utils._os import safe_join
 from whitenoise import WhiteNoise
 from whitenoise.string_utils import decode_path_info
 
@@ -25,9 +26,6 @@
             raise TypeError("locations argument is not a tuple or list")
         for root in locations:
             prefix, root = root
-            # Django requires paths, even on Windows, to use forward slashes
-            # do this substitution that will be idempotent on Unix
-            root = root.replace(os.sep, "/")
             if not prefix:
                 raise ValueError(
                     "Cannot use unprefixed locations for dynamic locations"
@@ -42,9 +40,20 @@
             filesystem_storage.prefix = prefix
             self.storages[root] = filesystem_storage
 
-    def find(self, path, all=False):
-        path = path.replace("/", os.sep)
-        return super(FileFinder, self).find(path, all=all)
+    def find_location(self, root, path, prefix=None):
+        """
+        Finds a requested static file in a location, returning the found
+        absolute path (or ``None`` if no match).
+        Vendored from Django to handle being passed a URL path instead of a file path.
+        """
+        if prefix:
+            prefix = prefix + "/"
+            if not path.startswith(prefix):
+                return None
+            path = path[len(prefix) :]
+        path = safe_join(root, path)
+        if os.path.exists(path):
+            return path
 
 
 class DynamicWhiteNoise(WhiteNoise):

{"golden_diff": "diff --git a/kolibri/utils/kolibri_whitenoise.py b/kolibri/utils/kolibri_whitenoise.py\n--- a/kolibri/utils/kolibri_whitenoise.py\n+++ b/kolibri/utils/kolibri_whitenoise.py\n@@ -5,6 +5,7 @@\n \n from django.contrib.staticfiles import finders\n from django.core.files.storage import FileSystemStorage\n+from django.utils._os import safe_join\n from whitenoise import WhiteNoise\n from whitenoise.string_utils import decode_path_info\n \n@@ -25,9 +26,6 @@\n             raise TypeError(\"locations argument is not a tuple or list\")\n         for root in locations:\n             prefix, root = root\n-            # Django requires paths, even on Windows, to use forward slashes\n-            # do this substitution that will be idempotent on Unix\n-            root = root.replace(os.sep, \"/\")\n             if not prefix:\n                 raise ValueError(\n                     \"Cannot use unprefixed locations for dynamic locations\"\n@@ -42,9 +40,20 @@\n             filesystem_storage.prefix = prefix\n             self.storages[root] = filesystem_storage\n \n-    def find(self, path, all=False):\n-        path = path.replace(\"/\", os.sep)\n-        return super(FileFinder, self).find(path, all=all)\n+    def find_location(self, root, path, prefix=None):\n+        \"\"\"\n+        Finds a requested static file in a location, returning the found\n+        absolute path (or ``None`` if no match).\n+        Vendored from Django to handle being passed a URL path instead of a file path.\n+        \"\"\"\n+        if prefix:\n+            prefix = prefix + \"/\"\n+            if not path.startswith(prefix):\n+                return None\n+            path = path[len(prefix) :]\n+        path = safe_join(root, path)\n+        if os.path.exists(path):\n+            return path\n \n \n class DynamicWhiteNoise(WhiteNoise):\n", "issue": "Resources loading on Windows (follow-up from #8159)\n\r\n## Observed behavior\r\nAfter Promise.polyfill issue was fixed to restore IE11 compatibility in #8159, resources (HTML5, videos) are not loading on all browsers on Windows, but those on Ubuntu Linux are not affected.\r\n\r\nHTML on IE11 | HTML on Firefox | videos on FF &  Chrome\r\n--- | --- | --- \r\n![Win7 (start)  Running  - Oracle VM VirtualBox_039](https://user-images.githubusercontent.com/1457929/122480445-2ae79f00-cfcd-11eb-9cdf-70c5eb78bdfe.jpg) | ![Win7 (start)  Running  - Oracle VM VirtualBox_040](https://user-images.githubusercontent.com/1457929/122480490-3aff7e80-cfcd-11eb-877c-634961f72953.jpg) | ![Win7 (start)  Running  - Oracle VM VirtualBox_041](https://user-images.githubusercontent.com/1457929/122480548-536f9900-cfcd-11eb-8d28-45ebd1a9dc0b.jpg) <br> ![Win7 (start)  Running  - Oracle VM VirtualBox_042](https://user-images.githubusercontent.com/1457929/122480570-5ff3f180-cfcd-11eb-8cb1-b806e5abede3.jpg)\r\n\r\n## Errors and logs\r\n\u2026\r\n\r\n## Expected behavior\r\nResources loading correctly on IE11, Firefox and Chrome on Windows.\r\n\r\n## User-facing consequences\r\n...\r\n\r\n## Steps to reproduce\r\n\u2026\r\n\r\n## Context\r\n * Kolibri version: 0.15/develop\r\n * Operating system: Windows 7\r\n * Browser: all\r\n\r\ncc @rtibbles \r\n\n", "before_files": [{"content": "import os\nimport re\nimport stat\nfrom collections import OrderedDict\n\nfrom django.contrib.staticfiles import finders\nfrom django.core.files.storage import FileSystemStorage\nfrom whitenoise import WhiteNoise\nfrom whitenoise.string_utils import decode_path_info\n\n\nclass FileFinder(finders.FileSystemFinder):\n    \"\"\"\n    A modified version of the Django FileSystemFinder class\n    which allows us to pass in arbitrary locations to find files\n    \"\"\"\n\n    def __init__(self, locations):\n        # List of locations with static files\n        self.locations = []\n        self.prefixes = set()\n        # Maps dir paths to an appropriate storage instance\n        self.storages = OrderedDict()\n        if not isinstance(locations, (list, tuple)):\n            raise TypeError(\"locations argument is not a tuple or list\")\n        for root in locations:\n            prefix, root = root\n            # Django requires paths, even on Windows, to use forward slashes\n            # do this substitution that will be idempotent on Unix\n            root = root.replace(os.sep, \"/\")\n            if not prefix:\n                raise ValueError(\n                    \"Cannot use unprefixed locations for dynamic locations\"\n                )\n            else:\n                prefix = prefix.rstrip(\"/\")\n            if (prefix, root) not in self.locations:\n                self.locations.append((prefix, root))\n            self.prefixes.add(prefix)\n        for prefix, root in self.locations:\n            filesystem_storage = FileSystemStorage(location=root)\n            filesystem_storage.prefix = prefix\n            self.storages[root] = filesystem_storage\n\n    def find(self, path, all=False):\n        path = path.replace(\"/\", os.sep)\n        return super(FileFinder, self).find(path, all=all)\n\n\nclass DynamicWhiteNoise(WhiteNoise):\n    def __init__(self, application, dynamic_locations=None, **kwargs):\n        whitenoise_settings = {\n            # Use 1 day as the default cache time for static assets\n            \"max_age\": 24 * 60 * 60,\n            # Add a test for any file name that contains a semantic version number\n            # or a 32 digit number (assumed to be a file hash)\n            # these files will be cached indefinitely\n            \"immutable_file_test\": r\"((0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)|[a-f0-9]{32})\",\n            \"autorefresh\": os.environ.get(\"KOLIBRI_DEVELOPER_MODE\", False),\n        }\n        kwargs.update(whitenoise_settings)\n        super(DynamicWhiteNoise, self).__init__(application, **kwargs)\n        self.dynamic_finder = FileFinder(dynamic_locations or [])\n        # Generate a regex to check if a path matches one of our dynamic\n        # location prefixes\n        self.dynamic_check = (\n            re.compile(\"^({})\".format(\"|\".join(self.dynamic_finder.prefixes)))\n            if self.dynamic_finder.prefixes\n            else None\n        )\n\n    def __call__(self, environ, start_response):\n        path = decode_path_info(environ.get(\"PATH_INFO\", \"\"))\n        if self.autorefresh:\n            static_file = self.find_file(path)\n        else:\n            static_file = self.files.get(path)\n        if static_file is None:\n            static_file = self.find_and_cache_dynamic_file(path)\n        if static_file is None:\n            return self.application(environ, start_response)\n        else:\n            return self.serve(static_file, environ, start_response)\n\n    def find_and_cache_dynamic_file(self, url):\n        path = self.get_dynamic_path(url)\n        if path:\n            file_stat = os.stat(path)\n            # Only try to do matches for regular files.\n            if stat.S_ISREG(file_stat.st_mode):\n                stat_cache = {path: os.stat(path)}\n                self.add_file_to_dictionary(url, path, stat_cache=stat_cache)\n                return self.files.get(url)\n\n    def get_dynamic_path(self, url):\n        if self.dynamic_check is not None and self.dynamic_check.match(url):\n            return self.dynamic_finder.find(url)\n\n    def candidate_paths_for_url(self, url):\n        paths = super(DynamicWhiteNoise, self).candidate_paths_for_url(url)\n        for path in paths:\n            yield path\n        path = self.get_dynamic_path(url)\n        if path:\n            yield path\n\n\nclass DjangoWhiteNoise(DynamicWhiteNoise):\n    def __init__(self, application, static_prefix=None, **kwargs):\n        super(DjangoWhiteNoise, self).__init__(application, **kwargs)\n        self.static_prefix = static_prefix\n        if not self.autorefresh and self.static_prefix:\n            self.add_files_from_finders()\n\n    def add_files_from_finders(self):\n        files = {}\n        for finder in finders.get_finders():\n            for path, storage in finder.list(None):\n                prefix = (getattr(storage, \"prefix\", None) or \"\").strip(\"/\")\n                url = u\"\".join(\n                    (\n                        self.static_prefix,\n                        prefix,\n                        \"/\" if prefix else \"\",\n                        path.replace(\"\\\\\", \"/\"),\n                    )\n                )\n                # Use setdefault as only first matching file should be used\n                files.setdefault(url, storage.path(path))\n        stat_cache = {path: os.stat(path) for path in files.values()}\n        for url, path in files.items():\n            self.add_file_to_dictionary(url, path, stat_cache=stat_cache)\n\n    def candidate_paths_for_url(self, url):\n        paths = super(DjangoWhiteNoise, self).candidate_paths_for_url(url)\n        for path in paths:\n            yield path\n        if self.autorefresh and url.startswith(self.static_prefix):\n            path = finders.find(url[len(self.static_prefix) :])\n            if path:\n                yield path\n", "path": "kolibri/utils/kolibri_whitenoise.py"}], "after_files": [{"content": "import os\nimport re\nimport stat\nfrom collections import OrderedDict\n\nfrom django.contrib.staticfiles import finders\nfrom django.core.files.storage import FileSystemStorage\nfrom django.utils._os import safe_join\nfrom whitenoise import WhiteNoise\nfrom whitenoise.string_utils import decode_path_info\n\n\nclass FileFinder(finders.FileSystemFinder):\n    \"\"\"\n    A modified version of the Django FileSystemFinder class\n    which allows us to pass in arbitrary locations to find files\n    \"\"\"\n\n    def __init__(self, locations):\n        # List of locations with static files\n        self.locations = []\n        self.prefixes = set()\n        # Maps dir paths to an appropriate storage instance\n        self.storages = OrderedDict()\n        if not isinstance(locations, (list, tuple)):\n            raise TypeError(\"locations argument is not a tuple or list\")\n        for root in locations:\n            prefix, root = root\n            if not prefix:\n                raise ValueError(\n                    \"Cannot use unprefixed locations for dynamic locations\"\n                )\n            else:\n                prefix = prefix.rstrip(\"/\")\n            if (prefix, root) not in self.locations:\n                self.locations.append((prefix, root))\n            self.prefixes.add(prefix)\n        for prefix, root in self.locations:\n            filesystem_storage = FileSystemStorage(location=root)\n            filesystem_storage.prefix = prefix\n            self.storages[root] = filesystem_storage\n\n    def find_location(self, root, path, prefix=None):\n        \"\"\"\n        Finds a requested static file in a location, returning the found\n        absolute path (or ``None`` if no match).\n        Vendored from Django to handle being passed a URL path instead of a file path.\n        \"\"\"\n        if prefix:\n            prefix = prefix + \"/\"\n            if not path.startswith(prefix):\n                return None\n            path = path[len(prefix) :]\n        path = safe_join(root, path)\n        if os.path.exists(path):\n            return path\n\n\nclass DynamicWhiteNoise(WhiteNoise):\n    def __init__(self, application, dynamic_locations=None, **kwargs):\n        whitenoise_settings = {\n            # Use 1 day as the default cache time for static assets\n            \"max_age\": 24 * 60 * 60,\n            # Add a test for any file name that contains a semantic version number\n            # or a 32 digit number (assumed to be a file hash)\n            # these files will be cached indefinitely\n            \"immutable_file_test\": r\"((0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)|[a-f0-9]{32})\",\n            \"autorefresh\": os.environ.get(\"KOLIBRI_DEVELOPER_MODE\", False),\n        }\n        kwargs.update(whitenoise_settings)\n        super(DynamicWhiteNoise, self).__init__(application, **kwargs)\n        self.dynamic_finder = FileFinder(dynamic_locations or [])\n        # Generate a regex to check if a path matches one of our dynamic\n        # location prefixes\n        self.dynamic_check = (\n            re.compile(\"^({})\".format(\"|\".join(self.dynamic_finder.prefixes)))\n            if self.dynamic_finder.prefixes\n            else None\n        )\n\n    def __call__(self, environ, start_response):\n        path = decode_path_info(environ.get(\"PATH_INFO\", \"\"))\n        if self.autorefresh:\n            static_file = self.find_file(path)\n        else:\n            static_file = self.files.get(path)\n        if static_file is None:\n            static_file = self.find_and_cache_dynamic_file(path)\n        if static_file is None:\n            return self.application(environ, start_response)\n        else:\n            return self.serve(static_file, environ, start_response)\n\n    def find_and_cache_dynamic_file(self, url):\n        path = self.get_dynamic_path(url)\n        if path:\n            file_stat = os.stat(path)\n            # Only try to do matches for regular files.\n            if stat.S_ISREG(file_stat.st_mode):\n                stat_cache = {path: os.stat(path)}\n                self.add_file_to_dictionary(url, path, stat_cache=stat_cache)\n                return self.files.get(url)\n\n    def get_dynamic_path(self, url):\n        if self.dynamic_check is not None and self.dynamic_check.match(url):\n            return self.dynamic_finder.find(url)\n\n    def candidate_paths_for_url(self, url):\n        paths = super(DynamicWhiteNoise, self).candidate_paths_for_url(url)\n        for path in paths:\n            yield path\n        path = self.get_dynamic_path(url)\n        if path:\n            yield path\n\n\nclass DjangoWhiteNoise(DynamicWhiteNoise):\n    def __init__(self, application, static_prefix=None, **kwargs):\n        super(DjangoWhiteNoise, self).__init__(application, **kwargs)\n        self.static_prefix = static_prefix\n        if not self.autorefresh and self.static_prefix:\n            self.add_files_from_finders()\n\n    def add_files_from_finders(self):\n        files = {}\n        for finder in finders.get_finders():\n            for path, storage in finder.list(None):\n                prefix = (getattr(storage, \"prefix\", None) or \"\").strip(\"/\")\n                url = u\"\".join(\n                    (\n                        self.static_prefix,\n                        prefix,\n                        \"/\" if prefix else \"\",\n                        path.replace(\"\\\\\", \"/\"),\n                    )\n                )\n                # Use setdefault as only first matching file should be used\n                files.setdefault(url, storage.path(path))\n        stat_cache = {path: os.stat(path) for path in files.values()}\n        for url, path in files.items():\n            self.add_file_to_dictionary(url, path, stat_cache=stat_cache)\n\n    def candidate_paths_for_url(self, url):\n        paths = super(DjangoWhiteNoise, self).candidate_paths_for_url(url)\n        for path in paths:\n            yield path\n        if self.autorefresh and url.startswith(self.static_prefix):\n            path = finders.find(url[len(self.static_prefix) :])\n            if path:\n                yield path\n", "path": "kolibri/utils/kolibri_whitenoise.py"}]}