-
Notifications
You must be signed in to change notification settings - Fork 0
/
http_client.py
122 lines (92 loc) · 2.97 KB
/
http_client.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import usocket
import ujson
try:
import ussl
SUPPORT_SSL = True
except ImportError:
ussl = None
SUPPORT_SSL = False
SUPPORT_TIMEOUT = hasattr(usocket.socket, 'settimeout')
CONTENT_TYPE_JSON = 'application/json'
class Response(object):
def __init__(self, status_code, raw):
self.status_code = status_code
self.raw = raw
self._content = False
self.encoding = 'utf-8'
@property
def content(self):
if self._content is False:
self._content = self.raw.read()
self.raw.close()
self.raw = None
return self._content
@property
def text(self):
content = self.content
return str(content, self.encoding) if content else ''
def close(self):
if self.raw is not None:
self._content = None
self.raw.close()
self.raw = None
def json(self):
return ujson.loads(self.text)
def raise_for_status(self):
if 400 <= self.status_code < 500:
raise OSError('Client error: %s' % self.status_code)
if 500 <= self.status_code < 600:
raise OSError('Server error: %s' % self.status_code)
# Adapted from upip
def request(method, url, json=None, timeout=None, headers=None):
urlparts = url.split('/', 3)
proto = urlparts[0]
host = urlparts[2]
urlpath = '' if len(urlparts) < 4 else urlparts[3]
if proto == 'http:':
port = 80
elif proto == 'https:':
port = 443
else:
raise OSError('Unsupported protocol: %s' % proto[:-1])
if ':' in host:
host, port = host.split(':')
port = int(port)
if json is not None:
# content = ujson.dumps(json)
content = json
content_type = "application/x-www-form-urlencoded"#CONTENT_TYPE_JSON
#content_type = CONTENT_TYPE_JSON
else:
content = None
ai = usocket.getaddrinfo(host, port)
addr = ai[0][4]
sock = usocket.socket()
if timeout is not None:
assert SUPPORT_TIMEOUT, 'Socket does not support timeout'
sock.settimeout(timeout)
sock.connect(addr)
if proto == 'https:':
assert SUPPORT_SSL, 'HTTPS not supported: could not find ussl'
sock = ussl.wrap_socket(sock)
sock.write('%s /%s HTTP/1.0\r\nHost: %s\r\n' % (method, urlpath, host))
if headers is not None:
for header in headers.items():
sock.write('%s: %s\r\n' % header)
if content is not None:
sock.write('content-length: %s\r\n' % len(content))
sock.write('content-type: %s\r\n' % content_type)
sock.write('\r\n')
sock.write(content)
else:
sock.write('\r\n')
l = sock.readline()
protover, status, msg = l.split(None, 2)
# Skip headers
while sock.readline() != b'\r\n':
pass
return Response(int(status), sock)
def get(url, **kwargs):
return request('GET', url, **kwargs)
def post(url, **kwargs):
return request('POST', url, **kwargs)