diff --git a/python-ecosys/urequests/metadata.txt b/python-ecosys/urequests/metadata.txt index 8cd156c39..04861d96f 100644 --- a/python-ecosys/urequests/metadata.txt +++ b/python-ecosys/urequests/metadata.txt @@ -1,4 +1,3 @@ srctype = micropython-lib type = module -version = 0.6 -author = Paul Sokolovsky +version = 0.7.0 diff --git a/python-ecosys/urequests/setup.py b/python-ecosys/urequests/setup.py index 65ee5da8b..51f1158e0 100644 --- a/python-ecosys/urequests/setup.py +++ b/python-ecosys/urequests/setup.py @@ -10,11 +10,11 @@ setup( name="micropython-urequests", - version="0.6", + version="0.7", description="urequests module for MicroPython", long_description="This is a module reimplemented specifically for MicroPython standard library,\nwith efficient and lean design in mind. Note that this module is likely work\nin progress and likely supports just a subset of CPython's corresponding\nmodule. Please help with the development if you are interested in this\nmodule.", url="https://github.com/micropython/micropython-lib", - author="Paul Sokolovsky", + author="micropython-lib Developers", author_email="micro-python@googlegroups.com", maintainer="micropython-lib Developers", maintainer_email="micro-python@googlegroups.com", diff --git a/python-ecosys/urequests/urequests.py b/python-ecosys/urequests/urequests.py index 75a145702..e1998711d 100644 --- a/python-ecosys/urequests/urequests.py +++ b/python-ecosys/urequests/urequests.py @@ -33,7 +33,28 @@ def json(self): return ujson.loads(self.content) -def request(method, url, data=None, json=None, headers={}, stream=None): +def request( + method, + url, + data=None, + json=None, + headers={}, + stream=None, + auth=None, + timeout=None, + parse_headers=True, +): + redirect = None # redirection url, None means no redirection + chunked_data = data and getattr(data, "__iter__", None) and not getattr(data, "__len__", None) + + if auth is not None: + import ubinascii + + username, password = auth + formated = b"{}:{}".format(username, password) + formated = str(ubinascii.b2a_base64(formated)[:-1], "ascii") + headers["Authorization"] = "Basic {}".format(formated) + try: proto, dummy, host, path = url.split("/", 3) except ValueError: @@ -55,7 +76,17 @@ def request(method, url, data=None, json=None, headers={}, stream=None): ai = usocket.getaddrinfo(host, port, 0, usocket.SOCK_STREAM) ai = ai[0] - s = usocket.socket(ai[0], ai[1], ai[2]) + resp_d = None + if parse_headers is not False: + resp_d = {} + + s = usocket.socket(ai[0], usocket.SOCK_STREAM, ai[2]) + + if timeout is not None: + # Note: settimeout is not supported on all platforms, will raise + # an AttributeError if not available. + s.settimeout(timeout) + try: s.connect(ai[-1]) if proto == "https:": @@ -76,14 +107,27 @@ 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)) - s.write(b"\r\n") + if chunked_data: + s.write(b"Transfer-Encoding: chunked\r\n") + else: + s.write(b"Content-Length: %d\r\n" % len(data)) + s.write(b"Connection: close\r\n\r\n") if data: - s.write(data) + if chunked_data: + 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) l = l.split(None, 2) + if len(l) < 2: + # Invalid response + raise ValueError("HTTP error: BadStatusLine:\n%s" % l) status = int(l[1]) reason = "" if len(l) > 2: @@ -95,17 +139,37 @@ def request(method, url, data=None, json=None, headers={}, stream=None): # print(l) if l.startswith(b"Transfer-Encoding:"): if b"chunked" in l: - raise ValueError("Unsupported " + l) + raise ValueError("Unsupported " + str(l, "utf-8")) 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 = str(l[10:-2], "utf-8") + else: + raise NotImplementedError("Redirect %d not yet supported" % status) + if parse_headers is False: + pass + elif parse_headers is True: + l = str(l, "utf-8") + k, v = l.split(":", 1) + resp_d[k] = v.strip() + else: + parse_headers(l, resp_d) 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 + if resp_d is not None: + resp.headers = resp_d + return resp def head(url, **kw): diff --git a/python-stdlib/binascii/binascii.py b/python-stdlib/binascii/binascii.py index 430b1132b..f2ec39e84 100644 --- a/python-stdlib/binascii/binascii.py +++ b/python-stdlib/binascii/binascii.py @@ -331,7 +331,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 @@ -357,5 +357,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")
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: