prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  SearXNG Firefox user-agent doesn't match real Firefox
  **Version of SearXNG, commit number if you are using on master branch and stipulate if you forked SearXNG**
  2022.10.29-fc9986de
  **How did you install SearXNG?**
  Script
  **What happened?**
  SearXNG will send a user-agent such as:  
  `Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0.2) Gecko/20100101 Firefox/106.0.2`
  However, real Firefox looks like this:  
  `Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0) Gecko/20100101 Firefox/106.0`
  
  Firefox does not send servers the patch version the user is running.
  
  **How To Reproduce**
  See https://github.com/searxng/searxng/blob/fc9986de0a21b01c1c8e342a9c4c8c6b96cc7ea2/searx/utils.py#L69-L74 and https://github.com/searxng/searxng/blob/fc9986de0a21b01c1c8e342a9c4c8c6b96cc7ea2/searx/data/useragents.json
  
  To confirm Firefox's behavior, use a Firefox version with non-zero patch version and check its user-agent.
  
  **Expected behavior**
  SearXNG creates a User-Agent header that matches the format of the browser it is pretending to be.
  
  **Additional context**
  Firefox seems to have stopped sending the patch version with the release of Firefox 16: https://web.archive.org/web/20181123134532/https://www.fxsitecompat.com/en-CA/docs/2012/ua-string-no-longer-contains-patch-level-version-number/
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `searxng_extra/update/update_firefox_version.py`
  Content:
  ```
  1 #!/usr/bin/env python
  2 # lint: pylint
  3 # SPDX-License-Identifier: AGPL-3.0-or-later
  4 
  5 """Fetch firefox useragent signatures
  6 
  7 Output file: :origin:`searx/data/useragents.json` (:origin:`CI Update data ...
  8 <.github/workflows/data-update.yml>`).
  9 
  10 """
  11 
  12 import json
  13 import re
  14 from os.path import join
  15 from urllib.parse import urlparse, urljoin
  16 from distutils.version import LooseVersion  # pylint: disable=deprecated-module
  17 
  18 import requests
  19 from lxml import html
  20 from searx import searx_dir
  21 
  22 URL = 'https://ftp.mozilla.org/pub/firefox/releases/'
  23 RELEASE_PATH = '/pub/firefox/releases/'
  24 
  25 NORMAL_REGEX = re.compile(r'^[0-9]+\.[0-9](\.[0-9])?$')
  26 # BETA_REGEX = re.compile(r'.*[0-9]b([0-9\-a-z]+)$')
  27 # ESR_REGEX = re.compile(r'^[0-9]+\.[0-9](\.[0-9])?esr$')
  28 
  29 #
  30 useragents = {
  31     # fmt: off
  32     "versions": (),
  33     "os": ('Windows NT 10.0; Win64; x64',
  34            'X11; Linux x86_64'),
  35     "ua": "Mozilla/5.0 ({os}; rv:{version}) Gecko/20100101 Firefox/{version}",
  36     # fmt: on
  37 }
  38 
  39 
  40 def fetch_firefox_versions():
  41     resp = requests.get(URL, timeout=2.0)
  42     if resp.status_code != 200:
  43         raise Exception("Error fetching firefox versions, HTTP code " + resp.status_code)
  44     dom = html.fromstring(resp.text)
  45     versions = []
  46 
  47     for link in dom.xpath('//a/@href'):
  48         url = urlparse(urljoin(URL, link))
  49         path = url.path
  50         if path.startswith(RELEASE_PATH):
  51             version = path[len(RELEASE_PATH) : -1]
  52             if NORMAL_REGEX.match(version):
  53                 versions.append(LooseVersion(version))
  54 
  55     list.sort(versions, reverse=True)
  56     return versions
  57 
  58 
  59 def fetch_firefox_last_versions():
  60     versions = fetch_firefox_versions()
  61 
  62     result = []
  63     major_last = versions[0].version[0]
  64     major_list = (major_last, major_last - 1)
  65     for version in versions:
  66         major_current = version.version[0]
  67         if major_current in major_list:
  68             result.append(version.vstring)
  69 
  70     return result
  71 
  72 
  73 def get_useragents_filename():
  74     return join(join(searx_dir, "data"), "useragents.json")
  75 
  76 
  77 if __name__ == '__main__':
  78     useragents["versions"] = fetch_firefox_last_versions()
  79     with open(get_useragents_filename(), "w", encoding='utf-8') as f:
  80         json.dump(useragents, f, indent=4, ensure_ascii=False)
  81
  ```
  --- 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/searxng_extra/update/update_firefox_version.py b/searxng_extra/update/update_firefox_version.py
  --- a/searxng_extra/update/update_firefox_version.py
  +++ b/searxng_extra/update/update_firefox_version.py
  @@ -64,8 +64,11 @@
       major_list = (major_last, major_last - 1)
       for version in versions:
           major_current = version.version[0]
  +        minor_current = version.version[1]
           if major_current in major_list:
  -            result.append(version.vstring)
  +            user_agent_version = f'{major_current}.{minor_current}'
  +            if user_agent_version not in result:
  +                result.append(user_agent_version)
   
       return result
  
verification_info: {"golden_diff": "diff --git a/searxng_extra/update/update_firefox_version.py b/searxng_extra/update/update_firefox_version.py\n--- a/searxng_extra/update/update_firefox_version.py\n+++ b/searxng_extra/update/update_firefox_version.py\n@@ -64,8 +64,11 @@\n     major_list = (major_last, major_last - 1)\n     for version in versions:\n         major_current = version.version[0]\n+        minor_current = version.version[1]\n         if major_current in major_list:\n-            result.append(version.vstring)\n+            user_agent_version = f'{major_current}.{minor_current}'\n+            if user_agent_version not in result:\n+                result.append(user_agent_version)\n \n     return result\n", "issue": "SearXNG Firefox user-agent doesn't match real Firefox\n**Version of SearXNG, commit number if you are using on master branch and stipulate if you forked SearXNG**\r\n2022.10.29-fc9986de\r\n**How did you install SearXNG?**\r\nScript\r\n**What happened?**\r\nSearXNG will send a user-agent such as:  \r\n`Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0.2) Gecko/20100101 Firefox/106.0.2`\r\nHowever, real Firefox looks like this:  \r\n`Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0) Gecko/20100101 Firefox/106.0`\r\n\r\nFirefox does not send servers the patch version the user is running.\r\n\r\n**How To Reproduce**\r\nSee https://github.com/searxng/searxng/blob/fc9986de0a21b01c1c8e342a9c4c8c6b96cc7ea2/searx/utils.py#L69-L74 and https://github.com/searxng/searxng/blob/fc9986de0a21b01c1c8e342a9c4c8c6b96cc7ea2/searx/data/useragents.json\r\n\r\nTo confirm Firefox's behavior, use a Firefox version with non-zero patch version and check its user-agent.\r\n\r\n**Expected behavior**\r\nSearXNG creates a User-Agent header that matches the format of the browser it is pretending to be.\r\n\r\n**Additional context**\r\nFirefox seems to have stopped sending the patch version with the release of Firefox 16: https://web.archive.org/web/20181123134532/https://www.fxsitecompat.com/en-CA/docs/2012/ua-string-no-longer-contains-patch-level-version-number/\n", "before_files": [{"content": "#!/usr/bin/env python\n# lint: pylint\n# SPDX-License-Identifier: AGPL-3.0-or-later\n\n\"\"\"Fetch firefox useragent signatures\n\nOutput file: :origin:`searx/data/useragents.json` (:origin:`CI Update data ...\n<.github/workflows/data-update.yml>`).\n\n\"\"\"\n\nimport json\nimport re\nfrom os.path import join\nfrom urllib.parse import urlparse, urljoin\nfrom distutils.version import LooseVersion  # pylint: disable=deprecated-module\n\nimport requests\nfrom lxml import html\nfrom searx import searx_dir\n\nURL = 'https://ftp.mozilla.org/pub/firefox/releases/'\nRELEASE_PATH = '/pub/firefox/releases/'\n\nNORMAL_REGEX = re.compile(r'^[0-9]+\\.[0-9](\\.[0-9])?$')\n# BETA_REGEX = re.compile(r'.*[0-9]b([0-9\\-a-z]+)$')\n# ESR_REGEX = re.compile(r'^[0-9]+\\.[0-9](\\.[0-9])?esr$')\n\n#\nuseragents = {\n    # fmt: off\n    \"versions\": (),\n    \"os\": ('Windows NT 10.0; Win64; x64',\n           'X11; Linux x86_64'),\n    \"ua\": \"Mozilla/5.0 ({os}; rv:{version}) Gecko/20100101 Firefox/{version}\",\n    # fmt: on\n}\n\n\ndef fetch_firefox_versions():\n    resp = requests.get(URL, timeout=2.0)\n    if resp.status_code != 200:\n        raise Exception(\"Error fetching firefox versions, HTTP code \" + resp.status_code)\n    dom = html.fromstring(resp.text)\n    versions = []\n\n    for link in dom.xpath('//a/@href'):\n        url = urlparse(urljoin(URL, link))\n        path = url.path\n        if path.startswith(RELEASE_PATH):\n            version = path[len(RELEASE_PATH) : -1]\n            if NORMAL_REGEX.match(version):\n                versions.append(LooseVersion(version))\n\n    list.sort(versions, reverse=True)\n    return versions\n\n\ndef fetch_firefox_last_versions():\n    versions = fetch_firefox_versions()\n\n    result = []\n    major_last = versions[0].version[0]\n    major_list = (major_last, major_last - 1)\n    for version in versions:\n        major_current = version.version[0]\n        if major_current in major_list:\n            result.append(version.vstring)\n\n    return result\n\n\ndef get_useragents_filename():\n    return join(join(searx_dir, \"data\"), \"useragents.json\")\n\n\nif __name__ == '__main__':\n    useragents[\"versions\"] = fetch_firefox_last_versions()\n    with open(get_useragents_filename(), \"w\", encoding='utf-8') as f:\n        json.dump(useragents, f, indent=4, ensure_ascii=False)\n", "path": "searxng_extra/update/update_firefox_version.py"}], "after_files": [{"content": "#!/usr/bin/env python\n# lint: pylint\n# SPDX-License-Identifier: AGPL-3.0-or-later\n\n\"\"\"Fetch firefox useragent signatures\n\nOutput file: :origin:`searx/data/useragents.json` (:origin:`CI Update data ...\n<.github/workflows/data-update.yml>`).\n\n\"\"\"\n\nimport json\nimport re\nfrom os.path import join\nfrom urllib.parse import urlparse, urljoin\nfrom distutils.version import LooseVersion  # pylint: disable=deprecated-module\n\nimport requests\nfrom lxml import html\nfrom searx import searx_dir\n\nURL = 'https://ftp.mozilla.org/pub/firefox/releases/'\nRELEASE_PATH = '/pub/firefox/releases/'\n\nNORMAL_REGEX = re.compile(r'^[0-9]+\\.[0-9](\\.[0-9])?$')\n# BETA_REGEX = re.compile(r'.*[0-9]b([0-9\\-a-z]+)$')\n# ESR_REGEX = re.compile(r'^[0-9]+\\.[0-9](\\.[0-9])?esr$')\n\n#\nuseragents = {\n    # fmt: off\n    \"versions\": (),\n    \"os\": ('Windows NT 10.0; Win64; x64',\n           'X11; Linux x86_64'),\n    \"ua\": \"Mozilla/5.0 ({os}; rv:{version}) Gecko/20100101 Firefox/{version}\",\n    # fmt: on\n}\n\n\ndef fetch_firefox_versions():\n    resp = requests.get(URL, timeout=2.0)\n    if resp.status_code != 200:\n        raise Exception(\"Error fetching firefox versions, HTTP code \" + resp.status_code)\n    dom = html.fromstring(resp.text)\n    versions = []\n\n    for link in dom.xpath('//a/@href'):\n        url = urlparse(urljoin(URL, link))\n        path = url.path\n        if path.startswith(RELEASE_PATH):\n            version = path[len(RELEASE_PATH) : -1]\n            if NORMAL_REGEX.match(version):\n                versions.append(LooseVersion(version))\n\n    list.sort(versions, reverse=True)\n    return versions\n\n\ndef fetch_firefox_last_versions():\n    versions = fetch_firefox_versions()\n\n    result = []\n    major_last = versions[0].version[0]\n    major_list = (major_last, major_last - 1)\n    for version in versions:\n        major_current = version.version[0]\n        minor_current = version.version[1]\n        if major_current in major_list:\n            user_agent_version = f'{major_current}.{minor_current}'\n            if user_agent_version not in result:\n                result.append(user_agent_version)\n\n    return result\n\n\ndef get_useragents_filename():\n    return join(join(searx_dir, \"data\"), \"useragents.json\")\n\n\nif __name__ == '__main__':\n    useragents[\"versions\"] = fetch_firefox_last_versions()\n    with open(get_useragents_filename(), \"w\", encoding='utf-8') as f:\n        json.dump(useragents, f, indent=4, ensure_ascii=False)\n", "path": "searxng_extra/update/update_firefox_version.py"}]}