3
3
import os
4
4
from six .moves import http_client
5
5
from six .moves .urllib .parse import urlparse
6
+ from ssl import SSLWantReadError
7
+
6
8
7
9
class Stream :
8
- def __init__ (self , server , port = 80 , headers = {}, url = '/' ):
9
- ''' Initialize a stream object and an HTTP Connection
10
+ def __init__ (self , server , port = 80 , headers = {}, url = '/' , ssl_enabled = False ):
11
+ ''' Initialize a stream object and an HTTP or HTTPS connection
10
12
with chunked Transfer-Encoding to server:port with optional headers.
11
13
'''
12
14
self .maxtries = 5
@@ -17,6 +19,7 @@ def __init__(self, server, port=80, headers={}, url='/'):
17
19
self ._port = port
18
20
self ._headers = headers
19
21
self ._url = url
22
+ self ._ssl_enabled = ssl_enabled
20
23
self ._connect ()
21
24
22
25
def write (self , data , reconnect_on = ('' , 200 , )):
@@ -73,17 +76,21 @@ def write(self, data, reconnect_on=('', 200, )):
73
76
def _get_proxy_config (self ):
74
77
"""
75
78
Determine if self._url should be passed through a proxy. If so, return
76
- the appropriate proxy_server and proxy_port
79
+ the appropriate proxy_server and proxy_port. Assumes https_proxy is used
80
+ when ssl_enabled=True.
77
81
78
82
"""
79
83
80
84
proxy_server = None
81
85
proxy_port = None
86
+ ssl_enabled = self ._ssl_enabled
82
87
83
- ## only doing HTTPConnection, so only use http_proxy
84
- proxy = os .environ .get ("http_proxy" )
88
+ if ssl_enabled :
89
+ proxy = os .environ .get ("https_proxy" )
90
+ else :
91
+ proxy = os .environ .get ("http_proxy" )
85
92
no_proxy = os .environ .get ("no_proxy" )
86
- no_proxy_url = no_proxy and self ._url in no_proxy
93
+ no_proxy_url = no_proxy and self ._server in no_proxy
87
94
88
95
if proxy and not no_proxy_url :
89
96
p = urlparse (proxy )
@@ -93,19 +100,30 @@ def _get_proxy_config(self):
93
100
return proxy_server , proxy_port
94
101
95
102
def _connect (self ):
96
- ''' Initialize an HTTP connection with chunked Transfer-Encoding
103
+ ''' Initialize an HTTP/HTTPS connection with chunked Transfer-Encoding
97
104
to server:port with optional headers.
98
105
'''
99
106
server = self ._server
100
107
port = self ._port
101
108
headers = self ._headers
109
+ ssl_enabled = self ._ssl_enabled
102
110
proxy_server , proxy_port = self ._get_proxy_config ()
103
111
104
112
if (proxy_server and proxy_port ):
105
- self ._conn = http_client .HTTPConnection (proxy_server , proxy_port )
113
+ if ssl_enabled :
114
+ self ._conn = http_client .HTTPSConnection (
115
+ proxy_server , proxy_port
116
+ )
117
+ else :
118
+ self ._conn = http_client .HTTPConnection (
119
+ proxy_server , proxy_port
120
+ )
106
121
self ._conn .set_tunnel (server , port )
107
122
else :
108
- self ._conn = http_client .HTTPConnection (server , port )
123
+ if ssl_enabled :
124
+ self ._conn = http_client .HTTPSConnection (server , port )
125
+ else :
126
+ self ._conn = http_client .HTTPConnection (server , port )
109
127
110
128
self ._conn .putrequest ('POST' , self ._url )
111
129
self ._conn .putheader ('Transfer-Encoding' , 'chunked' )
@@ -236,6 +254,13 @@ def _isconnected(self):
236
254
# let's just assume that we're still connected and
237
255
# hopefully recieve some data on the next try.
238
256
return True
257
+ elif isinstance (e , SSLWantReadError ):
258
+ # From: https://docs.python.org/3/library/ssl.html
259
+ # This is raised when trying to read or write data, but more
260
+ # data needs to be received on the underlying TCP transport
261
+ # before the request can be fulfilled. The socket is still
262
+ # connected to the server in this case.
263
+ return True
239
264
else :
240
265
# Unknown scenario
241
266
raise e
0 commit comments