internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: encode/uvicorn

Issue:
Catch `HttpParserInvalidMethodError` exception
`uvicorn==0.1.1` is throwing these errors

```
uvicorn[7423]: Unhandled exception in event loop
uvicorn[7423]: Traceback (most recent call last):
uvicorn[7423]:   File "uvloop/handles/stream.pyx", line 784, in uvloop.loop.__uv_stream_on_read_impl
uvicorn[7423]:   File "uvloop/handles/stream.pyx", line 563, in uvloop.loop.UVStream._on_read
uvicorn[7423]:   File "/home/web/.virtualenvs/mesh/lib/python3.5/site-packages/uvicorn/protocols/http.py", line 212, in data_received
uvicorn[7423]:     self.request_parser.feed_data(data)
uvicorn[7423]:   File "httptools/parser/parser.pyx", line 193, in httptools.parser.parser.HttpParser.feed_data
uvicorn[7423]: httptools.parser.errors.HttpParserInvalidMethodError: invalid HTTP method
```


Discussion:
@ChillarAnand you use method is not in [parser](https://github.com/nodejs/http-parser/blob/master/http_parser.c#L954) , but uvicorn should catch this error.
@ChillarAnand how can I reproduce this?
These errors are showing up in production. I am not sure why that is happening. I couldn't reproduce it locally.
@ChillarAnand The exception could be explicitly handled, but the underlying issue is what @zeromake said. If you could debug the information associated with the request and the data that is being received by the protocol then it may indicate the cause.
I will log the data and see what is happening. Thanks @erm @zeromake 
Should be easy enough to resolve:

* Catch the exception in `data_received` (If httptools has a base class for all parser exceptions then that's what we should be catching)
* Run `self.transport.close()` when exception occurs, and log a warning-level message.
* Add test case.

Resolving patch:
diff --git a/uvicorn/protocols/http/httptools.py b/uvicorn/protocols/http/httptools.py
--- a/uvicorn/protocols/http/httptools.py
+++ b/uvicorn/protocols/http/httptools.py
@@ -93,6 +93,10 @@ def eof_received(self):
     def data_received(self, data):
         try:
             self.parser.feed_data(data)
+        except httptools.parser.errors.HttpParserError:
+            msg = "Invalid HTTP request received."
+            self.logger.warn(msg)
+            self.transport.close()
         except httptools.HttpParserUpgrade:
             websocket_upgrade(self)
 


Test patch:
Repository: encode/uvicorn

Issue:
Drop response body on HEAD requests



Discussion:

Resolving patch:
diff --git a/uvicorn/protocols/http/h11_impl.py b/uvicorn/protocols/http/h11_impl.py
--- a/uvicorn/protocols/http/h11_impl.py
+++ b/uvicorn/protocols/http/h11_impl.py
@@ -465,7 +465,10 @@ async def send(self, message):
             more_body = message.get("more_body", False)
 
             # Write response body
-            event = h11.Data(data=body)
+            if self.scope['method'] == "HEAD":
+                event = h11.Data()
+            else:
+                event = h11.Data(data=body)
             output = self.conn.send(event)
             self.transport.write(output)
 
diff --git a/uvicorn/protocols/http/httptools_impl.py b/uvicorn/protocols/http/httptools_impl.py
--- a/uvicorn/protocols/http/httptools_impl.py
+++ b/uvicorn/protocols/http/httptools_impl.py
@@ -467,7 +467,9 @@ async def send(self, message):
             more_body = message.get("more_body", False)
 
             # Write response body
-            if self.chunked_encoding:
+            if self.scope['method'] == "HEAD":
+                self.expected_content_length = 0
+            elif self.chunked_encoding:
                 content = [b"%x\r\n" % len(body), body, b"\r\n"]
                 if not more_body:
                     content.append(b"0\r\n\r\n")


Test patch:
diff --git a/tests/protocols/test_http.py b/tests/protocols/test_http.py
--- a/tests/protocols/test_http.py
+++ b/tests/protocols/test_http.py
@@ -48,6 +48,8 @@ def set_content_type(self):
 
 SIMPLE_GET_REQUEST = b"\r\n".join([b"GET / HTTP/1.1", b"Host: example.org", b"", b""])
 
+SIMPLE_HEAD_REQUEST = b"\r\n".join([b"HEAD / HTTP/1.1", b"Host: example.org", b"", b""])
+
 SIMPLE_POST_REQUEST = b"\r\n".join(
     [
         b"POST / HTTP/1.1",
@@ -175,6 +177,18 @@ def app(scope):
     assert b"Hello, world" in protocol.transport.buffer
 
 
+@pytest.mark.parametrize("protocol_cls", [HttpToolsProtocol, H11Protocol])
+def test_head_request(protocol_cls):
+    def app(scope):
+        return Response("Hello, world", media_type="text/plain")
+
+    protocol = get_connected_protocol(app, protocol_cls)
+    protocol.data_received(SIMPLE_HEAD_REQUEST)
+    protocol.loop.run_one()
+    assert b"HTTP/1.1 200 OK" in protocol.transport.buffer
+    assert b"Hello, world" not in protocol.transport.buffer
+
+
 @pytest.mark.parametrize("protocol_cls", [HttpToolsProtocol, H11Protocol])
 def test_post_request(protocol_cls):
     class App:
Repository: encode/uvicorn

Issue:
`uvicorn.run` event loop behaviour when running programmatically.
I am trying to run Uvicorn in the same asyncio loop as some other components like the [asyncpg](https://github.com/MagicStack/asyncpg) DB connection pool.

As far as I can tell we can specify the callable that receives the scope and creates the request coroutine two ways:

- Passing a `str` containing the path to `uvicorn.run` but then we can't setup our dependencies (db, redis) since that function is called each new request. We could load the dependencies by creating them when the file is imported but there is no way that will pass codereview.

- Pass a callable to `uvicorn.run` with the dependencies in the scope. Unfortunately `uvicorn` [destroy the current event loop and replaces the event loop policy](https://github.com/encode/uvicorn/blob/master/uvicorn/loops/uvloop.py#L6) during the setup phase.

What is the recommended way to do things like this? If I could pass a loop instance in the `loop` parameter to `run` and have uvicorn use that directly without destroying it then it then I could use alternative 2 as long as we don't call `unicorn.run` from a async function [due to the `server.run` behaviour.](https://github.com/encode/uvicorn/blob/master/uvicorn/main.py#L337).

@tomchristie 


Discussion:
Perhaps we need a `loop="no_setup"` option?

Sets up the connection pool on the first incoming request. (An ASGI middleware could work there for example...)


Resolving patch:
diff --git a/uvicorn/main.py b/uvicorn/main.py
--- a/uvicorn/main.py
+++ b/uvicorn/main.py
@@ -221,12 +221,13 @@ def run(
         sock = socket.fromfd(fd, socket.AF_UNIX, socket.SOCK_STREAM)
 
     logger = get_logger(log_level)
-    loop_setup = import_from_string(LOOP_SETUPS[loop])
     http_protocol_class = import_from_string(HTTP_PROTOCOLS[http])
     ws_protocol_class = import_from_string(WS_PROTOCOLS[ws])
 
-    loop = loop_setup()
-
+    if isinstance(loop, str):
+        loop_setup = import_from_string(LOOP_SETUPS[loop])
+        loop = loop_setup()
+    
     try:
         app = import_from_string(app)
     except ImportFromStringError as exc:


Test patch:
Repository: encode/uvicorn

Issue:
Fixes bug #242, Exception in ASGI application 
When a unix socket is used `transport.get_extra_info("sockname")` returns None. This is normal and accounted for in the tests. However it is assumed to be there in websockets_impl.py where the server variable is used for logging. This sets it to a default of "unknown".


Discussion:

Resolving patch:
diff --git a/uvicorn/__init__.py b/uvicorn/__init__.py
--- a/uvicorn/__init__.py
+++ b/uvicorn/__init__.py
@@ -1,4 +1,4 @@
 from uvicorn.main import main, run
 
-__version__ = "0.3.21"
+__version__ = "0.3.22"
 __all__ = ["main", "run"]
diff --git a/uvicorn/protocols/websockets/websockets_impl.py b/uvicorn/protocols/websockets/websockets_impl.py
--- a/uvicorn/protocols/websockets/websockets_impl.py
+++ b/uvicorn/protocols/websockets/websockets_impl.py
@@ -167,7 +167,7 @@ async def asgi_send(self, message):
             if message_type == "websocket.accept":
                 self.logger.info(
                     '%s - "WebSocket %s" [accepted]',
-                    self.scope["server"][0],
+                    self.scope["client"],
                     self.scope["path"],
                 )
                 self.initial_response = None
@@ -177,7 +177,7 @@ async def asgi_send(self, message):
             elif message_type == "websocket.close":
                 self.logger.info(
                     '%s - "WebSocket %s" 403',
-                    self.scope["server"][0],
+                    self.scope["client"],
                     self.scope["path"],
                 )
                 self.initial_response = (http.HTTPStatus.FORBIDDEN, [], b'')
diff --git a/uvicorn/protocols/websockets/wsproto_impl.py b/uvicorn/protocols/websockets/wsproto_impl.py
--- a/uvicorn/protocols/websockets/wsproto_impl.py
+++ b/uvicorn/protocols/websockets/wsproto_impl.py
@@ -215,7 +215,7 @@ async def send(self, message):
             if message_type == "websocket.accept":
                 self.logger.info(
                     '%s - "WebSocket %s" [accepted]',
-                    self.scope["server"][0],
+                    self.scope["client"],
                     self.scope["path"],
                 )
                 self.handshake_complete = True
@@ -231,7 +231,7 @@ async def send(self, message):
                 })
                 self.logger.info(
                     '%s - "WebSocket %s" 403',
-                    self.scope["server"][0],
+                    self.scope["client"],
                     self.scope["path"],
                 )
                 self.handshake_complete = True


Test patch:
Repository: encode/uvicorn

Issue:
Fix: extra chunk when body is empty
Close: #267


Discussion:

Resolving patch:
diff --git a/uvicorn/protocols/http/httptools_impl.py b/uvicorn/protocols/http/httptools_impl.py
--- a/uvicorn/protocols/http/httptools_impl.py
+++ b/uvicorn/protocols/http/httptools_impl.py
@@ -493,7 +493,10 @@ async def send(self, message):
             if self.scope["method"] == "HEAD":
                 self.expected_content_length = 0
             elif self.chunked_encoding:
-                content = [b"%x\r\n" % len(body), body, b"\r\n"]
+                if body:
+                    content = [b"%x\r\n" % len(body), body, b"\r\n"]
+                else:
+                    content = []
                 if not more_body:
                     content.append(b"0\r\n\r\n")
                 self.transport.write(b"".join(content))


Test patch:
diff --git a/tests/protocols/test_http.py b/tests/protocols/test_http.py
--- a/tests/protocols/test_http.py
+++ b/tests/protocols/test_http.py
@@ -240,6 +240,35 @@ def app(scope):
     assert not protocol.transport.is_closing()
 
 
+@pytest.mark.parametrize("protocol_cls", [HttpToolsProtocol, H11Protocol])
+def test_chunked_encoding_empty_body(protocol_cls):
+    class App():
+        def __init__(self, scope):
+            assert scope['type'] == 'http'
+            self.scope = scope
+
+        async def __call__(self, receive, send):
+            await send({
+                'type': 'http.response.start',
+                'status': 200,
+                'headers': [
+                    [b'content-type', b'text/plain'],
+                ],
+            })
+            await send({
+                'type': 'http.response.body',
+                'body': b'',
+            })
+
+    protocol = get_connected_protocol(App, protocol_cls)
+    protocol.data_received(SIMPLE_GET_REQUEST)
+    protocol.loop.run_one()
+    assert b"HTTP/1.1 200 OK" in protocol.transport.buffer
+    print(protocol.transport.buffer)
+    assert protocol.transport.buffer.count(b'0\r\n\r\n') == 1
+    assert not protocol.transport.is_closing()
+
+
 @pytest.mark.parametrize("protocol_cls", [HttpToolsProtocol, H11Protocol])
 def test_pipelined_requests(protocol_cls):
     def app(scope):
Repository: encode/uvicorn

Issue:
NameError: name 'get_logger' is not defined
Happens only when running in debug mode.
```
$ uvicorn app:App --debug
Traceback (most recent call last):
  File "/home/jamie.chang/.local/bin/uvicorn", line 11, in <module>
    sys.exit(main())
  File "/home/jamie.chang/.local/lib/python3.5/site-packages/click/core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "/home/jamie.chang/.local/lib/python3.5/site-packages/click/core.py", line 717, in main
    rv = self.invoke(ctx)
  File "/home/jamie.chang/.local/lib/python3.5/site-packages/click/core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/jamie.chang/.local/lib/python3.5/site-packages/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "/home/jamie.chang/.local/lib/python3.5/site-packages/uvicorn/main.py", line 166, in main
    logger = get_logger(log_level)
NameError: name 'get_logger' is not defined```


Discussion:

Resolving patch:
diff --git a/uvicorn/__init__.py b/uvicorn/__init__.py
--- a/uvicorn/__init__.py
+++ b/uvicorn/__init__.py
@@ -1,4 +1,4 @@
 from uvicorn.main import main, run
 
-__version__ = "0.3.29"
+__version__ = "0.3.30"
 __all__ = ["main", "run"]
diff --git a/uvicorn/main.py b/uvicorn/main.py
--- a/uvicorn/main.py
+++ b/uvicorn/main.py
@@ -1,4 +1,4 @@
-from uvicorn.config import Config, LOG_LEVELS, HTTP_PROTOCOLS, WS_PROTOCOLS, LOOP_SETUPS
+from uvicorn.config import get_logger, Config, LOG_LEVELS, HTTP_PROTOCOLS, WS_PROTOCOLS, LOOP_SETUPS
 from uvicorn.global_state import GlobalState
 from uvicorn.lifespan import Lifespan
 from uvicorn.reloaders.statreload import StatReload


Test patch:
Repository: encode/uvicorn

Issue:
Deploying inside a process manager: must account for inherited socket family and type
Hi,

I get an error when trying to run uvicorn with Circus, but only if using a socket with file descriptor (which I'd like to do to increase the number of processes).

circus.ini:
```
[socket:web]
host = 0.0.0.0
port = 80
[watcher:uvicorn]
cmd = uvicorn
# args = --host 0.0.0.0 --port 80 satemo.asgi:application 
# --> works ok
args = --fd $(circus.sockets.web) satemo.asgi:application 
# --> Fails
use_sockets = True
numprocesses = 1
```

Error:
```
File "c:\nss\venv\channels2\lib\site-packages\uvicorn\main.py", line 247, in startup
    sock = socket.fromfd(config.fd, socket.AF_UNIX, socket.SOCK_STREAM)
UnboundLocalError: local variable 'socket' referenced before assignment
```

Environment:
* Windows 10
* Python 3.6.5
* uvicorn 0.4.1



Discussion:

Resolving patch:
diff --git a/uvicorn/__init__.py b/uvicorn/__init__.py
--- a/uvicorn/__init__.py
+++ b/uvicorn/__init__.py
@@ -1,4 +1,4 @@
 from uvicorn.main import main, run
 
-__version__ = "0.4.1"
+__version__ = "0.4.2"
 __all__ = ["main", "run"]
diff --git a/uvicorn/main.py b/uvicorn/main.py
--- a/uvicorn/main.py
+++ b/uvicorn/main.py
@@ -2,6 +2,7 @@
 import functools
 import os
 import signal
+import socket
 import sys
 import time
 from email.utils import formatdate


Test patch:
Repository: encode/uvicorn

Issue:
Issue getting root path from scope for access log
Based on changes from pr #284 for issue #253  the access log now is trying to get the root path from the scope and it doesn't have to be present.
Issue getting root path from scope for access log
Based on changes from pr #284 for issue #253  the access log now is trying to get the root path from the scope and it doesn't have to be present.


Discussion:

Resolving patch:
diff --git a/uvicorn/protocols/http/h11_impl.py b/uvicorn/protocols/http/h11_impl.py
--- a/uvicorn/protocols/http/h11_impl.py
+++ b/uvicorn/protocols/http/h11_impl.py
@@ -436,7 +436,7 @@ async def send(self, message):
                     '%s - "%s %s HTTP/%s" %d',
                     self.scope["client"],
                     self.scope["method"],
-                    self.scope["root_path"] + self.scope["path"],
+                    self.scope.get("root_path", "") + self.scope["path"],
                     self.scope["http_version"],
                     status_code,
                 )
diff --git a/uvicorn/protocols/http/httptools_impl.py b/uvicorn/protocols/http/httptools_impl.py
--- a/uvicorn/protocols/http/httptools_impl.py
+++ b/uvicorn/protocols/http/httptools_impl.py
@@ -435,7 +435,7 @@ async def send(self, message):
                     '%s - "%s %s HTTP/%s" %d',
                     self.scope["client"],
                     self.scope["method"],
-                    self.scope["root_path"] + self.scope["path"],
+                    self.scope.get("root_path", "") + self.scope["path"],
                     self.scope["http_version"],
                     status_code,
                 )


Test patch:
Repository: encode/uvicorn

Issue:
byes_data not working with Channels consumers
Uvicorn sends its data like this:

```
        is_text = isinstance(data, str)
        return {
            "type": "websocket.receive",
            "text": data if is_text else None,
            "bytes": None if is_text else data,
        }
```

Channels generic consumers work like this:
```
    def websocket_receive(self, message):
        """
        Called when a WebSocket frame is received. Decodes it and passes it
        to receive().
        """
        if "text" in message:
            self.receive(text_data=message["text"])
        else:
            self.receive(bytes_data=message["bytes"])
```

Since `text` is present but set to none `self.receive` is called with text_data discarding the bytes_data when it is present.

I don't know if this is a bug in Uvicorn or Channels. Its a simple fix either way. Either don't set it on the dict or the channels people should check if its a truthy value and not just present.


Discussion:

Resolving patch:
diff --git a/uvicorn/protocols/websockets/websockets_impl.py b/uvicorn/protocols/websockets/websockets_impl.py
--- a/uvicorn/protocols/websockets/websockets_impl.py
+++ b/uvicorn/protocols/websockets/websockets_impl.py
@@ -226,9 +226,11 @@ async def asgi_receive(self):
                 "code": exc.code,
             }
 
-        is_text = isinstance(data, str)
-        return {
-            "type": "websocket.receive",
-            "text": data if is_text else None,
-            "bytes": None if is_text else data,
-        }
+        msg = {"type": "websocket.receive"}
+
+        if isinstance(data, str):
+            msg["text"] = data
+        else:
+            msg["bytes"] = data
+
+        return msg


Test patch:
Repository: encode/uvicorn

Issue:
AttributeError: module 'ssl' has no attribute 'PROTOCOL_TLS' on Python ,,,3.5.2
Python 3.5 ssl module has no  attribute 'PROTOCOL_TLS'

![image](https://user-images.githubusercontent.com/14031394/54822018-d87c8280-4cde-11e9-9f36-f38699921ba9.png)



Discussion:
![image](https://user-images.githubusercontent.com/14031394/54822326-be8f6f80-4cdf-11e9-821d-963f4f4cc1e9.png)

Okay, thanks. Will try to look into that sometime.
Are you able to upgrade to 3.6+?
I have not see any error message, when run `docker run -it --rm python:3.5-alpine python -c "import ssl;ssl.PROTOCOL_TLS"`.

And in Pyhton 3.5 doc https://docs.python.org/3.5/library/ssl.html#ssl.PROTOCOL_TLS
![屏幕快照 2019-04-04 18 47 11](https://user-images.githubusercontent.com/9482395/55550130-15e30600-570a-11e9-8a5a-e5548abc14b0.png)

More info, see this port pull request https://github.com/python/cpython/commit/598894ff48e9c1171cb2ec1c798235826a75c7e0
Right, so our minimum version is 3.5.3, then I guess.
@ruanima which *exact* python version are you on?

@tomchristie  Right, my Python version is  3.5.2.  I will upgrade it to 3.6. 
I just ran into this one trying to run Uvicorn on https://glitch.com/ - which is a real shame because that would be an amazing environment for demos. They are likely to upgrade Python at some point but it's not clear when.
I got my demo working with Daphne instead https://twitter.com/simonw/status/1121572280637595648

Resolving patch:
diff --git a/uvicorn/config.py b/uvicorn/config.py
--- a/uvicorn/config.py
+++ b/uvicorn/config.py
@@ -43,6 +43,9 @@
 }
 INTERFACES = ["auto", "asgi3", "asgi2", "wsgi"]
 
+# Fallback to 'ssl.PROTOCOL_SSLv23' in order to support Python < 3.5.3.
+SSL_PROTOCOL_VERSION = getattr(ssl, "PROTOCOL_TLS", ssl.PROTOCOL_SSLv23)
+
 
 def get_logger(log_level):
     if isinstance(log_level, str):
@@ -93,7 +96,7 @@ def __init__(
         callback_notify=None,
         ssl_keyfile=None,
         ssl_certfile=None,
-        ssl_version=ssl.PROTOCOL_TLS,
+        ssl_version=SSL_PROTOCOL_VERSION,
         ssl_cert_reqs=ssl.CERT_NONE,
         ssl_ca_certs=None,
         ssl_ciphers="TLSv1",
diff --git a/uvicorn/main.py b/uvicorn/main.py
--- a/uvicorn/main.py
+++ b/uvicorn/main.py
@@ -16,6 +16,7 @@
     LIFESPAN,
     LOG_LEVELS,
     LOOP_SETUPS,
+    SSL_PROTOCOL_VERSION,
     WS_PROTOCOLS,
     Config,
     get_logger,
@@ -160,7 +161,7 @@
 @click.option(
     "--ssl-version",
     type=int,
-    default=ssl.PROTOCOL_TLS,
+    default=SSL_PROTOCOL_VERSION,
     help="SSL version to use (see stdlib ssl module's)",
     show_default=True,
 )


Test patch:
Repository: encode/uvicorn

Issue:
The notify callback is not called on time
https://github.com/encode/uvicorn/blob/545a2a10859165db016d02a641f0c30d07476af1/uvicorn/main.py#L404

On this line we rely on the 0.1 second ticks that occur to notify gunicorn in time. Jitter or cpu bound or naughty blocking io can cause these ticks to gradually fall behind and the process gets killed.

We should use the call to time that we do a few lines above and store the last time we notified in a member variable rather than the ticks, and make sure we have a margin so we definitely don’t notify too late.


Discussion:
Sounds reasonable.
Have you observed this behavior in the wild?
Unfortunately yes!
Call to a bit of cpu intensive but still relatively quick code (~1-2secs). Gradually the ticks get behind.
Took a bit of tracking down. Obviously it can be avoided with executors but its a pretty bad failure mode. 
Gotcha. Pull requests towards resolving this obvs. welcome, but it'll be on my list either way.
I have a fix, will make a PR later or tomorrow. Just 5 lines or so

Resolving patch:
diff --git a/uvicorn/main.py b/uvicorn/main.py
--- a/uvicorn/main.py
+++ b/uvicorn/main.py
@@ -298,6 +298,7 @@ def __init__(self, config):
         self.started = False
         self.should_exit = False
         self.force_exit = False
+        self.last_notified = 0
 
     def run(self, sockets=None, shutdown_servers=True):
         self.config.setup_event_loop()
@@ -399,10 +400,11 @@ async def on_tick(self, counter) -> bool:
                 (b"date", current_date)
             ] + self.config.encoded_headers
 
-        # Callback to `callback_notify` once every `timeout_notify` seconds.
-        if self.config.callback_notify is not None:
-            if counter % (10 * self.config.timeout_notify) == 0:
-                await self.config.callback_notify()
+            # Callback to `callback_notify` once every `timeout_notify` seconds.
+            if self.config.callback_notify is not None:
+                if current_time - self.last_notified > self.config.timeout_notify:
+                    self.last_notified = current_time
+                    await self.config.callback_notify()
 
         # Determine if we should exit.
         if self.should_exit:


Test patch: