esp_http.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. import usocket
  2. class Response:
  3. def __init__(self, f):
  4. self.raw = f
  5. self.encoding = "utf-8"
  6. self._cached = None
  7. def close(self):
  8. if self.raw:
  9. self.raw.close()
  10. self.raw = None
  11. self._cached = None
  12. @property
  13. def content(self):
  14. if self._cached is None:
  15. self._cached = self.raw.read()
  16. self.raw.close()
  17. self.raw = None
  18. return self._cached
  19. @property
  20. def text(self):
  21. return str(self.content, self.encoding)
  22. def json(self):
  23. import ujson
  24. return ujson.loads(self.content)
  25. def request(method, url, data=None, json=None, headers={}, stream=None,params=None):
  26. try:
  27. proto, dummy, host, path = url.split("/", 3)
  28. except ValueError:
  29. proto, dummy, host = url.split("/", 2)
  30. path = ""
  31. if proto == "http:":
  32. port = 80
  33. elif proto == "https:":
  34. import ussl
  35. port = 443
  36. else:
  37. raise ValueError("Unsupported protocol: " + proto)
  38. if ":" in host:
  39. host, port = host.split(":", 1)
  40. port = int(port)
  41. if params:
  42. path = path + "?"
  43. for k in params:
  44. path = path + '&'+k+'='+params[k]
  45. ai = usocket.getaddrinfo(host, port)
  46. addr = ai[0][4]
  47. s = usocket.socket()
  48. s.connect(addr)
  49. if proto == "https:":
  50. s = ussl.wrap_socket(s)
  51. s.write(b"%s /%s HTTP/1.0\r\n" % (method, path))
  52. if not "Host" in headers:
  53. s.write(b"Host: %s\r\n" % host)
  54. # Iterate over keys to avoid tuple alloc
  55. for k in headers:
  56. s.write(k)
  57. s.write(b": ")
  58. s.write(headers[k])
  59. s.write(b"\r\n")
  60. if json is not None:
  61. assert data is None
  62. import ujson
  63. data = ujson.dumps(json)
  64. if data:
  65. s.write(b"Content-Length: %d\r\n" % len(data))
  66. s.write(b"\r\n")
  67. if data:
  68. s.write(data)
  69. l = s.readline()
  70. protover, status, msg = l.split(None, 2)
  71. status = int(status)
  72. #print(protover, status, msg)
  73. while True:
  74. l = s.readline()
  75. if not l or l == b"\r\n":
  76. break
  77. #print(l)
  78. if l.startswith(b"Transfer-Encoding:"):
  79. if b"chunked" in l:
  80. raise ValueError("Unsupported " + l)
  81. elif l.startswith(b"Location:") and not 200 <= status <= 299:
  82. raise NotImplementedError("Redirects not yet supported")
  83. resp = Response(s)
  84. resp.status_code = status
  85. resp.reason = msg.rstrip()
  86. return resp
  87. def head(url, **kw):
  88. return request("HEAD", url, **kw)
  89. def get(url, **kw):
  90. return request("GET", url, **kw)
  91. def post(url, **kw):
  92. return request("POST", url, **kw)
  93. def put(url, **kw):
  94. return request("PUT", url, **kw)
  95. def patch(url, **kw):
  96. return request("PATCH", url, **kw)
  97. def delete(url, **kw):
  98. return request("DELETE", url, **kw)