@@ -213,26 +213,18 @@ connection object and start handing it data. For now, let's just see what
213
213
happens as we feed it data.
214
214
215
215
To 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:
222
219
223
220
.. code-block :: console
224
221
225
- $ hyper GET https://nghttp2.org/httpbin/get
222
+ $ curl --http2 https://nghttp2.org/httpbin/get
226
223
{'args': {},
227
224
'headers': {'Host': 'nghttp2.org'},
228
225
'origin': '10.0.0.2',
229
226
'url': 'https://nghttp2.org/httpbin/get'}
230
227
231
- Equivalent code with curl would look like this:
232
-
233
- .. code-block :: console
234
-
235
- $ curl --http2 https://nghttp2.org/httpbin/get
236
228
237
229
To use it with our server though, you will need to invoke it with a different
238
230
``--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:
301
293
handle(sock.accept()[0 ])
302
294
303
295
Running that in one shell, in your other shell you can run
304
- ``hyper --h2 GET http://localhost:8080/ ``. For the ``curl `` use
305
296
``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:
308
299
309
300
.. code-block :: console
310
301
311
302
$ python h2server.py
312
303
[<h2.events.RemoteSettingsChanged object at 0x10c4ee390>]
313
304
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
315
306
to do this a few times, to see how things behave.
316
307
317
308
So, 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
320
311
returned us a single event object:
321
312
:class: `RemoteSettingsChanged <h2.events.RemoteSettingsChanged> `.
322
313
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 ``
325
316
window, you'll notice that it hangs for a while and then eventually fails with
326
317
a socket timeout. It was waiting for something: what?
327
318
328
319
Well, it turns out that at the start of a connection, both sides need to send
329
320
a bit of data, called "the HTTP/2 preamble". We don't need to get into too much
330
321
detail 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,
332
323
but we didn't.
333
324
334
325
Let's do that next.
@@ -401,9 +392,10 @@ Your ``h2server.py`` script should now look like this:
401
392
402
393
403
394
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:
407
399
408
400
.. code-block :: console
409
401
@@ -423,17 +415,17 @@ Finally, even more data that triggers *two* events:
423
415
:class: `RequestReceived <h2.events.RequestReceived> ` and
424
416
:class: `StreamEnded <h2.events.StreamEnded> `.
425
417
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,
427
419
acknowledging ours, and then sending us a request. Then it ends a *stream *,
428
420
which is a HTTP/2 communications channel that holds a request and response
429
421
pair.
430
422
431
423
A stream isn't done until it's either *reset * or both sides *close * it:
432
424
in 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
434
426
data on that stream. That means the request is done.
435
427
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
437
429
that.
438
430
439
431
@@ -502,7 +494,7 @@ one exception is headers: h2 will automatically encode those into UTF-8.
502
494
The last thing to note is that on our call to ``send_data ``, we set
503
495
``end_stream `` to ``True ``. This tells h2 (and the remote peer) that
504
496
we'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
506
498
will be totally done with.
507
499
508
500
We'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:
594
586
while True :
595
587
handle(sock.accept()[0 ])
596
588
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.
598
590
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
600
592
``it works! ``. Success! Try running it a few more times, and we can see that
601
593
not only does it work the first time, it works the other times too!
602
594
@@ -705,15 +697,15 @@ file, which should now look like this:
705
697
while True :
706
698
handle(sock.accept()[0 ])
707
699
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 ``:
710
702
711
703
.. code-block :: console
712
704
713
- $ hyper --h2 GET http://localhost:8080/
705
+ $ curl -v --http2-prior-knowledge http://localhost:8080/
714
706
{":scheme": "http", ":authority": "localhost", ":method": "GET", ":path": "/"}
715
707
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.
717
709
These are similar to the ``:status `` header we have to send on our response:
718
710
they encode important parts of the HTTP request in a clearly-defined way. If
719
711
you 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:
758
750
.. _PyOpenSSL : http://pyopenssl.readthedocs.org/
759
751
.. _Eventlet example : https://github.com/python-hyper/h2/blob/master/examples/eventlet/eventlet-server.py
760
752
.. _curl : https://curl.se/docs/http2.html
753
+ .. _httpx : https://www.python-httpx.org/
0 commit comments