@@ -213,26 +213,18 @@ connection object and start handing it data. For now, let's just see what
213213happens as we feed it data.
214214
215215To make HTTP/2 connections, we need a tool that knows how to speak HTTP/2.
216- You can simply use `curl `_ or install a Python tool used throughout this
217- tutorial. In your Python environment, run ``pip install hyper `` (Make sure to
218- use ``Python < 3.10 `` or install it in separate environment). This will
219- install a Python command-line HTTP/2 tool called ``hyper ``. To confirm that
220- it works, try running this command and verifying that the output looks similar
221- to the one shown below:
216+ You can simply use `curl `_ or any other client with HTTP/2 support like
217+ `httpx `_. To confirm that it works, try running this command and verifying that
218+ the output looks similar to the one shown below:
222219
223220.. code-block :: console
224221
225- $ hyper GET https://nghttp2.org/httpbin/get
222+ $ curl --http2 https://nghttp2.org/httpbin/get
226223 {'args': {},
227224 'headers': {'Host': 'nghttp2.org'},
228225 'origin': '10.0.0.2',
229226 'url': 'https://nghttp2.org/httpbin/get'}
230227
231- Equivalent code with curl would look like this:
232-
233- .. code-block :: console
234-
235- $ curl --http2 https://nghttp2.org/httpbin/get
236228
237229 To use it with our server though, you will need to invoke it with a different
238230``--http2-prior-knowledge `` flag as we are going to serve over the insecure
@@ -301,17 +293,16 @@ function. Your ``h2server.py`` should end up looking a like this:
301293 handle(sock.accept()[0 ])
302294
303295 Running that in one shell, in your other shell you can run
304- ``hyper --h2 GET http://localhost:8080/ ``. For the ``curl `` use
305296``curl -v --http2-prior-knowledge http://localhost:8080/ `` command.
306- That shell should hang, and you
307- should then see the following output from your ``h2server.py `` shell:
297+ That shell should hang, and you should then see the following output from your
298+ ``h2server.py `` shell:
308299
309300.. code-block :: console
310301
311302 $ python h2server.py
312303 [<h2.events.RemoteSettingsChanged object at 0x10c4ee390>]
313304
314- You'll then need to kill ``hyper `` and ``h2server.py `` with Ctrl+C. Feel free
305+ You'll then need to kill ``curl `` and ``h2server.py `` with Ctrl+C. Feel free
315306to do this a few times, to see how things behave.
316307
317308So, what did we see here? When the connection was opened, we used the
@@ -320,15 +311,15 @@ socket, in a loop. We then passed that data to the connection object, which
320311returned us a single event object:
321312:class: `RemoteSettingsChanged <h2.events.RemoteSettingsChanged> `.
322313
323- But what we didn't see was anything else. So it seems like all ``hyper `` did
324- was change its settings, but nothing else. If you look at the other ``hyper ``
314+ But what we didn't see was anything else. So it seems like all ``curl `` did
315+ was change its settings, but nothing else. If you look at the other ``curl ``
325316window, you'll notice that it hangs for a while and then eventually fails with
326317a socket timeout. It was waiting for something: what?
327318
328319Well, it turns out that at the start of a connection, both sides need to send
329320a bit of data, called "the HTTP/2 preamble". We don't need to get into too much
330321detail here, but basically both sides need to send a single block of HTTP/2
331- data that tells the other side what their settings are. ``hyper `` did that,
322+ data that tells the other side what their settings are. ``curl `` did that,
332323but we didn't.
333324
334325Let's do that next.
@@ -401,9 +392,10 @@ Your ``h2server.py`` script should now look like this:
401392
402393
403394 With this change made, rerun your ``h2server.py `` script and hit it with the
404- same ``hyper `` command: ``hyper --h2 GET http://localhost:8080/ ``. The
405- ``hyper `` command still hangs, but this time we get a bit more output from our
406- ``h2server.py `` script:
395+ same ``curl `` command:
396+ ``curl -v --http2-prior-knowledge http://localhost:8080/ ``.
397+ The ``curl `` command still hangs, but this time we get a bit more output from
398+ our ``h2server.py `` script:
407399
408400.. code-block :: console
409401
@@ -423,17 +415,17 @@ Finally, even more data that triggers *two* events:
423415:class: `RequestReceived <h2.events.RequestReceived> ` and
424416:class: `StreamEnded <h2.events.StreamEnded> `.
425417
426- So, what's happening is that ``hyper `` is telling us about its settings,
418+ So, what's happening is that ``curl `` is telling us about its settings,
427419acknowledging ours, and then sending us a request. Then it ends a *stream *,
428420which is a HTTP/2 communications channel that holds a request and response
429421pair.
430422
431423A stream isn't done until it's either *reset * or both sides *close * it:
432424in this sense it's bi-directional. So what the ``StreamEnded `` event tells us
433- is that ``hyper `` is closing its half of the stream: it won't send us any more
425+ is that ``curl `` is closing its half of the stream: it won't send us any more
434426data on that stream. That means the request is done.
435427
436- So why is ``hyper `` hanging? Well, we haven't sent a response yet: let's do
428+ So why is ``curl `` hanging? Well, we haven't sent a response yet: let's do
437429that.
438430
439431
@@ -502,7 +494,7 @@ one exception is headers: h2 will automatically encode those into UTF-8.
502494The last thing to note is that on our call to ``send_data ``, we set
503495``end_stream `` to ``True ``. This tells h2 (and the remote peer) that
504496we're done with sending data: the response is over. Because we know that
505- ``hyper `` will have ended its side of the stream, when we end ours the stream
497+ ``curl `` will have ended its side of the stream, when we end ours the stream
506498will be totally done with.
507499
508500We're nearly ready to go with this: we just need to plumb this function in.
@@ -594,9 +586,9 @@ With these changes, your ``h2server.py`` file should look like this:
594586 while True :
595587 handle(sock.accept()[0 ])
596588
597- Alright. Let's run this, and then run our ``hyper `` command again.
589+ Alright. Let's run this, and then run our ``curl `` command again.
598590
599- This time, nothing is printed from our server, and the ``hyper `` side prints
591+ This time, nothing is printed from our server, and the ``curl `` side prints
600592``it works! ``. Success! Try running it a few more times, and we can see that
601593not only does it work the first time, it works the other times too!
602594
@@ -705,15 +697,15 @@ file, which should now look like this:
705697 while True :
706698 handle(sock.accept()[0 ])
707699
708- Now, execute ``h2server.py `` and then point ``hyper `` at it again. You should
709- see something like the following output from ``hyper ``:
700+ Now, execute ``h2server.py `` and then point ``curl `` at it again. You should
701+ see something like the following output from ``curl ``:
710702
711703.. code-block :: console
712704
713- $ hyper --h2 GET http://localhost:8080/
705+ $ curl -v --http2-prior-knowledge http://localhost:8080/
714706 {":scheme": "http", ":authority": "localhost", ":method": "GET", ":path": "/"}
715707
716- Here you can see the HTTP/2 request 'special headers' that ``hyper `` sends.
708+ Here you can see the HTTP/2 request 'special headers' that ``curl `` sends.
717709These are similar to the ``:status `` header we have to send on our response:
718710they encode important parts of the HTTP request in a clearly-defined way. If
719711you were writing a client stack using h2, you'd need to make sure you
@@ -758,3 +750,4 @@ it, there are a few directions you could investigate:
758750.. _PyOpenSSL : http://pyopenssl.readthedocs.org/
759751.. _Eventlet example : https://github.com/python-hyper/h2/blob/master/examples/eventlet/eventlet-server.py
760752.. _curl : https://curl.se/docs/http2.html
753+ .. _httpx : https://www.python-httpx.org/
0 commit comments