Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
N
nghttp2
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
nghttp2
Commits
7ce24fc1
Commit
7ce24fc1
authored
Aug 24, 2012
by
Tatsuhiro Tsujikawa
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
python: rewritten simple SPDY server. Add npn_get_version() helper function.
parent
dbe7cda7
Changes
4
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
423 additions
and
143 deletions
+423
-143
doc/python.rst
doc/python.rst
+14
-0
python/cspdylay.pxd
python/cspdylay.pxd
+3
-0
python/spdylay.pyx
python/spdylay.pyx
+388
-0
python/spdyserv.py
python/spdyserv.py
+18
-143
No files found.
doc/python.rst
View file @
7ce24fc1
...
...
@@ -543,6 +543,20 @@ Session Objects
:py:class:`StreamClosedError` will be raised if the stream is
already closed or does not exist.
Helper Functions
----------------
.. py:function:: npn_get_version(proto)
Returns SPDY version which spdylay library supports from the given
protocol name. The *proto* is the unicode string to the protocol
name. Currently, ``spdy/2`` and ``spdy/3`` are supported. The
returned nonzero SPDY version can be passed as the version
argument in :py:class:`Session` constructor.
This function returns nonzero SPDY version if it succeeds, or 0.
Data Provider Objects
---------------------
...
...
python/cspdylay.pxd
View file @
7ce24fc1
...
...
@@ -322,3 +322,6 @@ cdef extern from 'spdylay/spdylay.h':
int
spdylay_submit_window_update
(
spdylay_session
*
session
,
int32_t
stream_id
,
int32_t
delta_window_size
)
uint16_t
spdylay_npn_get_version
(
unsigned
char
*
proto
,
size_t
protolen
)
python/spdylay.pyx
View file @
7ce24fc1
This diff is collapsed.
Click to expand it.
python/spdyserv.py
View file @
7ce24fc1
#!/usr/bin/env python
# The example SPDY server. You need Python 3.3 or later because we
# use TLS NPN. Put private key and certificate file in the current
# working directory.
import
socket
import
threading
import
socketserver
import
ssl
import
io
import
select
# The example SPDY server. Python 3.3 or later is required because TLS
# NPN is used in spdylay.ThreadedSPDYServer. Put private key and
# certificate file in the current working directory.
import
spdylay
...
...
@@ -18,150 +11,32 @@ KEY_FILE='server.key'
# certificate file
CERT_FILE
=
'server.crt'
def
send_cb
(
session
,
data
):
ssctrl
=
session
.
user_data
wlen
=
ssctrl
.
sock
.
send
(
data
)
return
wlen
def
read_cb
(
session
,
stream_id
,
length
,
read_ctrl
,
source
):
data
=
source
.
read
(
length
)
if
not
data
:
read_ctrl
.
flags
=
spdylay
.
READ_EOF
return
data
class
MySPDYRequestHandler
(
spdylay
.
BaseSPDYRequestHandler
):
def
on_ctrl_recv_cb
(
session
,
frame
):
ssctrl
=
session
.
user_data
if
frame
.
frame_type
==
spdylay
.
SYN_STREAM
:
stctrl
=
StreamCtrl
(
frame
.
stream_id
)
stctrl
.
headers
.
extend
(
frame
.
nv
)
ssctrl
.
streams
[
frame
.
stream_id
]
=
stctrl
def
do_GET
(
self
):
if
self
.
path
==
'/notfound'
:
self
.
send_error
(
404
)
return
def
on_stream_close_cb
(
session
,
stream_id
,
status_code
):
ssctrl
=
session
.
user_data
if
stream_id
in
ssctrl
.
streams
:
del
ssctrl
.
streams
[
stream_id
]
self
.
send_response
(
200
)
self
.
send_header
(
'conten-type'
,
'text/html; charset=UTF-8'
)
def
on_request_recv_cb
(
session
,
stream_id
):
ssctrl
=
session
.
user_data
if
stream_id
in
ssctrl
.
streams
:
stctrl
=
ssctrl
.
streams
[
stream_id
]
for
name
,
value
in
stctrl
.
headers
:
if
name
==
'user-agent'
:
user_agent
=
value
break
else
:
user_agent
=
''
html
=
'''
\
content
=
'''
\
<html>
<head><title>SPDY FTW</title></head>
<body>
<h1>SPDY FTW</h1>
<p>The age of HTTP/1.1 is over. The time of SPDY has come.</p>
<p>Your browser {} supports SPDY.</p>
</body>
</html>
'''
.
format
(
user_agent
)
data_prd
=
spdylay
.
DataProvider
(
io
.
BytesIO
(
bytes
(
html
,
'utf-8'
)),
read_cb
)
stctrl
.
data_prd
=
data_prd
nv
=
[(
':status'
,
'200 OK'
),
(
':version'
,
'HTTP/1.1'
),
(
'server'
,
'python-spdylay'
)]
session
.
submit_response
(
stream_id
,
nv
,
data_prd
)
class
StreamCtrl
:
def
__init__
(
self
,
stream_id
):
self
.
stream_id
=
stream_id
self
.
data_prd
=
None
self
.
headers
=
[]
class
SessionCtrl
:
def
__init__
(
self
,
sock
):
self
.
sock
=
sock
self
.
streams
=
{}
class
ThreadedSPDYRequestHandler
(
socketserver
.
BaseRequestHandler
):
def
handle
(
self
):
ctx
=
ssl
.
SSLContext
(
ssl
.
PROTOCOL_SSLv23
)
ctx
.
load_cert_chain
(
CERT_FILE
,
KEY_FILE
)
ctx
.
set_npn_protocols
([
'spdy/3'
,
'spdy/2'
])
sock
=
ctx
.
wrap_socket
(
self
.
request
,
server_side
=
True
,
do_handshake_on_connect
=
False
)
sock
.
setblocking
(
False
)
</html>'''
.
encode
(
'UTF-8'
)
while
True
:
try
:
sock
.
do_handshake
()
break
except
ssl
.
SSLWantReadError
as
e
:
select
.
select
([
sock
],
[],
[])
except
ssl
.
SSLWantWriteError
as
e
:
select
.
select
([],
[
sock
],
[])
if
sock
.
selected_npn_protocol
()
==
'spdy/3'
:
version
=
spdylay
.
PROTO_SPDY3
elif
sock
.
selected_npn_protocol
()
==
'spdy/2'
:
version
=
spdylay
.
PROTO_SPDY2
else
:
return
ssctrl
=
SessionCtrl
(
sock
)
session
=
spdylay
.
Session
(
spdylay
.
SERVER
,
version
,
send_cb
=
send_cb
,
on_ctrl_recv_cb
=
on_ctrl_recv_cb
,
on_stream_close_cb
=
on_stream_close_cb
,
on_request_recv_cb
=
on_request_recv_cb
,
user_data
=
ssctrl
)
session
.
submit_settings
(
\
spdylay
.
FLAG_SETTINGS_NONE
,
[(
spdylay
.
SETTINGS_MAX_CONCURRENT_STREAMS
,
spdylay
.
ID_FLAG_SETTINGS_NONE
,
100
)])
while
session
.
want_read
()
or
session
.
want_write
():
want_read
=
want_write
=
False
try
:
data
=
sock
.
recv
(
4096
)
if
data
:
session
.
recv
(
data
)
else
:
break
except
ssl
.
SSLWantReadError
:
want_read
=
True
except
ssl
.
SSLWantWriteError
:
want_write
=
True
try
:
session
.
send
()
except
ssl
.
SSLWantReadError
:
want_read
=
True
except
ssl
.
SSLWantWriteError
:
want_write
=
True
if
want_read
or
want_write
:
select
.
select
([
sock
]
if
want_read
else
[],
[
sock
]
if
want_write
else
[],
[])
class
ThreadedSPDYServer
(
socketserver
.
ThreadingMixIn
,
socketserver
.
TCPServer
):
def
__init__
(
self
,
svaddr
,
handler
):
self
.
allow_reuse_address
=
True
socketserver
.
TCPServer
.
__init__
(
self
,
svaddr
,
handler
)
self
.
wfile
.
write
(
content
)
if
__name__
==
"__main__"
:
# Port 0 means to select an arbitrary unused port
HOST
,
PORT
=
"localhost"
,
3000
server
=
ThreadedSPDYServer
((
HOST
,
PORT
),
ThreadedSPDYRequestHandler
)
ip
,
port
=
server
.
server_address
# Start a thread with the server -- that thread will then start one
# more thread for each request
server_thread
=
threading
.
Thread
(
target
=
server
.
serve_forever
)
# Exit the server thread when the main thread terminates
#server_thread.daemon = True
server_thread
.
start
()
server
=
spdylay
.
ThreadedSPDYServer
((
HOST
,
PORT
),
MySPDYRequestHandler
,
cert_file
=
CERT_FILE
,
key_file
=
KEY_FILE
)
server
.
start
()
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment