We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Add more extensions to IGNORED_EXTENSIONS
A follow-up to https://github.com/scrapy/scrapy/pull/1835. For the record, in my last project I had to also add the following extensions to ignored:

```
{
    '7z', '7zip', 'xz', 'gz', 'tar', 'bz2',   # archives
    'cdr',  # Corel Draw files
    'apk', # Android packages
}
```

cdr and apk look safe; I wonder if we can add .gz: Scrapy decompresses gz responses automatically, so if we add .gz to `IGNORED_EXTENSIONS` spider may stop following e.g. sitemap.xml.gz links. 

On the other hand, for broad crawls most .gz files are archives, and we're filtering out .zip files already.

Updated the list of ignored extension in the linkextractor component
- Added following extension to the list: .7z, .7zip, .bz2, .gz, .tar, .xz, .cdr, .ico, .apk
- Moved archives into the separate section

See scrapy/scrapy#1837 issue for details and discussion.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `scrapy/linkextractors/__init__.py`
Content:
```
1 """
2 scrapy.linkextractors
3 
4 This package contains a collection of Link Extractors.
5 
6 For more info see docs/topics/link-extractors.rst
7 """
8 import re
9 
10 from six.moves.urllib.parse import urlparse
11 from parsel.csstranslator import HTMLTranslator
12 from w3lib.url import canonicalize_url
13 
14 from scrapy.utils.misc import arg_to_iter
15 from scrapy.utils.url import (
16     url_is_from_any_domain, url_has_any_extension,
17 )
18 
19 
20 # common file extensions that are not followed if they occur in links
21 IGNORED_EXTENSIONS = [
22     # images
23     'mng', 'pct', 'bmp', 'gif', 'jpg', 'jpeg', 'png', 'pst', 'psp', 'tif',
24     'tiff', 'ai', 'drw', 'dxf', 'eps', 'ps', 'svg',
25 
26     # audio
27     'mp3', 'wma', 'ogg', 'wav', 'ra', 'aac', 'mid', 'au', 'aiff',
28 
29     # video
30     '3gp', 'asf', 'asx', 'avi', 'mov', 'mp4', 'mpg', 'qt', 'rm', 'swf', 'wmv',
31     'm4a', 'm4v', 'flv',
32 
33     # office suites
34     'xls', 'xlsx', 'ppt', 'pptx', 'pps', 'doc', 'docx', 'odt', 'ods', 'odg',
35     'odp',
36 
37     # other
38     'css', 'pdf', 'exe', 'bin', 'rss', 'zip', 'rar',
39 ]
40 
41 
42 _re_type = type(re.compile("", 0))
43 _matches = lambda url, regexs: any(r.search(url) for r in regexs)
44 _is_valid_url = lambda url: url.split('://', 1)[0] in {'http', 'https', \
45                                                        'file', 'ftp'}
46 
47 
48 class FilteringLinkExtractor(object):
49 
50     _csstranslator = HTMLTranslator()
51 
52     def __init__(self, link_extractor, allow, deny, allow_domains, deny_domains,
53                  restrict_xpaths, canonicalize, deny_extensions, restrict_css, restrict_text):
54 
55         self.link_extractor = link_extractor
56 
57         self.allow_res = [x if isinstance(x, _re_type) else re.compile(x)
58                           for x in arg_to_iter(allow)]
59         self.deny_res = [x if isinstance(x, _re_type) else re.compile(x)
60                          for x in arg_to_iter(deny)]
61 
62         self.allow_domains = set(arg_to_iter(allow_domains))
63         self.deny_domains = set(arg_to_iter(deny_domains))
64 
65         self.restrict_xpaths = tuple(arg_to_iter(restrict_xpaths))
66         self.restrict_xpaths += tuple(map(self._csstranslator.css_to_xpath,
67                                           arg_to_iter(restrict_css)))
68 
69         self.canonicalize = canonicalize
70         if deny_extensions is None:
71             deny_extensions = IGNORED_EXTENSIONS
72         self.deny_extensions = {'.' + e for e in arg_to_iter(deny_extensions)}
73         self.restrict_text = [x if isinstance(x, _re_type) else re.compile(x)
74                               for x in arg_to_iter(restrict_text)]
75 
76     def _link_allowed(self, link):
77         if not _is_valid_url(link.url):
78             return False
79         if self.allow_res and not _matches(link.url, self.allow_res):
80             return False
81         if self.deny_res and _matches(link.url, self.deny_res):
82             return False
83         parsed_url = urlparse(link.url)
84         if self.allow_domains and not url_is_from_any_domain(parsed_url, self.allow_domains):
85             return False
86         if self.deny_domains and url_is_from_any_domain(parsed_url, self.deny_domains):
87             return False
88         if self.deny_extensions and url_has_any_extension(parsed_url, self.deny_extensions):
89             return False
90         if self.restrict_text and not _matches(link.text, self.restrict_text):
91             return False
92         return True
93 
94     def matches(self, url):
95 
96         if self.allow_domains and not url_is_from_any_domain(url, self.allow_domains):
97             return False
98         if self.deny_domains and url_is_from_any_domain(url, self.deny_domains):
99             return False
100 
101         allowed = (regex.search(url) for regex in self.allow_res) if self.allow_res else [True]
102         denied = (regex.search(url) for regex in self.deny_res) if self.deny_res else []
103         return any(allowed) and not any(denied)
104 
105     def _process_links(self, links):
106         links = [x for x in links if self._link_allowed(x)]
107         if self.canonicalize:
108             for link in links:
109                 link.url = canonicalize_url(link.url)
110         links = self.link_extractor._process_links(links)
111         return links
112 
113     def _extract_links(self, *args, **kwargs):
114         return self.link_extractor._extract_links(*args, **kwargs)
115 
116 
117 # Top-level imports
118 from .lxmlhtml import LxmlLinkExtractor as LinkExtractor
119
```
--- 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/scrapy/linkextractors/__init__.py b/scrapy/linkextractors/__init__.py
--- a/scrapy/linkextractors/__init__.py
+++ b/scrapy/linkextractors/__init__.py
@@ -19,23 +19,26 @@
 
 # common file extensions that are not followed if they occur in links
 IGNORED_EXTENSIONS = [
+    # archives
+    '7z', '7zip', 'bz2', 'rar', 'tar', 'tar.gz', 'xz', 'zip',
+
     # images
     'mng', 'pct', 'bmp', 'gif', 'jpg', 'jpeg', 'png', 'pst', 'psp', 'tif',
-    'tiff', 'ai', 'drw', 'dxf', 'eps', 'ps', 'svg',
+    'tiff', 'ai', 'drw', 'dxf', 'eps', 'ps', 'svg', 'cdr', 'ico',
 
     # audio
     'mp3', 'wma', 'ogg', 'wav', 'ra', 'aac', 'mid', 'au', 'aiff',
 
     # video
     '3gp', 'asf', 'asx', 'avi', 'mov', 'mp4', 'mpg', 'qt', 'rm', 'swf', 'wmv',
-    'm4a', 'm4v', 'flv',
+    'm4a', 'm4v', 'flv', 'webm',
 
     # office suites
     'xls', 'xlsx', 'ppt', 'pptx', 'pps', 'doc', 'docx', 'odt', 'ods', 'odg',
     'odp',
 
     # other
-    'css', 'pdf', 'exe', 'bin', 'rss', 'zip', 'rar',
+    'css', 'pdf', 'exe', 'bin', 'rss', 'dmg', 'iso', 'apk'
 ]

{"golden_diff": "diff --git a/scrapy/linkextractors/__init__.py b/scrapy/linkextractors/__init__.py\n--- a/scrapy/linkextractors/__init__.py\n+++ b/scrapy/linkextractors/__init__.py\n@@ -19,23 +19,26 @@\n \n # common file extensions that are not followed if they occur in links\n IGNORED_EXTENSIONS = [\n+    # archives\n+    '7z', '7zip', 'bz2', 'rar', 'tar', 'tar.gz', 'xz', 'zip',\n+\n     # images\n     'mng', 'pct', 'bmp', 'gif', 'jpg', 'jpeg', 'png', 'pst', 'psp', 'tif',\n-    'tiff', 'ai', 'drw', 'dxf', 'eps', 'ps', 'svg',\n+    'tiff', 'ai', 'drw', 'dxf', 'eps', 'ps', 'svg', 'cdr', 'ico',\n \n     # audio\n     'mp3', 'wma', 'ogg', 'wav', 'ra', 'aac', 'mid', 'au', 'aiff',\n \n     # video\n     '3gp', 'asf', 'asx', 'avi', 'mov', 'mp4', 'mpg', 'qt', 'rm', 'swf', 'wmv',\n-    'm4a', 'm4v', 'flv',\n+    'm4a', 'm4v', 'flv', 'webm',\n \n     # office suites\n     'xls', 'xlsx', 'ppt', 'pptx', 'pps', 'doc', 'docx', 'odt', 'ods', 'odg',\n     'odp',\n \n     # other\n-    'css', 'pdf', 'exe', 'bin', 'rss', 'zip', 'rar',\n+    'css', 'pdf', 'exe', 'bin', 'rss', 'dmg', 'iso', 'apk'\n ]\n", "issue": "Add more extensions to IGNORED_EXTENSIONS\nA follow-up to https://github.com/scrapy/scrapy/pull/1835. For the record, in my last project I had to also add the following extensions to ignored:\n\n```\n{\n    '7z', '7zip', 'xz', 'gz', 'tar', 'bz2',   # archives\n    'cdr',  # Corel Draw files\n    'apk', # Android packages\n}\n```\n\ncdr and apk look safe; I wonder if we can add .gz: Scrapy decompresses gz responses automatically, so if we add .gz to `IGNORED_EXTENSIONS` spider may stop following e.g. sitemap.xml.gz links. \n\nOn the other hand, for broad crawls most .gz files are archives, and we're filtering out .zip files already.\n\nUpdated the list of ignored extension in the linkextractor component\n- Added following extension to the list: .7z, .7zip, .bz2, .gz, .tar, .xz, .cdr, .ico, .apk\n- Moved archives into the separate section\n\nSee scrapy/scrapy#1837 issue for details and discussion.\n\n", "before_files": [{"content": "\"\"\"\nscrapy.linkextractors\n\nThis package contains a collection of Link Extractors.\n\nFor more info see docs/topics/link-extractors.rst\n\"\"\"\nimport re\n\nfrom six.moves.urllib.parse import urlparse\nfrom parsel.csstranslator import HTMLTranslator\nfrom w3lib.url import canonicalize_url\n\nfrom scrapy.utils.misc import arg_to_iter\nfrom scrapy.utils.url import (\n    url_is_from_any_domain, url_has_any_extension,\n)\n\n\n# common file extensions that are not followed if they occur in links\nIGNORED_EXTENSIONS = [\n    # images\n    'mng', 'pct', 'bmp', 'gif', 'jpg', 'jpeg', 'png', 'pst', 'psp', 'tif',\n    'tiff', 'ai', 'drw', 'dxf', 'eps', 'ps', 'svg',\n\n    # audio\n    'mp3', 'wma', 'ogg', 'wav', 'ra', 'aac', 'mid', 'au', 'aiff',\n\n    # video\n    '3gp', 'asf', 'asx', 'avi', 'mov', 'mp4', 'mpg', 'qt', 'rm', 'swf', 'wmv',\n    'm4a', 'm4v', 'flv',\n\n    # office suites\n    'xls', 'xlsx', 'ppt', 'pptx', 'pps', 'doc', 'docx', 'odt', 'ods', 'odg',\n    'odp',\n\n    # other\n    'css', 'pdf', 'exe', 'bin', 'rss', 'zip', 'rar',\n]\n\n\n_re_type = type(re.compile(\"\", 0))\n_matches = lambda url, regexs: any(r.search(url) for r in regexs)\n_is_valid_url = lambda url: url.split('://', 1)[0] in {'http', 'https', \\\n                                                       'file', 'ftp'}\n\n\nclass FilteringLinkExtractor(object):\n\n    _csstranslator = HTMLTranslator()\n\n    def __init__(self, link_extractor, allow, deny, allow_domains, deny_domains,\n                 restrict_xpaths, canonicalize, deny_extensions, restrict_css, restrict_text):\n\n        self.link_extractor = link_extractor\n\n        self.allow_res = [x if isinstance(x, _re_type) else re.compile(x)\n                          for x in arg_to_iter(allow)]\n        self.deny_res = [x if isinstance(x, _re_type) else re.compile(x)\n                         for x in arg_to_iter(deny)]\n\n        self.allow_domains = set(arg_to_iter(allow_domains))\n        self.deny_domains = set(arg_to_iter(deny_domains))\n\n        self.restrict_xpaths = tuple(arg_to_iter(restrict_xpaths))\n        self.restrict_xpaths += tuple(map(self._csstranslator.css_to_xpath,\n                                          arg_to_iter(restrict_css)))\n\n        self.canonicalize = canonicalize\n        if deny_extensions is None:\n            deny_extensions = IGNORED_EXTENSIONS\n        self.deny_extensions = {'.' + e for e in arg_to_iter(deny_extensions)}\n        self.restrict_text = [x if isinstance(x, _re_type) else re.compile(x)\n                              for x in arg_to_iter(restrict_text)]\n\n    def _link_allowed(self, link):\n        if not _is_valid_url(link.url):\n            return False\n        if self.allow_res and not _matches(link.url, self.allow_res):\n            return False\n        if self.deny_res and _matches(link.url, self.deny_res):\n            return False\n        parsed_url = urlparse(link.url)\n        if self.allow_domains and not url_is_from_any_domain(parsed_url, self.allow_domains):\n            return False\n        if self.deny_domains and url_is_from_any_domain(parsed_url, self.deny_domains):\n            return False\n        if self.deny_extensions and url_has_any_extension(parsed_url, self.deny_extensions):\n            return False\n        if self.restrict_text and not _matches(link.text, self.restrict_text):\n            return False\n        return True\n\n    def matches(self, url):\n\n        if self.allow_domains and not url_is_from_any_domain(url, self.allow_domains):\n            return False\n        if self.deny_domains and url_is_from_any_domain(url, self.deny_domains):\n            return False\n\n        allowed = (regex.search(url) for regex in self.allow_res) if self.allow_res else [True]\n        denied = (regex.search(url) for regex in self.deny_res) if self.deny_res else []\n        return any(allowed) and not any(denied)\n\n    def _process_links(self, links):\n        links = [x for x in links if self._link_allowed(x)]\n        if self.canonicalize:\n            for link in links:\n                link.url = canonicalize_url(link.url)\n        links = self.link_extractor._process_links(links)\n        return links\n\n    def _extract_links(self, *args, **kwargs):\n        return self.link_extractor._extract_links(*args, **kwargs)\n\n\n# Top-level imports\nfrom .lxmlhtml import LxmlLinkExtractor as LinkExtractor\n", "path": "scrapy/linkextractors/__init__.py"}], "after_files": [{"content": "\"\"\"\nscrapy.linkextractors\n\nThis package contains a collection of Link Extractors.\n\nFor more info see docs/topics/link-extractors.rst\n\"\"\"\nimport re\n\nfrom six.moves.urllib.parse import urlparse\nfrom parsel.csstranslator import HTMLTranslator\nfrom w3lib.url import canonicalize_url\n\nfrom scrapy.utils.misc import arg_to_iter\nfrom scrapy.utils.url import (\n    url_is_from_any_domain, url_has_any_extension,\n)\n\n\n# common file extensions that are not followed if they occur in links\nIGNORED_EXTENSIONS = [\n    # archives\n    '7z', '7zip', 'bz2', 'rar', 'tar', 'tar.gz', 'xz', 'zip',\n\n    # images\n    'mng', 'pct', 'bmp', 'gif', 'jpg', 'jpeg', 'png', 'pst', 'psp', 'tif',\n    'tiff', 'ai', 'drw', 'dxf', 'eps', 'ps', 'svg', 'cdr', 'ico',\n\n    # audio\n    'mp3', 'wma', 'ogg', 'wav', 'ra', 'aac', 'mid', 'au', 'aiff',\n\n    # video\n    '3gp', 'asf', 'asx', 'avi', 'mov', 'mp4', 'mpg', 'qt', 'rm', 'swf', 'wmv',\n    'm4a', 'm4v', 'flv', 'webm',\n\n    # office suites\n    'xls', 'xlsx', 'ppt', 'pptx', 'pps', 'doc', 'docx', 'odt', 'ods', 'odg',\n    'odp',\n\n    # other\n    'css', 'pdf', 'exe', 'bin', 'rss', 'dmg', 'iso', 'apk'\n]\n\n\n_re_type = type(re.compile(\"\", 0))\n_matches = lambda url, regexs: any(r.search(url) for r in regexs)\n_is_valid_url = lambda url: url.split('://', 1)[0] in {'http', 'https', \\\n                                                       'file', 'ftp'}\n\n\nclass FilteringLinkExtractor(object):\n\n    _csstranslator = HTMLTranslator()\n\n    def __init__(self, link_extractor, allow, deny, allow_domains, deny_domains,\n                 restrict_xpaths, canonicalize, deny_extensions, restrict_css, restrict_text):\n\n        self.link_extractor = link_extractor\n\n        self.allow_res = [x if isinstance(x, _re_type) else re.compile(x)\n                          for x in arg_to_iter(allow)]\n        self.deny_res = [x if isinstance(x, _re_type) else re.compile(x)\n                         for x in arg_to_iter(deny)]\n\n        self.allow_domains = set(arg_to_iter(allow_domains))\n        self.deny_domains = set(arg_to_iter(deny_domains))\n\n        self.restrict_xpaths = tuple(arg_to_iter(restrict_xpaths))\n        self.restrict_xpaths += tuple(map(self._csstranslator.css_to_xpath,\n                                          arg_to_iter(restrict_css)))\n\n        self.canonicalize = canonicalize\n        if deny_extensions is None:\n            deny_extensions = IGNORED_EXTENSIONS\n        self.deny_extensions = {'.' + e for e in arg_to_iter(deny_extensions)}\n        self.restrict_text = [x if isinstance(x, _re_type) else re.compile(x)\n                              for x in arg_to_iter(restrict_text)]\n\n    def _link_allowed(self, link):\n        if not _is_valid_url(link.url):\n            return False\n        if self.allow_res and not _matches(link.url, self.allow_res):\n            return False\n        if self.deny_res and _matches(link.url, self.deny_res):\n            return False\n        parsed_url = urlparse(link.url)\n        if self.allow_domains and not url_is_from_any_domain(parsed_url, self.allow_domains):\n            return False\n        if self.deny_domains and url_is_from_any_domain(parsed_url, self.deny_domains):\n            return False\n        if self.deny_extensions and url_has_any_extension(parsed_url, self.deny_extensions):\n            return False\n        if self.restrict_text and not _matches(link.text, self.restrict_text):\n            return False\n        return True\n\n    def matches(self, url):\n\n        if self.allow_domains and not url_is_from_any_domain(url, self.allow_domains):\n            return False\n        if self.deny_domains and url_is_from_any_domain(url, self.deny_domains):\n            return False\n\n        allowed = (regex.search(url) for regex in self.allow_res) if self.allow_res else [True]\n        denied = (regex.search(url) for regex in self.deny_res) if self.deny_res else []\n        return any(allowed) and not any(denied)\n\n    def _process_links(self, links):\n        links = [x for x in links if self._link_allowed(x)]\n        if self.canonicalize:\n            for link in links:\n                link.url = canonicalize_url(link.url)\n        links = self.link_extractor._process_links(links)\n        return links\n\n    def _extract_links(self, *args, **kwargs):\n        return self.link_extractor._extract_links(*args, **kwargs)\n\n\n# Top-level imports\nfrom .lxmlhtml import LxmlLinkExtractor as LinkExtractor\n", "path": "scrapy/linkextractors/__init__.py"}]}