Skip to content

Urequests updates #500

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 11 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions python-ecosys/urequests/metadata.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
srctype = micropython-lib
type = module
version = 0.6
author = Paul Sokolovsky
version = 0.7.0
4 changes: 2 additions & 2 deletions python-ecosys/urequests/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
86 changes: 75 additions & 11 deletions python-ecosys/urequests/urequests.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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:":
Expand All @@ -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:
Expand All @@ -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):
Expand Down
5 changes: 3 additions & 2 deletions python-stdlib/binascii/binascii.py
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ def a2b_base64(ascii):
table_b2a_base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"


def b2a_base64(bin):
def b2a_base64(bin, newline=True):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change doesn't seem to have anything to do with urequests, but otherwise it's OK to have here (it's a separate commit, which is good).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I'd thought it was related - was in the same original PR as the redirect/chunked change. Can confirm it was not actually used there, though looks like a clean change anyway.

"Base64-code line of data."

newlength = (len(bin) + 2) // 3
Expand All @@ -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")
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

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:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy