sipeed / MaixPy-v1

MicroPython for K210 RISC-V, let's play with edge AI easier
https://wiki.sipeed.com/maixpy
Other
1.68k stars 438 forks source link

[Errno 22] EINVAL if Host is given instead of IP in HTTPS request #283

Closed valenzmanu closed 3 years ago

valenzmanu commented 4 years ago

I'm trying to make a HTTPS request, so I'm using the firmware in https://github.com/sipeed/MaixPy/tree/develop since the ussl module is needed.

When I try to connect using the hostname I get [Errno 22] EINVAL in socket.getaddrinfo(HOST, PORT)[0][-1] . I tried changing hostname to the public IP (using a service like this: https://www.cdmon.com/es/conversor-host-ip) and I no longer got this error, however I think this is a problem since the public IP might change at any given time.

Here is a snippet of my code (I'm using a maixduino, and it was already connected to a wifi network):

import ussl
import socket

# define host and port
HOST = 'host name'
# HOST = 'host ip'
PORT = 443
PROTO = "HTTPS"
RETRY = 3

# make connection
sock = socket.socket()
for i in range(RETRY):
    try:
        addr = socket.getaddrinfo(HOST, PORT)[0][-1]
        print('addr:', addr)
        break
    except Exception as exc:
        print('addr error: ', exc)
try:
    sock.connect(addr)
    print('Connected')
except Exception as exc:
    print('connect error', exc)

# use ssl encryption if https
if(PROTO == "HTTPS"):
    ussl.wrap_socket(sock)
    print('ussl: socket encrypted')

# try to send a GET request
write_res = sock.write('''GET / HTTP/1.1
Host: host_name
Cache-Control: no-cache

''')

# get response
while True:
    read_res = sock.readline()
    if not read_res or read_res == b'\r\n':
        break

print('bytes written:', write_res)
print('response:', sock.read())
valenzmanu commented 4 years ago

@junhuanchen

junhuanchen commented 4 years ago

Ah, sorry, this socket.getAddrInfo is implemented on the AT network card, which means it needs to support HTTPS on the network card, not the built-in function of K210.

Maybe you may configure or burn the firmware for ES8285/ESP32 that supports HTTPS parsing.

Such as

        try:
            err = 0
            while 1:
                try:
                    self._socketAddr = socket.getaddrinfo(host, port)[0][-1]
                    break
                except Exception:
                    err += 1
                if err > 5:
                    raise Exception("get ip failed!")
            #cli = socket.socket()
            cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            cli.settimeout(self.ConnTimeoutSec)
            cli.connect(self._socketAddr)
        except:
            raise Exception('Error to connect to %s:%s' % (host, port))
valenzmanu commented 4 years ago

Thanks,

I'm not sure what firmware to burn into the ESP32 or how to do it. Should I use the USB-C port? I see the ESP32 is connected to the CH552 which is connected to the USB port. If so, what software do you recommend? I've been using Kflash ever since I started using the Maixduino, will it work to burn ESP32 firmware?

Regarding your code, I don't quite understand where should it be at? What Class self._socketAddr refers to?

junhuanchen commented 4 years ago

I'm not sure what you're using right now, but you can try burning AT firmware for ESP8266 and try AT parsing HTTPS to get IP. It's much easier for you

junhuanchen commented 4 years ago

image

Not all HTTPS gets IP

junhuanchen commented 3 years ago

This is a bug that relies on an external network.