diff --git a/binascii/binascii.py b/binascii/binascii.py index dd6744c2f..969822854 100644 --- a/binascii/binascii.py +++ b/binascii/binascii.py @@ -83,7 +83,7 @@ def a2b_base64(ascii): table_b2a_base64 = ( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/") -def b2a_base64(bin): +def b2a_base64(bin, newline=True): "Base64-code line of data." newlength = (len(bin) + 2) // 3 @@ -109,5 +109,6 @@ def b2a_base64(bin): elif leftbits == 4: res.append(table_b2a_base64[(leftchar & 0xf) << 2]) res.append(PAD) - res.append('\n') + if newline: + res.append('\n') return ''.join(res).encode('ascii') diff --git a/urequests/urequests.py b/urequests/urequests.py index acb220e85..68ca76968 100644 --- a/urequests/urequests.py +++ b/urequests/urequests.py @@ -32,7 +32,13 @@ def json(self): return ujson.loads(self.content) +def is_chunked_data(data): + return getattr(data, "__iter__", None) and not getattr(data, "__len__", None) + def request(method, url, data=None, json=None, headers={}, stream=None): + chunked = data and is_chunked_data(data) + redirect = None #redirection url, None means no redirection + try: proto, dummy, host, path = url.split("/", 3) except ValueError: @@ -73,10 +79,20 @@ def request(method, url, data=None, json=None, headers={}, stream=None): data = ujson.dumps(json) s.write(b"Content-Type: application/json\r\n") if data: - s.write(b"Content-Length: %d\r\n" % len(data)) + if chunked: + s.write(b"Transfer-Encoding: chunked\r\n") + else: + s.write(b"Content-Length: %d\r\n" % len(data)) s.write(b"\r\n") if data: - s.write(data) + if chunked: + for chunk in data: + s.write(b"%x\r\n" % len(chunk)) + s.write(chunk) + s.write(b"\r\n") + s.write("0\r\n\r\n") + else: + s.write(data) l = s.readline() #print(l) @@ -94,15 +110,25 @@ def request(method, url, data=None, json=None, headers={}, stream=None): if b"chunked" in l: raise ValueError("Unsupported " + l) elif l.startswith(b"Location:") and not 200 <= status <= 299: - raise NotImplementedError("Redirects not yet supported") + if status in [301, 302, 303, 307, 308]: + redirect = l[10:-2].decode() + else: + raise NotImplementedError("Redirect %d not yet supported" % status) except OSError: s.close() raise - resp = Response(s) - resp.status_code = status - resp.reason = reason - return resp + if redirect: + s.close() + if status in [301, 302, 303]: + return request("GET", redirect, None, None, headers, stream) + else: + return request(method, redirect, data, json, headers, stream) + else: + resp = Response(s) + resp.status_code = status + resp.reason = reason + return resp def head(url, **kw): @@ -121,4 +147,4 @@ def patch(url, **kw): return request("PATCH", url, **kw) def delete(url, **kw): - return request("DELETE", url, **kw) + return request("DELETE", url, **kw) \ No newline at end of file