micropython / micropython-lib

Core Python libraries ported to MicroPython
Other
2.37k stars 993 forks source link

OSError: -40 #400

Open mradovan opened 3 years ago

mradovan commented 3 years ago

ESP-8266, urequests installed manually.

Code:

import urequests as u req = u.get("https://api.telegram.org/bot/ ... my_chat_id>") , i get this:

Traceback (most recent call last): File "", line 1, in File "/lib/urequests.py", line 112, in get File "/lib/urequests.py", line 60, in request OSError: -40

But for example, this works: req = u.get("https://telegram-webhook-sample.herokuapp.com/")

JasonLearmouth commented 3 years ago

I'm getting the same error when I try posting to Slack.

Traceback (most recent call last): File "main.py", line 16, in File "slackService.py", line 10, in send_toban_status File "urequests.py", line 166, in post File "urequests.py", line 104, in request OSError: -40

MicroPython v1.13 on 2020-09-11; ESP module with ESP8266

URL = 'https://hooks.slack.com/services/TTL3HSK...4pbNKt9'
msg = dict([("text","Hello, World!")])
resp = urequests.post(URL, data=msg)

I have a get request that is working fine, but it was not HTTPS. When I changed it to HTTPS (which is supported by the server), I now get an error on that request:

TLS buffer overflow, record size: 9040 (+5) Traceback (most recent call last): File "main.py", line 12, in File "rfsService.py", line 10, in get_sydney_toban_today File "urequests.py", line 162, in get File "urequests.py", line 128, in request OSError: -257

Not the same error in each case, so maybe not that helpful...

I also tried the URL that @mradovan said worked, and it worked for me as well.

gretel commented 3 years ago

have the same case using the telegram api.

also tried https://github.com/micropython/micropython/blob/master/examples/network/http_client_ssl.py getting the OSError: -40 result.

mrkprdo commented 3 years ago

I encountered same error with urequests when trying to fetch HTTPS url. As an experiment, i tried it with HTTP (http://www.example.com/) and surprisingly it is working. Checking urequests.py line 59-60, as expected it is related to ussl module

        if proto == "https:":
            s = ussl.wrap_socket(s, server_hostname=host)

I found somewhere that socket must be closed first, just dont know how to make it work with this one...

gretel commented 3 years ago

@mrkprdo i got the same idea.. and on wrap_socket() the esp8266 i am using resets. did enable the emergency buffer but don't get anything but garbled output until it resets. i'm going to read the related c code soon i hope.

jantznick commented 3 years ago

I am having this same issue, I think it may be due to using subdomains in the URL and the IP address for them not returning the proper value. During the call getaddrinfo, it appears to replace the domain with the IP for that domain, when I try to load my content using the IP instead of the domain it is failing.

gretel commented 3 years ago

even if we get it fixed does not look like it will get upstream any time soon :(

Darwinnn commented 3 years ago

Having the same problem with urequests and telegram api (on esp8266-20200911-v1.13):

>>> requests.get("https://telegram.org")                                                                                                              
Traceback (most recent call last):                                                                                                                    
  File "<stdin>", line 1, in <module>                                                                                                                 
  File "urequests.py", line 162, in get                                                                                                               
  File "urequests.py", line 104, in request                                                                                                           
OSError: -40   

although even google seems to work:

>>> requests.get("https://www.google.com")                                                                                                            
<Response object at 3fff2860>                                                                                                                         
>>>                                                                                                                                                   
mludvig commented 3 years ago

After some debugging this seems to be caused by incompatible SSL cipher suites between MicroPython 1.13 ussl and some web servers. That's why it works with some servers and fails with others - it depends on their SSL configuration.

This is the wireshark capture with MicroPython 1.13:

Screenshot_933_Selection

Looks like this has been resolved in MicroPython 1.14+ (I'm using v1.14-9-g9dedcf122):

Screenshot_936_Selection

gretel commented 3 years ago

@mludvig thank you! going to update to 1.14..

thefeiter commented 3 years ago

Still happening for https://api.telegram.org on microPython 1.14.

gretel commented 3 years ago

Still happening for https://api.telegram.org on microPython 1.14.

thanks, that's the application i have.

alessiol commented 3 years ago

Still happening for https://api.telegram.org on microPython 1.14.

same problem with microPython 1.15 on ESP8266

c-p-b commented 3 years ago

I found some more info here:

https://forum.micropython.org/viewtopic.php?t=10437&p=57759

The issue seems to be that certain certificate types are not supported in axtls. So to test it I applied the patch linked there (see it below) and compiled it into the ESP8266 firmware:

https://github.com/micropython/micropython/pull/6433/files

Here is same changes in patch file format: https://gist.github.com/cpdeethree/6c293ed7b78f8e5aeba27cfcfeb14877

And it worked. So it does seem to be problem with axtls library and switching to mbedtls fixes the issue. However, as noted in the link and the issue, the above patch is a hack. My ESP8266 hangs for about 7-8 seconds trying to call that library for every HTTP request, and I have to call gc.mem_free() in between calls. So it's not ideal and probably shouldn't be considered anything other than a way to demonstrate that axtls is the issue.

ofen commented 2 years ago

same on microPython 1.17 ESP8266

res = urequests.post('https://api.telegram.org/bot<TOKEN>/sendMessage', data={'chat_id': 12345678, 'text': 'test'})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "urequests.py", line 120, in post
  File "urequests.py", line 62, in request
OSError: -40
kaninfod commented 2 years ago

473

Erkman84 commented 1 year ago

This issue still persists on Micropython 1.19.1 (I use POST) but it also does not work with get, it is combined with 'https' (SSL) domains. File "urequests.py", line 120, in post File "urequests.py", line 62, in request OSError: -40

frainfreeze commented 4 months ago

Same issues here on Micropython 1.23.0, some https sites return -40, others do not.

juhanijaakola commented 4 months ago

I get OSError: -40 while trying to get day ahead electricity prices from https://web-api.tp.entsoe.eu/api using urequests.get()

Is there any other way to issue a https GET in Micropython ESP8266_GENERIC-20240222-v1.22.2?

Or is there any hope to get this fixed in urequests?

andrewleech commented 4 months ago

The problem is that the 8266 is just too small / slow.

The sites that don't work are using a modern https/SSL cipher. Micropython supported two libraries for SSL; mbedtls which is full featured and supports these modern ciphers, and axtls which is smaller and does not support as much.

As mentioned earlier, the 8266 is just too small/slow to support mbedtls properly so is built with axtls instead.

There's not likely to be any possible way to really fix this.