]> git.ipfire.org Git - thirdparty/httpx.git/commitdiff
Improve GatewayService example
authorTom Christie <tom@tomchristie.com>
Sat, 6 Apr 2019 14:39:09 +0000 (15:39 +0100)
committerTom Christie <tom@tomchristie.com>
Sat, 6 Apr 2019 14:39:09 +0000 (15:39 +0100)
README.md

index 965885f7b33d331e3b42ff24a1e314864e404a3c..94d2e723e38e28cab164fd22ef9bb79da97f31ac 100644 (file)
--- a/README.md
+++ b/README.md
@@ -110,13 +110,22 @@ class GatewayServer:
         path = scope['path']
         query = scope['query_string']
         method = scope['method']
-        headers = scope['headers']
+        headers = [
+            (k, v) for (k, v) in scope['headers']
+            if k not in (b'host', b'content-length', b'transfer-encoding')
+        ]
 
         url = self.base_url + path
         if query:
             url += '?' + query.decode()
 
-        body = self.stream_body(receive)
+        initial_body, more_body = await self.initial_body(receive)
+        if more_body:
+            # Streaming request.
+            body = self.stream_body(receive, initial_body)
+        else:
+            # Standard request.
+            body = initial_body
 
         response = await self.http.request(
             method, url, headers=headers, body=body, stream=True
@@ -127,21 +136,39 @@ class GatewayServer:
             'status': response.status_code,
             'headers': response.headers
         })
-        async for data in response.stream():
-            await send({
-                'type': 'http.response.body',
-                'body': data,
-                'more_body': True
-            })
-        await send({'type': 'http.response.body'})
-
-    async def stream_body(self, receive):
+        data = b''
+        async for next_data in response.stream():
+            if data:
+                await send({
+                    'type': 'http.response.body',
+                    'body': data,
+                    'more_body': True
+                })
+            data = next_data
+        await send({'type': 'http.response.body', 'body': data})
+
+    async def initial_body(self, receive):
+        """
+        Pull the first body message off the 'receive' channel.
+        Allows us to determine if we should use a streaming request or not.
+        """
+        message = await receive()
+        body = message.get('body', b'')
+        more_body = message.get('more_body', False)
+        return (body, more_body)
+
+    async def stream_body(self, receive, initial_body):
+        """
+        Async iterator returning bytes for the request body.
+        """
+        yield initial_body
         while True:
             message = await receive()
             yield message.get('body', b'')
             if not message.get('more_body', False):
                 break
 
+
 app = GatewayServer('http://example.org')
 ```