We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Divide by Zero error
Its in `netlib/strutils.py`

This line # around 126 :

``` python
    for i in six.iterbytes(s[:100])
) / len(s[:100]) > 0.3
```

if s is empty, it gives this error in the mitmproxy, (doesn't crash though due to recent improvements in mitmproxy i guess..)


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `netlib/strutils.py`
Content:
```
1 from __future__ import absolute_import, print_function, division
2 import re
3 import codecs
4 
5 import six
6 
7 
8 def always_bytes(unicode_or_bytes, *encode_args):
9     if isinstance(unicode_or_bytes, six.text_type):
10         return unicode_or_bytes.encode(*encode_args)
11     return unicode_or_bytes
12 
13 
14 def native(s, *encoding_opts):
15     """
16     Convert :py:class:`bytes` or :py:class:`unicode` to the native
17     :py:class:`str` type, using latin1 encoding if conversion is necessary.
18 
19     https://www.python.org/dev/peps/pep-3333/#a-note-on-string-types
20     """
21     if not isinstance(s, (six.binary_type, six.text_type)):
22         raise TypeError("%r is neither bytes nor unicode" % s)
23     if six.PY2:
24         if isinstance(s, six.text_type):
25             return s.encode(*encoding_opts)
26     else:
27         if isinstance(s, six.binary_type):
28             return s.decode(*encoding_opts)
29     return s
30 
31 
32 # Translate control characters to "safe" characters. This implementation initially
33 # replaced them with the matching control pictures (http://unicode.org/charts/PDF/U2400.pdf),
34 # but that turned out to render badly with monospace fonts. We are back to "." therefore.
35 _control_char_trans = {
36     x: ord(".")  # x + 0x2400 for unicode control group pictures
37     for x in range(32)
38 }
39 _control_char_trans[127] = ord(".")  # 0x2421
40 _control_char_trans_newline = _control_char_trans.copy()
41 for x in ("\r", "\n", "\t"):
42     del _control_char_trans_newline[ord(x)]
43 
44 
45 if six.PY2:
46     pass
47 else:
48     _control_char_trans = str.maketrans(_control_char_trans)
49     _control_char_trans_newline = str.maketrans(_control_char_trans_newline)
50 
51 
52 def escape_control_characters(text, keep_spacing=True):
53     """
54     Replace all unicode C1 control characters from the given text with a single "."
55 
56     Args:
57         keep_spacing: If True, tabs and newlines will not be replaced.
58     """
59     # type: (six.string_types) -> six.text_type
60     if not isinstance(text, six.string_types):
61         raise ValueError("text type must be unicode but is {}".format(type(text).__name__))
62 
63     trans = _control_char_trans_newline if keep_spacing else _control_char_trans
64     if six.PY2:
65         return u"".join(
66             six.unichr(trans.get(ord(ch), ord(ch)))
67             for ch in text
68         )
69     return text.translate(trans)
70 
71 
72 def bytes_to_escaped_str(data, keep_spacing=False, escape_single_quotes=False):
73     """
74     Take bytes and return a safe string that can be displayed to the user.
75 
76     Single quotes are always escaped, double quotes are never escaped:
77         "'" + bytes_to_escaped_str(...) + "'"
78     gives a valid Python string.
79 
80     Args:
81         keep_spacing: If True, tabs and newlines will not be escaped.
82     """
83 
84     if not isinstance(data, bytes):
85         raise ValueError("data must be bytes, but is {}".format(data.__class__.__name__))
86     # We always insert a double-quote here so that we get a single-quoted string back
87     # https://stackoverflow.com/questions/29019340/why-does-python-use-different-quotes-for-representing-strings-depending-on-their
88     ret = repr(b'"' + data).lstrip("b")[2:-1]
89     if not escape_single_quotes:
90         ret = re.sub(r"(?<!\\)(\\\\)*\\'", lambda m: (m.group(1) or "") + "'", ret)
91     if keep_spacing:
92         ret = re.sub(
93             r"(?<!\\)(\\\\)*\\([nrt])",
94             lambda m: (m.group(1) or "") + dict(n="\n", r="\r", t="\t")[m.group(2)],
95             ret
96         )
97     return ret
98 
99 
100 def escaped_str_to_bytes(data):
101     """
102     Take an escaped string and return the unescaped bytes equivalent.
103 
104     Raises:
105         ValueError, if the escape sequence is invalid.
106     """
107     if not isinstance(data, six.string_types):
108         if six.PY2:
109             raise ValueError("data must be str or unicode, but is {}".format(data.__class__.__name__))
110         raise ValueError("data must be str, but is {}".format(data.__class__.__name__))
111 
112     if six.PY2:
113         if isinstance(data, unicode):
114             data = data.encode("utf8")
115         return data.decode("string-escape")
116 
117     # This one is difficult - we use an undocumented Python API here
118     # as per http://stackoverflow.com/a/23151714/934719
119     return codecs.escape_decode(data)[0]
120 
121 
122 def is_mostly_bin(s):
123     # type: (bytes) -> bool
124     return sum(
125         i < 9 or 13 < i < 32 or 126 < i
126         for i in six.iterbytes(s[:100])
127     ) / len(s[:100]) > 0.3
128 
129 
130 def is_xml(s):
131     # type: (bytes) -> bool
132     return s.strip().startswith(b"<")
133 
134 
135 def clean_hanging_newline(t):
136     """
137         Many editors will silently add a newline to the final line of a
138         document (I'm looking at you, Vim). This function fixes this common
139         problem at the risk of removing a hanging newline in the rare cases
140         where the user actually intends it.
141     """
142     if t and t[-1] == "\n":
143         return t[:-1]
144     return t
145 
146 
147 def hexdump(s):
148     """
149         Returns:
150             A generator of (offset, hex, str) tuples
151     """
152     for i in range(0, len(s), 16):
153         offset = "{:0=10x}".format(i)
154         part = s[i:i + 16]
155         x = " ".join("{:0=2x}".format(i) for i in six.iterbytes(part))
156         x = x.ljust(47)  # 16*2 + 15
157         part_repr = native(escape_control_characters(
158             part.decode("ascii", "replace").replace(u"\ufffd", u"."),
159             False
160         ))
161         yield (offset, x, part_repr)
162
```
--- 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/netlib/strutils.py b/netlib/strutils.py
--- a/netlib/strutils.py
+++ b/netlib/strutils.py
@@ -121,6 +121,9 @@
 
 def is_mostly_bin(s):
     # type: (bytes) -> bool
+    if not s or len(s) == 0:
+        return False
+
     return sum(
         i < 9 or 13 < i < 32 or 126 < i
         for i in six.iterbytes(s[:100])

{"golden_diff": "diff --git a/netlib/strutils.py b/netlib/strutils.py\n--- a/netlib/strutils.py\n+++ b/netlib/strutils.py\n@@ -121,6 +121,9 @@\n \n def is_mostly_bin(s):\n     # type: (bytes) -> bool\n+    if not s or len(s) == 0:\n+        return False\n+\n     return sum(\n         i < 9 or 13 < i < 32 or 126 < i\n         for i in six.iterbytes(s[:100])\n", "issue": "Divide by Zero error\nIts in `netlib/strutils.py`\n\nThis line # around 126 :\n\n``` python\n    for i in six.iterbytes(s[:100])\n) / len(s[:100]) > 0.3\n```\n\nif s is empty, it gives this error in the mitmproxy, (doesn't crash though due to recent improvements in mitmproxy i guess..)\n\n", "before_files": [{"content": "from __future__ import absolute_import, print_function, division\nimport re\nimport codecs\n\nimport six\n\n\ndef always_bytes(unicode_or_bytes, *encode_args):\n    if isinstance(unicode_or_bytes, six.text_type):\n        return unicode_or_bytes.encode(*encode_args)\n    return unicode_or_bytes\n\n\ndef native(s, *encoding_opts):\n    \"\"\"\n    Convert :py:class:`bytes` or :py:class:`unicode` to the native\n    :py:class:`str` type, using latin1 encoding if conversion is necessary.\n\n    https://www.python.org/dev/peps/pep-3333/#a-note-on-string-types\n    \"\"\"\n    if not isinstance(s, (six.binary_type, six.text_type)):\n        raise TypeError(\"%r is neither bytes nor unicode\" % s)\n    if six.PY2:\n        if isinstance(s, six.text_type):\n            return s.encode(*encoding_opts)\n    else:\n        if isinstance(s, six.binary_type):\n            return s.decode(*encoding_opts)\n    return s\n\n\n# Translate control characters to \"safe\" characters. This implementation initially\n# replaced them with the matching control pictures (http://unicode.org/charts/PDF/U2400.pdf),\n# but that turned out to render badly with monospace fonts. We are back to \".\" therefore.\n_control_char_trans = {\n    x: ord(\".\")  # x + 0x2400 for unicode control group pictures\n    for x in range(32)\n}\n_control_char_trans[127] = ord(\".\")  # 0x2421\n_control_char_trans_newline = _control_char_trans.copy()\nfor x in (\"\\r\", \"\\n\", \"\\t\"):\n    del _control_char_trans_newline[ord(x)]\n\n\nif six.PY2:\n    pass\nelse:\n    _control_char_trans = str.maketrans(_control_char_trans)\n    _control_char_trans_newline = str.maketrans(_control_char_trans_newline)\n\n\ndef escape_control_characters(text, keep_spacing=True):\n    \"\"\"\n    Replace all unicode C1 control characters from the given text with a single \".\"\n\n    Args:\n        keep_spacing: If True, tabs and newlines will not be replaced.\n    \"\"\"\n    # type: (six.string_types) -> six.text_type\n    if not isinstance(text, six.string_types):\n        raise ValueError(\"text type must be unicode but is {}\".format(type(text).__name__))\n\n    trans = _control_char_trans_newline if keep_spacing else _control_char_trans\n    if six.PY2:\n        return u\"\".join(\n            six.unichr(trans.get(ord(ch), ord(ch)))\n            for ch in text\n        )\n    return text.translate(trans)\n\n\ndef bytes_to_escaped_str(data, keep_spacing=False, escape_single_quotes=False):\n    \"\"\"\n    Take bytes and return a safe string that can be displayed to the user.\n\n    Single quotes are always escaped, double quotes are never escaped:\n        \"'\" + bytes_to_escaped_str(...) + \"'\"\n    gives a valid Python string.\n\n    Args:\n        keep_spacing: If True, tabs and newlines will not be escaped.\n    \"\"\"\n\n    if not isinstance(data, bytes):\n        raise ValueError(\"data must be bytes, but is {}\".format(data.__class__.__name__))\n    # We always insert a double-quote here so that we get a single-quoted string back\n    # https://stackoverflow.com/questions/29019340/why-does-python-use-different-quotes-for-representing-strings-depending-on-their\n    ret = repr(b'\"' + data).lstrip(\"b\")[2:-1]\n    if not escape_single_quotes:\n        ret = re.sub(r\"(?<!\\\\)(\\\\\\\\)*\\\\'\", lambda m: (m.group(1) or \"\") + \"'\", ret)\n    if keep_spacing:\n        ret = re.sub(\n            r\"(?<!\\\\)(\\\\\\\\)*\\\\([nrt])\",\n            lambda m: (m.group(1) or \"\") + dict(n=\"\\n\", r=\"\\r\", t=\"\\t\")[m.group(2)],\n            ret\n        )\n    return ret\n\n\ndef escaped_str_to_bytes(data):\n    \"\"\"\n    Take an escaped string and return the unescaped bytes equivalent.\n\n    Raises:\n        ValueError, if the escape sequence is invalid.\n    \"\"\"\n    if not isinstance(data, six.string_types):\n        if six.PY2:\n            raise ValueError(\"data must be str or unicode, but is {}\".format(data.__class__.__name__))\n        raise ValueError(\"data must be str, but is {}\".format(data.__class__.__name__))\n\n    if six.PY2:\n        if isinstance(data, unicode):\n            data = data.encode(\"utf8\")\n        return data.decode(\"string-escape\")\n\n    # This one is difficult - we use an undocumented Python API here\n    # as per http://stackoverflow.com/a/23151714/934719\n    return codecs.escape_decode(data)[0]\n\n\ndef is_mostly_bin(s):\n    # type: (bytes) -> bool\n    return sum(\n        i < 9 or 13 < i < 32 or 126 < i\n        for i in six.iterbytes(s[:100])\n    ) / len(s[:100]) > 0.3\n\n\ndef is_xml(s):\n    # type: (bytes) -> bool\n    return s.strip().startswith(b\"<\")\n\n\ndef clean_hanging_newline(t):\n    \"\"\"\n        Many editors will silently add a newline to the final line of a\n        document (I'm looking at you, Vim). This function fixes this common\n        problem at the risk of removing a hanging newline in the rare cases\n        where the user actually intends it.\n    \"\"\"\n    if t and t[-1] == \"\\n\":\n        return t[:-1]\n    return t\n\n\ndef hexdump(s):\n    \"\"\"\n        Returns:\n            A generator of (offset, hex, str) tuples\n    \"\"\"\n    for i in range(0, len(s), 16):\n        offset = \"{:0=10x}\".format(i)\n        part = s[i:i + 16]\n        x = \" \".join(\"{:0=2x}\".format(i) for i in six.iterbytes(part))\n        x = x.ljust(47)  # 16*2 + 15\n        part_repr = native(escape_control_characters(\n            part.decode(\"ascii\", \"replace\").replace(u\"\\ufffd\", u\".\"),\n            False\n        ))\n        yield (offset, x, part_repr)\n", "path": "netlib/strutils.py"}], "after_files": [{"content": "from __future__ import absolute_import, print_function, division\nimport re\nimport codecs\n\nimport six\n\n\ndef always_bytes(unicode_or_bytes, *encode_args):\n    if isinstance(unicode_or_bytes, six.text_type):\n        return unicode_or_bytes.encode(*encode_args)\n    return unicode_or_bytes\n\n\ndef native(s, *encoding_opts):\n    \"\"\"\n    Convert :py:class:`bytes` or :py:class:`unicode` to the native\n    :py:class:`str` type, using latin1 encoding if conversion is necessary.\n\n    https://www.python.org/dev/peps/pep-3333/#a-note-on-string-types\n    \"\"\"\n    if not isinstance(s, (six.binary_type, six.text_type)):\n        raise TypeError(\"%r is neither bytes nor unicode\" % s)\n    if six.PY2:\n        if isinstance(s, six.text_type):\n            return s.encode(*encoding_opts)\n    else:\n        if isinstance(s, six.binary_type):\n            return s.decode(*encoding_opts)\n    return s\n\n\n# Translate control characters to \"safe\" characters. This implementation initially\n# replaced them with the matching control pictures (http://unicode.org/charts/PDF/U2400.pdf),\n# but that turned out to render badly with monospace fonts. We are back to \".\" therefore.\n_control_char_trans = {\n    x: ord(\".\")  # x + 0x2400 for unicode control group pictures\n    for x in range(32)\n}\n_control_char_trans[127] = ord(\".\")  # 0x2421\n_control_char_trans_newline = _control_char_trans.copy()\nfor x in (\"\\r\", \"\\n\", \"\\t\"):\n    del _control_char_trans_newline[ord(x)]\n\n\nif six.PY2:\n    pass\nelse:\n    _control_char_trans = str.maketrans(_control_char_trans)\n    _control_char_trans_newline = str.maketrans(_control_char_trans_newline)\n\n\ndef escape_control_characters(text, keep_spacing=True):\n    \"\"\"\n    Replace all unicode C1 control characters from the given text with a single \".\"\n\n    Args:\n        keep_spacing: If True, tabs and newlines will not be replaced.\n    \"\"\"\n    # type: (six.string_types) -> six.text_type\n    if not isinstance(text, six.string_types):\n        raise ValueError(\"text type must be unicode but is {}\".format(type(text).__name__))\n\n    trans = _control_char_trans_newline if keep_spacing else _control_char_trans\n    if six.PY2:\n        return u\"\".join(\n            six.unichr(trans.get(ord(ch), ord(ch)))\n            for ch in text\n        )\n    return text.translate(trans)\n\n\ndef bytes_to_escaped_str(data, keep_spacing=False, escape_single_quotes=False):\n    \"\"\"\n    Take bytes and return a safe string that can be displayed to the user.\n\n    Single quotes are always escaped, double quotes are never escaped:\n        \"'\" + bytes_to_escaped_str(...) + \"'\"\n    gives a valid Python string.\n\n    Args:\n        keep_spacing: If True, tabs and newlines will not be escaped.\n    \"\"\"\n\n    if not isinstance(data, bytes):\n        raise ValueError(\"data must be bytes, but is {}\".format(data.__class__.__name__))\n    # We always insert a double-quote here so that we get a single-quoted string back\n    # https://stackoverflow.com/questions/29019340/why-does-python-use-different-quotes-for-representing-strings-depending-on-their\n    ret = repr(b'\"' + data).lstrip(\"b\")[2:-1]\n    if not escape_single_quotes:\n        ret = re.sub(r\"(?<!\\\\)(\\\\\\\\)*\\\\'\", lambda m: (m.group(1) or \"\") + \"'\", ret)\n    if keep_spacing:\n        ret = re.sub(\n            r\"(?<!\\\\)(\\\\\\\\)*\\\\([nrt])\",\n            lambda m: (m.group(1) or \"\") + dict(n=\"\\n\", r=\"\\r\", t=\"\\t\")[m.group(2)],\n            ret\n        )\n    return ret\n\n\ndef escaped_str_to_bytes(data):\n    \"\"\"\n    Take an escaped string and return the unescaped bytes equivalent.\n\n    Raises:\n        ValueError, if the escape sequence is invalid.\n    \"\"\"\n    if not isinstance(data, six.string_types):\n        if six.PY2:\n            raise ValueError(\"data must be str or unicode, but is {}\".format(data.__class__.__name__))\n        raise ValueError(\"data must be str, but is {}\".format(data.__class__.__name__))\n\n    if six.PY2:\n        if isinstance(data, unicode):\n            data = data.encode(\"utf8\")\n        return data.decode(\"string-escape\")\n\n    # This one is difficult - we use an undocumented Python API here\n    # as per http://stackoverflow.com/a/23151714/934719\n    return codecs.escape_decode(data)[0]\n\n\ndef is_mostly_bin(s):\n    # type: (bytes) -> bool\n    if not s or len(s) == 0:\n        return False\n\n    return sum(\n        i < 9 or 13 < i < 32 or 126 < i\n        for i in six.iterbytes(s[:100])\n    ) / len(s[:100]) > 0.3\n\n\ndef is_xml(s):\n    # type: (bytes) -> bool\n    return s.strip().startswith(b\"<\")\n\n\ndef clean_hanging_newline(t):\n    \"\"\"\n        Many editors will silently add a newline to the final line of a\n        document (I'm looking at you, Vim). This function fixes this common\n        problem at the risk of removing a hanging newline in the rare cases\n        where the user actually intends it.\n    \"\"\"\n    if t and t[-1] == \"\\n\":\n        return t[:-1]\n    return t\n\n\ndef hexdump(s):\n    \"\"\"\n        Returns:\n            A generator of (offset, hex, str) tuples\n    \"\"\"\n    for i in range(0, len(s), 16):\n        offset = \"{:0=10x}\".format(i)\n        part = s[i:i + 16]\n        x = \" \".join(\"{:0=2x}\".format(i) for i in six.iterbytes(part))\n        x = x.ljust(47)  # 16*2 + 15\n        part_repr = native(escape_control_characters(\n            part.decode(\"ascii\", \"replace\").replace(u\"\\ufffd\", u\".\"),\n            False\n        ))\n        yield (offset, x, part_repr)\n", "path": "netlib/strutils.py"}]}