prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Cannot inject websocket with binary or string content.
  #### Problem Description
  mitmproxy attempts to parse the injected websocket binary data as text, and replaces the binary data if it cannot be decoded into text, changing the injected websocket message. Also, when a string is given instead, there is error:
  File "\mitmproxy\proxy\layers\websocket.py", line 230, in msg
      data_str = data.decode(errors="replace")
  AttributeError: 'str' object has no attribute 'decode'
  
  #### Steps to reproduce the behavior:
  1. from mitmproxy.ctx import master
  2. master.commands.call("inject.websocket", flow, False, bytes([i for i in range(256)])) # No error, but message contents are changed
  3. master.commands.call("inject.websocket", flow, False, "string") # AttributeError
  
  #### System Information
  Mitmproxy: 7.0.2
  Python:    3.9.6
  OpenSSL:   OpenSSL 1.1.1k  25 Mar 2021
  Platform:  Windows-10-10.0.19043-SP0
  
  
  </issue>
  <code>
  [start of examples/addons/websocket-inject-message.py]
  1 """
  2 Inject a WebSocket message into a running connection.
  3 
  4 This example shows how to inject a WebSocket message into a running connection.
  5 """
  6 import asyncio
  7 
  8 from mitmproxy import ctx, http
  9 
  10 
  11 # Simple example: Inject a message as a response to an event
  12 
  13 def websocket_message(flow: http.HTTPFlow):
  14     assert flow.websocket is not None  # make type checker happy
  15     last_message = flow.websocket.messages[-1]
  16     if b"secret" in last_message.content:
  17         last_message.drop()
  18         ctx.master.commands.call("inject.websocket", flow, last_message.from_client, "ssssssh")
  19 
  20 
  21 # Complex example: Schedule a periodic timer
  22 
  23 async def inject_async(flow: http.HTTPFlow):
  24     msg = "hello from mitmproxy! "
  25     assert flow.websocket is not None  # make type checker happy
  26     while flow.websocket.timestamp_end is None:
  27         ctx.master.commands.call("inject.websocket", flow, True, msg)
  28         await asyncio.sleep(1)
  29         msg = msg[1:] + msg[:1]
  30 
  31 
  32 def websocket_start(flow: http.HTTPFlow):
  33     asyncio.create_task(inject_async(flow))
  34
  [end of examples/addons/websocket-inject-message.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/examples/addons/websocket-inject-message.py b/examples/addons/websocket-inject-message.py
  --- a/examples/addons/websocket-inject-message.py
  +++ b/examples/addons/websocket-inject-message.py
  @@ -13,9 +13,9 @@
   def websocket_message(flow: http.HTTPFlow):
       assert flow.websocket is not None  # make type checker happy
       last_message = flow.websocket.messages[-1]
  -    if b"secret" in last_message.content:
  +    if last_message.is_text and "secret" in last_message.text:
           last_message.drop()
  -        ctx.master.commands.call("inject.websocket", flow, last_message.from_client, "ssssssh")
  +        ctx.master.commands.call("inject.websocket", flow, last_message.from_client, "ssssssh".encode())
   
   
   # Complex example: Schedule a periodic timer
  @@ -24,7 +24,7 @@
       msg = "hello from mitmproxy! "
       assert flow.websocket is not None  # make type checker happy
       while flow.websocket.timestamp_end is None:
  -        ctx.master.commands.call("inject.websocket", flow, True, msg)
  +        ctx.master.commands.call("inject.websocket", flow, True, msg.encode())
           await asyncio.sleep(1)
           msg = msg[1:] + msg[:1]
  
verification_info: {"golden_diff": "diff --git a/examples/addons/websocket-inject-message.py b/examples/addons/websocket-inject-message.py\n--- a/examples/addons/websocket-inject-message.py\n+++ b/examples/addons/websocket-inject-message.py\n@@ -13,9 +13,9 @@\n def websocket_message(flow: http.HTTPFlow):\n     assert flow.websocket is not None  # make type checker happy\n     last_message = flow.websocket.messages[-1]\n-    if b\"secret\" in last_message.content:\n+    if last_message.is_text and \"secret\" in last_message.text:\n         last_message.drop()\n-        ctx.master.commands.call(\"inject.websocket\", flow, last_message.from_client, \"ssssssh\")\n+        ctx.master.commands.call(\"inject.websocket\", flow, last_message.from_client, \"ssssssh\".encode())\n \n \n # Complex example: Schedule a periodic timer\n@@ -24,7 +24,7 @@\n     msg = \"hello from mitmproxy! \"\n     assert flow.websocket is not None  # make type checker happy\n     while flow.websocket.timestamp_end is None:\n-        ctx.master.commands.call(\"inject.websocket\", flow, True, msg)\n+        ctx.master.commands.call(\"inject.websocket\", flow, True, msg.encode())\n         await asyncio.sleep(1)\n         msg = msg[1:] + msg[:1]\n", "issue": "Cannot inject websocket with binary or string content.\n#### Problem Description\r\nmitmproxy attempts to parse the injected websocket binary data as text, and replaces the binary data if it cannot be decoded into text, changing the injected websocket message. Also, when a string is given instead, there is error:\r\nFile \"\\mitmproxy\\proxy\\layers\\websocket.py\", line 230, in msg\r\n    data_str = data.decode(errors=\"replace\")\r\nAttributeError: 'str' object has no attribute 'decode'\r\n\r\n#### Steps to reproduce the behavior:\r\n1. from mitmproxy.ctx import master\r\n2. master.commands.call(\"inject.websocket\", flow, False, bytes([i for i in range(256)])) # No error, but message contents are changed\r\n3. master.commands.call(\"inject.websocket\", flow, False, \"string\") # AttributeError\r\n\r\n#### System Information\r\nMitmproxy: 7.0.2\r\nPython:    3.9.6\r\nOpenSSL:   OpenSSL 1.1.1k  25 Mar 2021\r\nPlatform:  Windows-10-10.0.19043-SP0\r\n\n", "before_files": [{"content": "\"\"\"\nInject a WebSocket message into a running connection.\n\nThis example shows how to inject a WebSocket message into a running connection.\n\"\"\"\nimport asyncio\n\nfrom mitmproxy import ctx, http\n\n\n# Simple example: Inject a message as a response to an event\n\ndef websocket_message(flow: http.HTTPFlow):\n    assert flow.websocket is not None  # make type checker happy\n    last_message = flow.websocket.messages[-1]\n    if b\"secret\" in last_message.content:\n        last_message.drop()\n        ctx.master.commands.call(\"inject.websocket\", flow, last_message.from_client, \"ssssssh\")\n\n\n# Complex example: Schedule a periodic timer\n\nasync def inject_async(flow: http.HTTPFlow):\n    msg = \"hello from mitmproxy! \"\n    assert flow.websocket is not None  # make type checker happy\n    while flow.websocket.timestamp_end is None:\n        ctx.master.commands.call(\"inject.websocket\", flow, True, msg)\n        await asyncio.sleep(1)\n        msg = msg[1:] + msg[:1]\n\n\ndef websocket_start(flow: http.HTTPFlow):\n    asyncio.create_task(inject_async(flow))\n", "path": "examples/addons/websocket-inject-message.py"}]}