prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Add a rst file for useragents.
  There is no rst file for the useragents module, so there is no documentation on readthedocs either.
  
  Found in #211.
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `pwnlib/util/web.py`
  Content:
  ```
  1 # -*- coding: utf-8 -*-
  2 import os, tempfile, logging
  3 from .misc import size
  4 log = logging.getLogger(__name__)
  5 
  6 def wget(url, save=None, timeout=5, **kwargs):
  7     """wget(url, save=None, timeout=5) -> str
  8 
  9     Downloads a file via HTTP/HTTPS.
  10 
  11     Args:
  12       url (str): URL to download
  13       save (str or bool): Name to save as.  Any truthy value
  14             will auto-generate a name based on the URL.
  15       timeout (int): Timeout, in seconds
  16 
  17     Example:
  18 
  19       >>> url    = 'http://httpbin.org/robots.txt'
  20       >>> with context.local(log_level='ERROR'): result = wget(url)
  21       >>> result
  22       'User-agent: *\nDisallow: /deny\n'
  23       >>> with context.local(log_level='ERROR'): wget(url, True)
  24       >>> result == file('robots.txt').read()
  25       True
  26     """
  27     import requests
  28 
  29     with log.progress("Downloading '%s'" % url) as w:
  30         w.status("Making request...")
  31 
  32         response = requests.get(url, stream=True, **kwargs)
  33 
  34         if not response.ok:
  35             w.failure("Got code %s" % response.status_code)
  36             return
  37 
  38         total_size = int(response.headers.get('content-length',0))
  39 
  40         w.status('0 / %s' % size(total_size))
  41 
  42         # Find out the next largest size we can represent as
  43         chunk_size = 1
  44         while chunk_size < (total_size/10):
  45             chunk_size *= 1000
  46 
  47         # Count chunks as they're received
  48         total_data    = ''
  49 
  50         # Loop until we have all of the data
  51         for chunk in response.iter_content(chunk_size = 2**10):
  52             total_data    += chunk
  53             if total_size:
  54                 w.status('%s / %s' % (size(total_data), size(total_size)))
  55             else:
  56                 w.status('%s' % size(total_data))
  57 
  58         # Save to the target file if provided
  59         if save:
  60             if not isinstance(save, (str, unicode)):
  61                 save = os.path.basename(url)
  62                 save = save or tempfile.NamedTemporaryFile(dir='.', delete=False).name
  63             with file(save,'wb+') as f:
  64                 f.write(total_data)
  65                 w.success('Saved %r (%s)' % (f.name, size(total_data)))
  66         else:
  67             w.success('%s' % size(total_data))
  68 
  69         return total_data
  70 
  71
  ```
  
  Path: `pwnlib/util/hashes.py`
  Content:
  ```
  1 import hashlib
  2 
  3 for _algo in hashlib.algorithms:
  4     def _closure():
  5         hash = hashlib.__dict__[_algo]
  6         def file(p):
  7             h = hash()
  8             fd = open(p)
  9             while True:
  10                 s = fd.read(4096)
  11                 if not s:
  12                     break
  13                 h.update(s)
  14             fd.close()
  15             return h
  16         def sum(s):
  17             return hash(s)
  18         filef = lambda x: file(x).digest()
  19         filef.__doc__ = 'Calculates the %s sum of a file' % _algo
  20         sumf = lambda x: sum(x).digest()
  21         sumf.__doc__ = 'Calculates the %s sum of a string' % _algo
  22         fileh = lambda x: file(x).hexdigest()
  23         fileh.__doc__ = 'Calculates the %s sum of a file; returns hex-encoded' % _algo
  24         sumh = lambda x: sum(x).hexdigest()
  25         sumh.__doc__ = 'Calculates the %s sum of a string; returns hex-encoded' % _algo
  26         return filef, sumf, fileh, sumh
  27     (globals()[_algo + 'file'],
  28      globals()[_algo + 'sum'],
  29      globals()[_algo + 'filehex'],
  30      globals()[_algo + 'sumhex']) = _closure()
  31
  ```
  
  Path: `pwnlib/useragents.py`
  Content:
  ```
  1 """
  2 Database of 22,000 user agent strings
  3 """
  4 __all__ = ['getall', 'random']
  5 
  6 import os, random as randommod
  7 
  8 _cache = None
  9 
  10 def _load():
  11     global _cache
  12     if _cache is None:
  13         _cache = set()
  14         with open(os.path.join(os.path.dirname(__file__),
  15                                'data/useragents/useragents.txt'
  16                                ), 'r') as fd:
  17             for line in fd:
  18                 if line:
  19                     _cache.add(line.strip())
  20     return _cache
  21 
  22 def getall():
  23     """getall() -> str set
  24 
  25     Get all the user agents that we know about.
  26 
  27     Args:
  28         None
  29 
  30     Returns:
  31         A set of user agent strings.
  32 
  33     Examples:
  34         >>> 'libcurl-agent/1.0' in getall()
  35         True
  36         >>> 'wget' in getall()
  37         True
  38     """
  39     return _load().copy()
  40 
  41 def random():
  42     """random() -> str
  43 
  44     Get a random user agent string.
  45 
  46     Args:
  47         None
  48 
  49     Returns:
  50         A random user agent string selected from :func:`getall`.
  51 
  52     >>> import random as randommod
  53     >>> randommod.seed(1)
  54     >>> random()
  55     'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; FDM)'
  56     """
  57     return randommod.choice(list(_load()))
  58
  ```
  --- 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/pwnlib/useragents.py b/pwnlib/useragents.py
  --- a/pwnlib/useragents.py
  +++ b/pwnlib/useragents.py
  @@ -1,5 +1,5 @@
   """
  -Database of 22,000 user agent strings
  +Database of >22,000 user agent strings
   """
   __all__ = ['getall', 'random']
   
  @@ -52,6 +52,6 @@
       >>> import random as randommod
       >>> randommod.seed(1)
       >>> random()
  -    'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; FDM)'
  +    'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; FunWebProducts; FunWebProducts-MyTotalSearch; iebar)'
       """
       return randommod.choice(list(_load()))
  diff --git a/pwnlib/util/hashes.py b/pwnlib/util/hashes.py
  --- a/pwnlib/util/hashes.py
  +++ b/pwnlib/util/hashes.py
  @@ -1,3 +1,6 @@
  +"""
  +Functions for computing various hashes of files and strings.
  +"""
   import hashlib
   
   for _algo in hashlib.algorithms:
  diff --git a/pwnlib/util/web.py b/pwnlib/util/web.py
  --- a/pwnlib/util/web.py
  +++ b/pwnlib/util/web.py
  @@ -17,10 +17,12 @@
       Example:
   
         >>> url    = 'http://httpbin.org/robots.txt'
  -      >>> with context.local(log_level='ERROR'): result = wget(url)
  +      >>> with context.local(log_level='ERROR'):
  +      ...     result = wget(url)
         >>> result
  -      'User-agent: *\nDisallow: /deny\n'
  -      >>> with context.local(log_level='ERROR'): wget(url, True)
  +      'User-agent: *\\nDisallow: /deny\\n'
  +      >>> with context.local(log_level='ERROR'):
  +      ...     _ = wget(url, True)
         >>> result == file('robots.txt').read()
         True
       """
  @@ -67,4 +69,3 @@
               w.success('%s' % size(total_data))
   
           return total_data
  -
  
verification_info: {"golden_diff": "diff --git a/pwnlib/useragents.py b/pwnlib/useragents.py\n--- a/pwnlib/useragents.py\n+++ b/pwnlib/useragents.py\n@@ -1,5 +1,5 @@\n \"\"\"\n-Database of 22,000 user agent strings\n+Database of >22,000 user agent strings\n \"\"\"\n __all__ = ['getall', 'random']\n \n@@ -52,6 +52,6 @@\n     >>> import random as randommod\n     >>> randommod.seed(1)\n     >>> random()\n-    'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; FDM)'\n+    'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; FunWebProducts; FunWebProducts-MyTotalSearch; iebar)'\n     \"\"\"\n     return randommod.choice(list(_load()))\ndiff --git a/pwnlib/util/hashes.py b/pwnlib/util/hashes.py\n--- a/pwnlib/util/hashes.py\n+++ b/pwnlib/util/hashes.py\n@@ -1,3 +1,6 @@\n+\"\"\"\n+Functions for computing various hashes of files and strings.\n+\"\"\"\n import hashlib\n \n for _algo in hashlib.algorithms:\ndiff --git a/pwnlib/util/web.py b/pwnlib/util/web.py\n--- a/pwnlib/util/web.py\n+++ b/pwnlib/util/web.py\n@@ -17,10 +17,12 @@\n     Example:\n \n       >>> url    = 'http://httpbin.org/robots.txt'\n-      >>> with context.local(log_level='ERROR'): result = wget(url)\n+      >>> with context.local(log_level='ERROR'):\n+      ...     result = wget(url)\n       >>> result\n-      'User-agent: *\\nDisallow: /deny\\n'\n-      >>> with context.local(log_level='ERROR'): wget(url, True)\n+      'User-agent: *\\\\nDisallow: /deny\\\\n'\n+      >>> with context.local(log_level='ERROR'):\n+      ...     _ = wget(url, True)\n       >>> result == file('robots.txt').read()\n       True\n     \"\"\"\n@@ -67,4 +69,3 @@\n             w.success('%s' % size(total_data))\n \n         return total_data\n-\n", "issue": "Add a rst file for useragents.\nThere is no rst file for the useragents module, so there is no documentation on readthedocs either.\n\nFound in #211.\n\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\nimport os, tempfile, logging\nfrom .misc import size\nlog = logging.getLogger(__name__)\n\ndef wget(url, save=None, timeout=5, **kwargs):\n    \"\"\"wget(url, save=None, timeout=5) -> str\n\n    Downloads a file via HTTP/HTTPS.\n\n    Args:\n      url (str): URL to download\n      save (str or bool): Name to save as.  Any truthy value\n            will auto-generate a name based on the URL.\n      timeout (int): Timeout, in seconds\n\n    Example:\n\n      >>> url    = 'http://httpbin.org/robots.txt'\n      >>> with context.local(log_level='ERROR'): result = wget(url)\n      >>> result\n      'User-agent: *\\nDisallow: /deny\\n'\n      >>> with context.local(log_level='ERROR'): wget(url, True)\n      >>> result == file('robots.txt').read()\n      True\n    \"\"\"\n    import requests\n\n    with log.progress(\"Downloading '%s'\" % url) as w:\n        w.status(\"Making request...\")\n\n        response = requests.get(url, stream=True, **kwargs)\n\n        if not response.ok:\n            w.failure(\"Got code %s\" % response.status_code)\n            return\n\n        total_size = int(response.headers.get('content-length',0))\n\n        w.status('0 / %s' % size(total_size))\n\n        # Find out the next largest size we can represent as\n        chunk_size = 1\n        while chunk_size < (total_size/10):\n            chunk_size *= 1000\n\n        # Count chunks as they're received\n        total_data    = ''\n\n        # Loop until we have all of the data\n        for chunk in response.iter_content(chunk_size = 2**10):\n            total_data    += chunk\n            if total_size:\n                w.status('%s / %s' % (size(total_data), size(total_size)))\n            else:\n                w.status('%s' % size(total_data))\n\n        # Save to the target file if provided\n        if save:\n            if not isinstance(save, (str, unicode)):\n                save = os.path.basename(url)\n                save = save or tempfile.NamedTemporaryFile(dir='.', delete=False).name\n            with file(save,'wb+') as f:\n                f.write(total_data)\n                w.success('Saved %r (%s)' % (f.name, size(total_data)))\n        else:\n            w.success('%s' % size(total_data))\n\n        return total_data\n\n", "path": "pwnlib/util/web.py"}, {"content": "import hashlib\n\nfor _algo in hashlib.algorithms:\n    def _closure():\n        hash = hashlib.__dict__[_algo]\n        def file(p):\n            h = hash()\n            fd = open(p)\n            while True:\n                s = fd.read(4096)\n                if not s:\n                    break\n                h.update(s)\n            fd.close()\n            return h\n        def sum(s):\n            return hash(s)\n        filef = lambda x: file(x).digest()\n        filef.__doc__ = 'Calculates the %s sum of a file' % _algo\n        sumf = lambda x: sum(x).digest()\n        sumf.__doc__ = 'Calculates the %s sum of a string' % _algo\n        fileh = lambda x: file(x).hexdigest()\n        fileh.__doc__ = 'Calculates the %s sum of a file; returns hex-encoded' % _algo\n        sumh = lambda x: sum(x).hexdigest()\n        sumh.__doc__ = 'Calculates the %s sum of a string; returns hex-encoded' % _algo\n        return filef, sumf, fileh, sumh\n    (globals()[_algo + 'file'],\n     globals()[_algo + 'sum'],\n     globals()[_algo + 'filehex'],\n     globals()[_algo + 'sumhex']) = _closure()\n", "path": "pwnlib/util/hashes.py"}, {"content": "\"\"\"\nDatabase of 22,000 user agent strings\n\"\"\"\n__all__ = ['getall', 'random']\n\nimport os, random as randommod\n\n_cache = None\n\ndef _load():\n    global _cache\n    if _cache is None:\n        _cache = set()\n        with open(os.path.join(os.path.dirname(__file__),\n                               'data/useragents/useragents.txt'\n                               ), 'r') as fd:\n            for line in fd:\n                if line:\n                    _cache.add(line.strip())\n    return _cache\n\ndef getall():\n    \"\"\"getall() -> str set\n\n    Get all the user agents that we know about.\n\n    Args:\n        None\n\n    Returns:\n        A set of user agent strings.\n\n    Examples:\n        >>> 'libcurl-agent/1.0' in getall()\n        True\n        >>> 'wget' in getall()\n        True\n    \"\"\"\n    return _load().copy()\n\ndef random():\n    \"\"\"random() -> str\n\n    Get a random user agent string.\n\n    Args:\n        None\n\n    Returns:\n        A random user agent string selected from :func:`getall`.\n\n    >>> import random as randommod\n    >>> randommod.seed(1)\n    >>> random()\n    'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; FDM)'\n    \"\"\"\n    return randommod.choice(list(_load()))\n", "path": "pwnlib/useragents.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\nimport os, tempfile, logging\nfrom .misc import size\nlog = logging.getLogger(__name__)\n\ndef wget(url, save=None, timeout=5, **kwargs):\n    \"\"\"wget(url, save=None, timeout=5) -> str\n\n    Downloads a file via HTTP/HTTPS.\n\n    Args:\n      url (str): URL to download\n      save (str or bool): Name to save as.  Any truthy value\n            will auto-generate a name based on the URL.\n      timeout (int): Timeout, in seconds\n\n    Example:\n\n      >>> url    = 'http://httpbin.org/robots.txt'\n      >>> with context.local(log_level='ERROR'):\n      ...     result = wget(url)\n      >>> result\n      'User-agent: *\\\\nDisallow: /deny\\\\n'\n      >>> with context.local(log_level='ERROR'):\n      ...     _ = wget(url, True)\n      >>> result == file('robots.txt').read()\n      True\n    \"\"\"\n    import requests\n\n    with log.progress(\"Downloading '%s'\" % url) as w:\n        w.status(\"Making request...\")\n\n        response = requests.get(url, stream=True, **kwargs)\n\n        if not response.ok:\n            w.failure(\"Got code %s\" % response.status_code)\n            return\n\n        total_size = int(response.headers.get('content-length',0))\n\n        w.status('0 / %s' % size(total_size))\n\n        # Find out the next largest size we can represent as\n        chunk_size = 1\n        while chunk_size < (total_size/10):\n            chunk_size *= 1000\n\n        # Count chunks as they're received\n        total_data    = ''\n\n        # Loop until we have all of the data\n        for chunk in response.iter_content(chunk_size = 2**10):\n            total_data    += chunk\n            if total_size:\n                w.status('%s / %s' % (size(total_data), size(total_size)))\n            else:\n                w.status('%s' % size(total_data))\n\n        # Save to the target file if provided\n        if save:\n            if not isinstance(save, (str, unicode)):\n                save = os.path.basename(url)\n                save = save or tempfile.NamedTemporaryFile(dir='.', delete=False).name\n            with file(save,'wb+') as f:\n                f.write(total_data)\n                w.success('Saved %r (%s)' % (f.name, size(total_data)))\n        else:\n            w.success('%s' % size(total_data))\n\n        return total_data\n", "path": "pwnlib/util/web.py"}, {"content": "\"\"\"\nFunctions for computing various hashes of files and strings.\n\"\"\"\nimport hashlib\n\nfor _algo in hashlib.algorithms:\n    def _closure():\n        hash = hashlib.__dict__[_algo]\n        def file(p):\n            h = hash()\n            fd = open(p)\n            while True:\n                s = fd.read(4096)\n                if not s:\n                    break\n                h.update(s)\n            fd.close()\n            return h\n        def sum(s):\n            return hash(s)\n        filef = lambda x: file(x).digest()\n        filef.__doc__ = 'Calculates the %s sum of a file' % _algo\n        sumf = lambda x: sum(x).digest()\n        sumf.__doc__ = 'Calculates the %s sum of a string' % _algo\n        fileh = lambda x: file(x).hexdigest()\n        fileh.__doc__ = 'Calculates the %s sum of a file; returns hex-encoded' % _algo\n        sumh = lambda x: sum(x).hexdigest()\n        sumh.__doc__ = 'Calculates the %s sum of a string; returns hex-encoded' % _algo\n        return filef, sumf, fileh, sumh\n    (globals()[_algo + 'file'],\n     globals()[_algo + 'sum'],\n     globals()[_algo + 'filehex'],\n     globals()[_algo + 'sumhex']) = _closure()\n", "path": "pwnlib/util/hashes.py"}, {"content": "\"\"\"\nDatabase of >22,000 user agent strings\n\"\"\"\n__all__ = ['getall', 'random']\n\nimport os, random as randommod\n\n_cache = None\n\ndef _load():\n    global _cache\n    if _cache is None:\n        _cache = set()\n        with open(os.path.join(os.path.dirname(__file__),\n                               'data/useragents/useragents.txt'\n                               ), 'r') as fd:\n            for line in fd:\n                if line:\n                    _cache.add(line.strip())\n    return _cache\n\ndef getall():\n    \"\"\"getall() -> str set\n\n    Get all the user agents that we know about.\n\n    Args:\n        None\n\n    Returns:\n        A set of user agent strings.\n\n    Examples:\n        >>> 'libcurl-agent/1.0' in getall()\n        True\n        >>> 'wget' in getall()\n        True\n    \"\"\"\n    return _load().copy()\n\ndef random():\n    \"\"\"random() -> str\n\n    Get a random user agent string.\n\n    Args:\n        None\n\n    Returns:\n        A random user agent string selected from :func:`getall`.\n\n    >>> import random as randommod\n    >>> randommod.seed(1)\n    >>> random()\n    'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; FunWebProducts; FunWebProducts-MyTotalSearch; iebar)'\n    \"\"\"\n    return randommod.choice(list(_load()))\n", "path": "pwnlib/useragents.py"}]}