Skip to content

Commit 4224ea7

Browse files
committed
Add basic Tornado example.
1 parent 6e00a93 commit 4224ea7

File tree

3 files changed

+130
-0
lines changed

3 files changed

+130
-0
lines changed

examples/tornado/server.crt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIDUjCCAjoCCQCQmNzzpQTCijANBgkqhkiG9w0BAQUFADBrMQswCQYDVQQGEwJH
3+
QjEPMA0GA1UECBMGTG9uZG9uMQ8wDQYDVQQHEwZMb25kb24xETAPBgNVBAoTCGh5
4+
cGVyLWgyMREwDwYDVQQLEwhoeXBleS1oMjEUMBIGA1UEAxMLZXhhbXBsZS5jb20w
5+
HhcNMTUwOTE2MjAyOTA0WhcNMTYwOTE1MjAyOTA0WjBrMQswCQYDVQQGEwJHQjEP
6+
MA0GA1UECBMGTG9uZG9uMQ8wDQYDVQQHEwZMb25kb24xETAPBgNVBAoTCGh5cGVy
7+
LWgyMREwDwYDVQQLEwhoeXBleS1oMjEUMBIGA1UEAxMLZXhhbXBsZS5jb20wggEi
8+
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC74ZeB4Jdb5cnC9KXXLJuzjwTg
9+
45q5EeShDYQe0TbKgreiUP6clU3BR0fFAVedN1q/LOuQ1HhvrDk1l4TfGF2bpCIq
10+
K+U9CnzcQknvdpyyVeOLtSsCjOPk4xydHwkQxwJvHVdtJx4CzDDqGbHNHCF/9gpQ
11+
lsa3JZW+tIZLK0XMEPFQ4XFXgegxTStO7kBBPaVIgG9Ooqc2MG4rjMNUpxa28WF1
12+
SyqWTICf2N8T/C+fPzbQLKCWrFrKUP7WQlOaqPNQL9bCDhSTPRTwQOc2/MzVZ9gT
13+
Xr0Z+JMTXwkSMKO52adE1pmKt00jJ1ecZBiJFyjx0X6hH+/59dLbG/7No+PzAgMB
14+
AAEwDQYJKoZIhvcNAQEFBQADggEBAG3UhOCa0EemL2iY+C+PR6CwEHQ+n7vkBzNz
15+
gKOG+Q39spyzqU1qJAzBxLTE81bIQbDg0R8kcLWHVH2y4zViRxZ0jHUFKMgjONW+
16+
Aj4evic/2Y/LxpLxCajECq/jeMHYrmQONszf9pbc0+exrQpgnwd8asfsM3d/FJS2
17+
5DIWryCKs/61m9vYL8icWx/9cnfPkBoNv1ER+V1L1TH3ARvABh406SBaeqLTm/kG
18+
MNuKytKWJsQbNlxzWHVgkKzVsBKvYj0uIEJpClIhbe6XNYRDy8T8mKXVWhJuxH4p
19+
/agmCG3nxO8aCrUK/EVmbWmVIfCH3t7jlwMX1nJ8MsRE7Ydnk8I=
20+
-----END CERTIFICATE-----

examples/tornado/server.key

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
-----BEGIN RSA PRIVATE KEY-----
2+
MIIEpQIBAAKCAQEAu+GXgeCXW+XJwvSl1yybs48E4OOauRHkoQ2EHtE2yoK3olD+
3+
nJVNwUdHxQFXnTdavyzrkNR4b6w5NZeE3xhdm6QiKivlPQp83EJJ73acslXji7Ur
4+
Aozj5OMcnR8JEMcCbx1XbSceAsww6hmxzRwhf/YKUJbGtyWVvrSGSytFzBDxUOFx
5+
V4HoMU0rTu5AQT2lSIBvTqKnNjBuK4zDVKcWtvFhdUsqlkyAn9jfE/wvnz820Cyg
6+
lqxaylD+1kJTmqjzUC/Wwg4Ukz0U8EDnNvzM1WfYE169GfiTE18JEjCjudmnRNaZ
7+
irdNIydXnGQYiRco8dF+oR/v+fXS2xv+zaPj8wIDAQABAoIBAQCsdq278+0c13d4
8+
tViSh4k5r1w8D9IUdp9XU2/nVgckqA9nOVAvbkJc3FC+P7gsQgbUHKj0XoVbhU1S
9+
q461t8kduPH/oiGhAcKR8WurHEdE0OC6ewhLJAeCMRQwCrAorXXHh7icIt9ClCuG
10+
iSWUcXEy5Cidx3oL3r1xvIbV85fzdDtE9RC1I/kMjAy63S47YGiqh5vYmJkCa8rG
11+
Dsd1sEMDPr63XJpqJj3uHRcPvySgXTa+ssTmUH8WJlPTjvDB5hnPz+lkk2JKVPNu
12+
8adzftZ6hSun+tsc4ZJp8XhGu/m/7MjxWh8MeupLHlXcOEsnj4uHQQsOM3zHojr3
13+
aDCZiC1pAoGBAOAhwe1ujoS2VJ5RXJ9KMs7eBER/02MDgWZjo54Jv/jFxPWGslKk
14+
QQceuTe+PruRm41nzvk3q4iZXt8pG0bvpgigN2epcVx/O2ouRsUWWBT0JrVlEzha
15+
TIvWjtZ5tSQExXgHL3VlM9+ka40l+NldLSPn25+prizaqhalWuvTpP23AoGBANaY
16+
VhEI6yhp0BBUSATEv9lRgkwx3EbcnXNXPQjDMOthsyfq7FxbdOBEK1rwSDyuE6Ij
17+
zQGcTOfdiur5Ttg0OQilTJIXJAlpoeecOQ9yGma08c5FMXVJJvcZUuWRZWg1ocQj
18+
/hx0WVE9NwOoKwTBERv8HX7vJOFRZyvgkJwFxoulAoGAe4m/1XoZrga9z2GzNs10
19+
AdgX7BW00x+MhH4pIiPnn1yK+nYa9jg4647Asnv3IfXZEnEEgRNxReKbi0+iDFBt
20+
aNW+lDGuHTi37AfD1EBDnpEQgO1MUcRb6rwBkTAWatsCaO00+HUmyX9cFLm4Vz7n
21+
caILyQ6CxZBlLgRIgDHxADMCgYEAtubsJGTHmZBmSCStpXLUWbOBLNQqfTM398DZ
22+
QoirP1PsUQ+IGUfSG/u+QCogR6fPEBkXeFHxsoY/Cvsm2lvYaKgK1VFn46Xm2vNq
23+
JuIH4pZCqp6LAv4weddZslT0a5eaowRSZ4o7PmTAaRuCXvD3VjTSJwhJFMo+90TV
24+
vEWn7gkCgYEAkk+unX9kYmKoUdLh22/tzQekBa8WqMxXDwzBCECTAs2GlpL/f73i
25+
zD15TnaNfLP6Q5RNb0N9tb0Gz1wSkwI1+jGAQLnh2K9X9cIVIqJn8Mf/KQa/wUDV
26+
Tb1j7FoGUEgX7vbsyWuTd8P76kNYyGqCss1XmbttcSolqpbIdlSUcO0=
27+
-----END RSA PRIVATE KEY-----

examples/tornado/tornado-server.py

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
#!/usr/bin/env python
2+
3+
import collections
4+
import json
5+
import ssl
6+
7+
import tornado.gen
8+
import tornado.ioloop
9+
import tornado.iostream
10+
import tornado.tcpserver
11+
12+
from h2.connection import H2Connection
13+
from h2.events import RequestReceived, DataReceived
14+
15+
16+
def create_ssl_context(certfile, keyfile):
17+
ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
18+
ssl_context.options |= (
19+
ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 | ssl.OP_NO_COMPRESSION
20+
)
21+
ssl_context.set_ciphers("ECDHE+AESGCM")
22+
ssl_context.load_cert_chain(certfile=certfile, keyfile=keyfile)
23+
ssl_context.set_alpn_protocols(["h2"])
24+
return ssl_context
25+
26+
27+
class H2Server(tornado.tcpserver.TCPServer):
28+
29+
@tornado.gen.coroutine
30+
def handle_stream(self, stream, address):
31+
handler = EchoHeadersHandler(stream)
32+
yield handler.handle()
33+
34+
35+
class EchoHeadersHandler(object):
36+
37+
def __init__(self, stream):
38+
self.stream = stream
39+
self.conn = H2Connection(client_side=False)
40+
41+
@tornado.gen.coroutine
42+
def handle(self):
43+
self.conn.initiate_connection()
44+
yield self.stream.write(self.conn.data_to_send())
45+
46+
while True:
47+
try:
48+
data = yield self.stream.read_bytes(65535, partial=True)
49+
if not data:
50+
break
51+
52+
events = self.conn.receive_data(data)
53+
for event in events:
54+
if isinstance(event, RequestReceived):
55+
self.request_received(event.headers, event.stream_id)
56+
elif isinstance(event, DataReceived):
57+
self.conn.reset_stream(event.stream_id)
58+
59+
yield self.stream.write(self.conn.data_to_send())
60+
61+
except tornado.iostream.StreamClosedError:
62+
break
63+
64+
def request_received(self, headers, stream_id):
65+
headers = collections.OrderedDict(headers)
66+
data = json.dumps({'headers': headers}, indent=4).encode('utf-8')
67+
68+
response_headers = (
69+
(':status', '200'),
70+
('content-type', 'application/json'),
71+
('content-length', len(data)),
72+
('server', 'tornado-h2'),
73+
)
74+
self.conn.send_headers(stream_id, response_headers)
75+
self.conn.send_data(stream_id, data, end_stream=True)
76+
77+
78+
if __name__ == '__main__':
79+
ssl_context = create_ssl_context('server.crt', 'server.key')
80+
server = H2Server(ssl_options=ssl_context)
81+
server.listen(8888)
82+
io_loop = tornado.ioloop.IOLoop.current()
83+
io_loop.start()

0 commit comments

Comments
 (0)