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
33d35912
Commit
33d35912
authored
Aug 28, 2012
by
Tatsuhiro Tsujikawa
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
python: add simple SPDY client function urlfetch()
parent
6b64276c
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
191 additions
and
0 deletions
+191
-0
python/spdylay.pyx
python/spdylay.pyx
+191
-0
No files found.
python/spdylay.pyx
View file @
33d35912
...
...
@@ -1481,6 +1481,197 @@ try:
socketserver
.
ThreadingMixIn
.
process_request
(
self
,
request
,
client_address
)
# Simple SPDY client implementation. Since this implementation
# uses TLS NPN, Python 3.3.0 or later is required.
from
urllib.parse
import
urlsplit
class
BaseSPDYStreamHandler
:
def
__init__
(
self
,
uri
,
fetcher
):
self
.
uri
=
uri
self
.
fetcher
=
fetcher
self
.
stream_id
=
None
def
on_header
(
self
,
nv
):
pass
def
on_data
(
self
,
data
):
pass
def
on_close
(
self
,
status_code
):
pass
class
UrlFetchError
(
Exception
):
pass
class
UrlFetcher
:
def
__init__
(
self
,
server_address
,
uris
,
StreamHandlerClass
):
self
.
server_address
=
server_address
self
.
handlers
=
[
StreamHandlerClass
(
uri
,
self
)
for
uri
in
uris
]
self
.
streams
=
{}
self
.
finished
=
[]
self
.
ctx
=
ssl
.
SSLContext
(
ssl
.
PROTOCOL_SSLv23
)
self
.
ctx
.
options
=
ssl
.
OP_ALL
|
ssl
.
OP_NO_SSLv2
|
\
ssl
.
OP_NO_COMPRESSION
self
.
ctx
.
set_npn_protocols
(
get_npn_protocols
())
def
send_cb
(
self
,
session
,
data
):
return
self
.
sock
.
send
(
data
)
def
before_ctrl_send_cb
(
self
,
session
,
frame
):
if
frame
.
frame_type
==
SYN_STREAM
:
handler
=
session
.
get_stream_user_data
(
frame
.
stream_id
)
if
handler
:
handler
.
stream_id
=
frame
.
stream_id
self
.
streams
[
handler
.
stream_id
]
=
handler
def
on_ctrl_recv_cb
(
self
,
session
,
frame
):
if
frame
.
frame_type
==
SYN_REPLY
or
frame
.
frame_type
==
HEADERS
:
if
frame
.
stream_id
in
self
.
streams
:
handler
=
self
.
streams
[
frame
.
stream_id
]
handler
.
on_header
(
frame
.
nv
)
def
on_data_chunk_recv_cb
(
self
,
session
,
flags
,
stream_id
,
data
):
if
stream_id
in
self
.
streams
:
handler
=
self
.
streams
[
stream_id
]
handler
.
on_data
(
data
)
def
on_stream_close_cb
(
self
,
session
,
stream_id
,
status_code
):
if
stream_id
in
self
.
streams
:
handler
=
self
.
streams
[
stream_id
]
handler
.
on_close
(
status_code
)
del
self
.
streams
[
stream_id
]
self
.
finished
.
append
(
handler
)
def
connect
(
self
,
server_address
):
self
.
sock
=
None
for
res
in
socket
.
getaddrinfo
(
server_address
[
0
],
server_address
[
1
],
socket
.
AF_UNSPEC
,
socket
.
SOCK_STREAM
):
af
,
socktype
,
proto
,
canonname
,
sa
=
res
try
:
self
.
sock
=
socket
.
socket
(
af
,
socktype
,
proto
)
except
OSError
as
msg
:
self
.
sock
=
None
continue
try
:
self
.
sock
.
connect
(
sa
)
except
OSError
as
msg
:
self
.
sock
.
close
()
self
.
sock
=
None
continue
break
else
:
raise
UrlFetchError
(
'Could not connect to {}'
\
.
format
(
server_address
))
def
tls_handshake
(
self
):
self
.
sock
=
self
.
ctx
.
wrap_socket
(
self
.
sock
,
server_side
=
False
,
do_handshake_on_connect
=
False
)
self
.
sock
.
do_handshake
()
self
.
version
=
npn_get_version
(
self
.
sock
.
selected_npn_protocol
())
if
self
.
version
==
0
:
raise
UrlFetchError
(
'NPN failed'
)
def
loop
(
self
):
self
.
connect
(
self
.
server_address
)
self
.
tls_handshake
()
self
.
sock
.
setblocking
(
False
)
session
=
Session
(
CLIENT
,
self
.
version
,
send_cb
=
self
.
send_cb
,
on_ctrl_recv_cb
=
self
.
on_ctrl_recv_cb
,
on_data_chunk_recv_cb
=
self
.
on_data_chunk_recv_cb
,
before_ctrl_send_cb
=
self
.
before_ctrl_send_cb
,
on_stream_close_cb
=
self
.
on_stream_close_cb
)
session
.
submit_settings
(
\
FLAG_SETTINGS_NONE
,
[(
SETTINGS_MAX_CONCURRENT_STREAMS
,
ID_FLAG_SETTINGS_NONE
,
100
)]
)
if
self
.
server_address
[
1
]
==
443
:
hostport
=
self
.
server_address
[
0
]
else
:
hostport
=
'{}:{}'
.
format
(
self
.
server_address
[
0
],
self
.
server_address
[
1
])
for
handler
in
self
.
handlers
:
res
=
urlsplit
(
handler
.
uri
)
if
res
.
path
:
path
=
res
.
path
else
:
path
=
'/'
if
res
.
query
:
path
=
'?'
.
join
([
path
,
res
.
query
])
session
.
submit_request
(
0
,
[(
':method'
,
'GET'
),
(
':scheme'
,
'https'
),
(
':path'
,
path
),
(
':version'
,
'HTTP/1.1'
),
(
':host'
,
hostport
),
(
'accept'
,
'*/*'
),
(
'user-agent'
,
'python-spdylay'
)],
stream_user_data
=
handler
)
while
(
session
.
want_read
()
or
session
.
want_write
())
\
and
not
len
(
self
.
finished
)
==
len
(
self
.
handlers
):
want_read
=
want_write
=
False
try
:
data
=
self
.
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
([
self
.
sock
]
if
want_read
else
[],
[
self
.
sock
]
if
want_write
else
[],
[])
def
_urlfetch_session_one
(
uris
,
StreamHandlerClass
):
res
=
urlsplit
(
uris
[
0
])
if
res
.
scheme
!=
'https'
:
raise
UrlFetchError
(
'Unsupported scheme {}'
.
format
(
res
.
scheme
))
hostname
=
res
.
hostname
port
=
res
.
port
if
res
.
port
else
443
f
=
UrlFetcher
((
hostname
,
port
),
uris
,
StreamHandlerClass
)
f
.
loop
()
def
urlfetch
(
uri_or_uris
,
StreamHandlerClass
):
if
isinstance
(
uri_or_uris
,
str
):
_urlfetch_session_one
([
uri_or_uris
],
StreamHandlerClass
)
else
:
uris
=
[]
prev_addr
=
(
None
,
None
)
for
uri
in
uri_or_uris
:
res
=
urlsplit
(
uri
)
port
=
res
.
port
if
res
.
port
else
443
if
prev_addr
!=
(
res
.
hostname
,
port
):
if
uris
:
_urlfetch_session_one
(
uris
,
StreamHandlerClass
)
uris
=
[]
prev_addr
=
(
res
.
hostname
,
port
)
uris
.
append
(
uri
)
if
uris
:
_urlfetch_session_one
(
uris
,
StreamHandlerClass
)
except
ImportError
:
# No server for 2.x because they lack TLS NPN.
pass
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