10
10
11
11
12
12
class Stream :
13
- def __init__ (self , server , port = 80 , headers = {}, url = '/' , ssl_enabled = False ,
14
- ssl_verification_enabled = True ):
15
- ''' Initialize a stream object and an HTTP or HTTPS connection
13
+ def __init__ (
14
+ self ,
15
+ server ,
16
+ port = 80 ,
17
+ headers = {},
18
+ url = "/" ,
19
+ ssl_enabled = False ,
20
+ ssl_verification_enabled = True ,
21
+ ):
22
+ """ Initialize a stream object and an HTTP or HTTPS connection
16
23
with chunked Transfer-Encoding to server:port with optional headers.
17
- '''
24
+ """
18
25
self .maxtries = 5
19
26
self ._tries = 0
20
27
self ._delay = 1
@@ -27,23 +34,25 @@ def __init__(self, server, port=80, headers={}, url='/', ssl_enabled=False,
27
34
self ._ssl_verification_enabled = ssl_verification_enabled
28
35
self ._connect ()
29
36
30
- def write (self , data , reconnect_on = ('' , 200 , 502 )):
31
- ''' Send `data` to the server in chunk-encoded form.
37
+ def write (self , data , reconnect_on = ("" , 200 , 502 )):
38
+ """ Send `data` to the server in chunk-encoded form.
32
39
Check the connection before writing and reconnect
33
40
if disconnected and if the response status code is in `reconnect_on`.
34
41
35
42
The response may either be an HTTPResponse object or an empty string.
36
- '''
43
+ """
37
44
38
45
if not self ._isconnected ():
39
46
40
47
# Attempt to get the response.
41
48
response = self ._getresponse ()
42
49
43
50
# Reconnect depending on the status code.
44
- if ((response == '' and '' in reconnect_on ) or
45
- (response and isinstance (response , http_client .HTTPResponse ) and
46
- response .status in reconnect_on )):
51
+ if (response == "" and "" in reconnect_on ) or (
52
+ response
53
+ and isinstance (response , http_client .HTTPResponse )
54
+ and response .status in reconnect_on
55
+ ):
47
56
self ._reconnect ()
48
57
49
58
elif response and isinstance (response , http_client .HTTPResponse ):
@@ -56,23 +65,25 @@ def write(self, data, reconnect_on=('', 200, 502)):
56
65
# like Invalid Credentials.
57
66
# This allows the user to determine when
58
67
# to reconnect.
59
- raise Exception ("Server responded with "
60
- "status code: {status_code}\n "
61
- "and message: {msg}."
62
- .format (status_code = response .status ,
63
- msg = response .read ()))
68
+ raise Exception (
69
+ "Server responded with "
70
+ "status code: {status_code}\n "
71
+ "and message: {msg}." .format (
72
+ status_code = response .status , msg = response .read ()
73
+ )
74
+ )
64
75
65
- elif response == '' :
66
- raise Exception ("Attempted to write but socket "
67
- "was not connected." )
76
+ elif response == "" :
77
+ raise Exception ("Attempted to write but socket " "was not connected." )
68
78
69
79
try :
70
80
msg = data
71
- msglen = format (len (msg ), 'x' ) # msg length in hex
81
+ msglen = format (len (msg ), "x" ) # msg length in hex
72
82
# Send the message in chunk-encoded form
73
83
self ._conn .sock .setblocking (1 )
74
- self ._conn .send ('{msglen}\r \n {msg}\r \n '
75
- .format (msglen = msglen , msg = msg ).encode ('utf-8' ))
84
+ self ._conn .send (
85
+ "{msglen}\r \n {msg}\r \n " .format (msglen = msglen , msg = msg ).encode ("utf-8" )
86
+ )
76
87
self ._conn .sock .setblocking (0 )
77
88
except http_client .socket .error :
78
89
self ._reconnect ()
@@ -94,11 +105,9 @@ def _get_proxy_config(self):
94
105
ssl_enabled = self ._ssl_enabled
95
106
96
107
if ssl_enabled :
97
- proxy = (os .environ .get ("https_proxy" ) or
98
- os .environ .get ("HTTPS_PROXY" ))
108
+ proxy = os .environ .get ("https_proxy" ) or os .environ .get ("HTTPS_PROXY" )
99
109
else :
100
- proxy = (os .environ .get ("http_proxy" ) or
101
- os .environ .get ("HTTP_PROXY" ))
110
+ proxy = os .environ .get ("http_proxy" ) or os .environ .get ("HTTP_PROXY" )
102
111
103
112
no_proxy = os .environ .get ("no_proxy" ) or os .environ .get ("NO_PROXY" )
104
113
no_proxy_url = no_proxy and self ._server in no_proxy
@@ -131,82 +140,78 @@ def _get_ssl_context(self):
131
140
return context
132
141
133
142
def _connect (self ):
134
- ''' Initialize an HTTP/HTTPS connection with chunked Transfer-Encoding
143
+ """ Initialize an HTTP/HTTPS connection with chunked Transfer-Encoding
135
144
to server:port with optional headers.
136
- '''
145
+ """
137
146
server = self ._server
138
147
port = self ._port
139
148
headers = self ._headers
140
149
ssl_enabled = self ._ssl_enabled
141
150
proxy_server , proxy_port , proxy_auth = self ._get_proxy_config ()
142
151
143
- if ( proxy_server and proxy_port ) :
152
+ if proxy_server and proxy_port :
144
153
if ssl_enabled :
145
154
context = self ._get_ssl_context ()
146
155
self ._conn = http_client .HTTPSConnection (
147
156
proxy_server , proxy_port , context = context
148
157
)
149
158
else :
150
- self ._conn = http_client .HTTPConnection (
151
- proxy_server , proxy_port
152
- )
159
+ self ._conn = http_client .HTTPConnection (proxy_server , proxy_port )
153
160
154
161
tunnel_headers = None
155
162
if proxy_auth :
156
- tunnel_headers = {' Proxy-Authorization' : proxy_auth }
163
+ tunnel_headers = {" Proxy-Authorization" : proxy_auth }
157
164
158
165
self ._conn .set_tunnel (server , port , headers = tunnel_headers )
159
166
else :
160
167
if ssl_enabled :
161
168
context = self ._get_ssl_context ()
162
- self ._conn = http_client .HTTPSConnection (
163
- server , port , context = context
164
- )
169
+ self ._conn = http_client .HTTPSConnection (server , port , context = context )
165
170
else :
166
171
self ._conn = http_client .HTTPConnection (server , port )
167
172
168
- self ._conn .putrequest (' POST' , self ._url )
169
- self ._conn .putheader (' Transfer-Encoding' , ' chunked' )
173
+ self ._conn .putrequest (" POST" , self ._url )
174
+ self ._conn .putheader (" Transfer-Encoding" , " chunked" )
170
175
for header in headers :
171
176
self ._conn .putheader (header , headers [header ])
172
177
self ._conn .endheaders ()
173
178
174
179
# Set blocking to False prevents recv
175
180
# from blocking while waiting for a response.
176
181
self ._conn .sock .setblocking (False )
177
- self ._bytes = six .b ('' )
182
+ self ._bytes = six .b ("" )
178
183
self ._reset_retries ()
179
184
time .sleep (0.5 )
180
185
181
186
def close (self ):
182
- ''' Close the connection to server.
187
+ """ Close the connection to server.
183
188
184
189
If available, return a http_client.HTTPResponse object.
185
190
186
191
Closing the connection involves sending the
187
192
Transfer-Encoding terminating bytes.
188
- '''
193
+ """
189
194
self ._reset_retries ()
190
195
self ._closed = True
191
196
192
197
# Chunked-encoded posts are terminated with '0\r\n\r\n'
193
198
# For some reason, either Python or node.js seems to
194
199
# require an extra \r\n.
195
200
try :
196
- self ._conn .send (' \r \n 0\r \n \r \n ' .encode (' utf-8' ))
201
+ self ._conn .send (" \r \n 0\r \n \r \n " .encode (" utf-8" ))
197
202
except http_client .socket .error :
198
203
# In case the socket has already been closed
199
- return ''
204
+ return ""
200
205
201
206
return self ._getresponse ()
202
207
203
208
def _getresponse (self ):
204
- ''' Read from recv and return a HTTPResponse object if possible.
209
+ """ Read from recv and return a HTTPResponse object if possible.
205
210
Either
206
211
1 - The client has succesfully closed the connection: Return ''
207
212
2 - The server has already closed the connection: Return the response
208
213
if possible.
209
- '''
214
+ """
210
215
# Wait for a response
211
216
self ._conn .sock .setblocking (True )
212
217
# Parse the response
@@ -217,8 +222,8 @@ def _getresponse(self):
217
222
except http_client .socket .error :
218
223
# For error 54: Connection reset by peer
219
224
# (and perhaps others)
220
- return six .b ('' )
221
- if _bytes == six .b ('' ):
225
+ return six .b ("" )
226
+ if _bytes == six .b ("" ):
222
227
break
223
228
else :
224
229
response += _bytes
@@ -227,19 +232,19 @@ def _getresponse(self):
227
232
228
233
# Convert the response string to a http_client.HTTPResponse
229
234
# object with a bit of a hack
230
- if response != six .b ('' ):
235
+ if response != six .b ("" ):
231
236
# Taken from
232
237
# http://pythonwise.blogspot.ca/2010/02/parse-http-response.html
233
238
try :
234
239
response = http_client .HTTPResponse (_FakeSocket (response ))
235
240
response .begin ()
236
241
except :
237
242
# Bad headers ... etc.
238
- response = six .b ('' )
243
+ response = six .b ("" )
239
244
return response
240
245
241
246
def _isconnected (self ):
242
- ''' Return True if the socket is still connected
247
+ """ Return True if the socket is still connected
243
248
to the server, False otherwise.
244
249
245
250
This check is done in 3 steps:
@@ -248,7 +253,7 @@ def _isconnected(self):
248
253
3 - Check if the server has returned any data. If they have,
249
254
assume that the server closed the response after they sent
250
255
the data, i.e. that the data was the HTTP response.
251
- '''
256
+ """
252
257
253
258
# 1 - check if we've closed the connection.
254
259
if self ._closed :
@@ -263,7 +268,7 @@ def _isconnected(self):
263
268
# 3 - Check if the server has returned any data.
264
269
# If they have, then start to store the response
265
270
# in _bytes.
266
- self ._bytes = six .b ('' )
271
+ self ._bytes = six .b ("" )
267
272
self ._bytes = self ._conn .sock .recv (1 )
268
273
return False
269
274
except http_client .socket .error as e :
@@ -309,9 +314,9 @@ def _isconnected(self):
309
314
raise e
310
315
311
316
def _reconnect (self ):
312
- ''' Connect if disconnected.
317
+ """ Connect if disconnected.
313
318
Retry self.maxtries times with delays
314
- '''
319
+ """
315
320
if not self ._isconnected ():
316
321
try :
317
322
self ._connect ()
@@ -335,8 +340,8 @@ def _reconnect(self):
335
340
self ._closed = False
336
341
337
342
def _reset_retries (self ):
338
- ''' Reset the connect counters and delays
339
- '''
343
+ """ Reset the connect counters and delays
344
+ """
340
345
self ._tries = 0
341
346
self ._delay = 1
342
347
0 commit comments