Skip to content
This repository has been archived by the owner on Feb 4, 2023. It is now read-only.

Http GET polling causes crash when host disconnected #22

Closed
andrewk123 opened this issue Oct 31, 2021 · 8 comments
Closed

Http GET polling causes crash when host disconnected #22

andrewk123 opened this issue Oct 31, 2021 · 8 comments
Labels
bug Something isn't working

Comments

@andrewk123
Copy link

andrewk123 commented Oct 31, 2021

A follow up to a previous issue since I am seeing the same issue.

Bug report is as follows:

Describe the bug

Multiple requests to an internal NodeJS server when the server is disconnected causes a crash.

Steps to Reproduce

Use the example "AsyncHTTPRequest_ESP.ino"

Only changes in this sketch are as follows:
Line 49 #define ASYNC_HTTP_LOGLEVEL 4
Line 52 #define HTTP_REQUEST_INTERVAL 10
Line 59 and 60 add SSID and Password
Line 102 change to requestOpenResult = request.open("GET", "http://192.168.59.188/ping.htm");

Expected behavior

When the target is disconnected an HTTP error code should be returned after a very short timeout (ideally controlled by setTimeout() or the like).

Actual behavior

When http://192.168.59.188/ping.htm is available everything works as expected (the ping page just generates an OK) which is printed by the Sketch. However if you connect the ethernet cable, requests receive no response (as expected). However, after several requests (typically 3) the ESP restarts,

Please ensure to specify the following:

  • Arduino IDE version (e.g. 1.8.13) or Platform.io version
    Arduino IDE 1.8.13
  • ESP8266,ESP32 or STM32 Core Version (e.g. ESP8266 core v2.7.4, ESP32 v1.0.5 or STM32 v1.9.0)
    ESP8266 Core 3.0.2

Here is the debug output:

AsyncHTTPRequest @ IP : 192.168.1.23
[AHTTP] open( GET , url = http://192.168.1.21/ping.htm
[AHTTP] _parseURL(): scheme+host HTTP:// 192.168.1.21
[AHTTP] _parseURL(): port+path+query 80 /ping.htm
[AHTTP] open: conneting to hostname = 192.168.1.21:80
[AHTTP] _connect()
[AHTTP] send()
[AHTTP] _buildRequest()
[AHTTP] _HTTPmethod = 0
[AHTTP] GET /ping.htm HTTP/1.1

[AHTTP] host : 192.168.1.21:80

[AHTTP] _send(), _request->available = 50
[AHTTP] *can't send
[AHTTP] open( GET , url = http://192.168.1.21/ping.htm
[AHTTP] _parseURL(): scheme+host HTTP:// 192.168.1.21
[AHTTP] _parseURL(): port+path+query 80 /ping.htm
[AHTTP] open: conneting to hostname = 192.168.1.21:80
[AHTTP] _connect()
[AHTTP] send()
[AHTTP] _buildRequest()
[AHTTP] _HTTPmethod = 0
[AHTTP] GET /ping.htm HTTP/1.1

[AHTTP] host : 192.168.1.21:80

[AHTTP] _send(), _request->available = 50
[AHTTP] *can't send
H[AHTTP] open( GET , url = http://192.168.1.21/ping.htm
[AHTTP] _parseURL(): scheme+host HTTP:// 192.168.1.21
[AHTTP] _parseURL(): port+path+query 80 /ping.htm
[AHTTP] open: conneting to hostname = 192.168.1.21:80
[AHTTP] _connect()
[AHTTP] send()
[AHTTP] _buildRequest()
[AHTTP] _HTTPmethod = 0
[AHTTP] GET /ping.htm HTTP/1.1

[AHTTP] host : 192.168.1.21:80

[AHTTP] _send(), _request->available = 50
[AHTTP] *can't send
H[AHTTP] open( GET , url = http://192.168.1.21/ping.htm
[AHTTP] _parseURL(): scheme+host HTTP:// 192.168.1.21
[AHTTP] _parseURL(): port+path+query 80 /ping.htm
[AHTTP] open: conneting to hostname = 192.168.1.21:80
[AHTTP] _connect()
[AHTTP] send()
[AHTTP] _buildRequest()
[AHTTP] _HTTPmethod = 0
[AHTTP] GET /ping.htm HTTP/1.1

[AHTTP] host : 192.168.1.21:80

[AHTTP] _send(), _request->available = 50
[AHTTP] *can't send
H[AHTTP] _onError handler error = -13
[AHTTP]
_onDisconnect handler
[AHTTP] _setReadyState : 4


[AHTTP] responseText()
[AHTTP] responseText() no data


--------------- CUT HERE FOR EXCEPTION DECODER ---------------

Note: It takes approximately 30 seconds from the first [AHTTP] *can't send till the _onDisconnect handler fires. The reset happens at the time the next request would happen after the _onDisconnect handler fires.

Thanks for your help

Originally posted by @andrewk123 in #16 (comment)

@khoih-prog
Copy link
Owner

Hi @andrewk123

Can you post your internal NodeJS server code

@khoih-prog khoih-prog added the question Further information is requested label Nov 23, 2021
@khoih-prog
Copy link
Owner

khoih-prog commented Nov 23, 2021

Hi @andrewk123

I couldn't duplicate the issue as the code was running normally. I suggest you check your board / WebServer code

The debug terminal

Starting AsyncHTTPRequest_ESP using ESP8266_NODEMCU_ESP12E
AsyncHTTPRequest_Generic v1.3.1
Connecting to WiFi SSID: HueNet1
...........AsyncHTTPRequest @ IP : 192.168.2.96

**************************************
[AHTTP] responseText()
[AHTTP] xbuf::readString: Reserved size =  612
[AHTTP] responseText(char) <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <form action="/" method="POST">
        <label>Name: </label>
        <input type="text" name="dname" value="" /><br />
        <label>Email: </label>
        <input type="text" name="demail" value="" /><br />
        <label>Address: </label>
        <input type="text" name="daddress" value="" /><br />
        <button>submit</button>
    </form>
</body>
</html>
 , avail = 611
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <form action="/" method="POST">
        <label>Name: </label>
        <input type="text" name="dname" value="" /><br />
        <label>Email: </label>
        <input type="text" name="demail" value="" /><br />
        <label>Address: </label>
        <input type="text" name="daddress" value="" /><br />
        <button>submit</button>
    </form>
</body>
</html>

************************************** <========== Stop server
[AHTTP] _onData handler 0

 , len = 5
[AHTTP] _onData: _processChunks
[AHTTP] _processChunks() 0

 , chunks available = 5
[AHTTP] xbuf::readString: Reserved size =  4
[AHTTP] *getChunkHeader 0
 , chunkHeader length = 3
[AHTTP] *all chunks received - no disconnect
[AHTTP] 
_onDisconnect handler
[AHTTP] open( GET , url = http://192.168.2.30:3000/index
[AHTTP] _parseURL(): scheme+host HTTP:// 192.168.2.30
[AHTTP] _parseURL(): port+path+query 3000 /index 
[AHTTP] open: conneting to hostname = 192.168.2.30:3000
[AHTTP] _connect()
[AHTTP] send()
[AHTTP] _buildRequest()
[AHTTP] _HTTPmethod = 0
[AHTTP] GET  /index   HTTP/1.1

[AHTTP] host : 192.168.2.30:3000 

[AHTTP] _send(), _request->available = 47
[AHTTP] !connected
H[AHTTP] _onError handler error = -14
[AHTTP] 
_onDisconnect handler
[AHTTP] _setReadyState : 4

**************************************
[AHTTP] responseText()
[AHTTP] responseText() no data

**************************************
[AHTTP] open( GET , url = http://192.168.2.30:3000/index
[AHTTP] _parseURL(): scheme+host HTTP:// 192.168.2.30
[AHTTP] _parseURL(): port+path+query 3000 /index 
[AHTTP] open: conneting to hostname = 192.168.2.30:3000
[AHTTP] _connect()
[AHTTP] send()
[AHTTP] _buildRequest()
[AHTTP] _HTTPmethod = 0
[AHTTP] GET  /index   HTTP/1.1

[AHTTP] host : 192.168.2.30:3000 

[AHTTP] _send(), _request->available = 47
[AHTTP] !connected
H[AHTTP] _onError handler error = -14
[AHTTP] 
_onDisconnect handler
[AHTTP] _setReadyState : 4

**************************************
[AHTTP] responseText()
[AHTTP] responseText() no data

**************************************
[AHTTP] open( GET , url = http://192.168.2.30:3000/index
[AHTTP] _parseURL(): scheme+host HTTP:// 192.168.2.30
[AHTTP] _parseURL(): port+path+query 3000 /index 
[AHTTP] open: conneting to hostname = 192.168.2.30:3000
[AHTTP] _connect()
[AHTTP] send()
[AHTTP] _buildRequest()
[AHTTP] _HTTPmethod = 0
[AHTTP] GET  /index   HTTP/1.1

[AHTTP] host : 192.168.2.30:3000 

[AHTTP] _send(), _request->available = 47
[AHTTP] !connected
H[AHTTP] _onError handler error = -14
[AHTTP] 
_onDisconnect handler
[AHTTP] _setReadyState : 4

**************************************
[AHTTP] responseText()
[AHTTP] responseText() no data

**************************************
[AHTTP] open( GET , url = http://192.168.2.30:3000/index
[AHTTP] _parseURL(): scheme+host HTTP:// 192.168.2.30
[AHTTP] _parseURL(): port+path+query 3000 /index 
[AHTTP] open: conneting to hostname = 192.168.2.30:3000
[AHTTP] _connect()
[AHTTP] send()
[AHTTP] _buildRequest()
[AHTTP] _HTTPmethod = 0
[AHTTP] GET  /index   HTTP/1.1

[AHTTP] host : 192.168.2.30:3000 

[AHTTP] _send(), _request->available = 47
[AHTTP] !connected
H[AHTTP] _onError handler error = -14
[AHTTP] 
_onDisconnect handler
[AHTTP] _setReadyState : 4

**************************************
[AHTTP] responseText()
[AHTTP] responseText() no data

**************************************
[AHTTP] open( GET , url = http://192.168.2.30:3000/index
[AHTTP] _parseURL(): scheme+host HTTP:// 192.168.2.30
[AHTTP] _parseURL(): port+path+query 3000 /index 
[AHTTP] open: conneting to hostname = 192.168.2.30:3000
[AHTTP] _connect()
[AHTTP] send()
[AHTTP] _buildRequest()
[AHTTP] _HTTPmethod = 0
[AHTTP] GET  /index   HTTP/1.1

[AHTTP] host : 192.168.2.30:3000 

[AHTTP] _send(), _request->available = 47
[AHTTP] !connected
H[AHTTP] _onError handler error = -14
[AHTTP] 
_onDisconnect handler
[AHTTP] _setReadyState : 4

**************************************
[AHTTP] responseText()
[AHTTP] responseText() no data

**************************************
[AHTTP] open( GET , url = http://192.168.2.30:3000/index
[AHTTP] _parseURL(): scheme+host HTTP:// 192.168.2.30
[AHTTP] _parseURL(): port+path+query 3000 /index 
[AHTTP] open: conneting to hostname = 192.168.2.30:3000
[AHTTP] _connect()
[AHTTP] send()
[AHTTP] _buildRequest()
[AHTTP] _HTTPmethod = 0
[AHTTP] GET  /index   HTTP/1.1

[AHTTP] host : 192.168.2.30:3000 

[AHTTP] _send(), _request->available = 47
[AHTTP] !connected
H [AHTTP] _onError handler error = -14
[AHTTP] 
_onDisconnect handler
[AHTTP] _setReadyState : 4

**************************************
[AHTTP] responseText()
[AHTTP] responseText() no data

**************************************
[AHTTP] open( GET , url = http://192.168.2.30:3000/index
[AHTTP] _parseURL(): scheme+host HTTP:// 192.168.2.30
[AHTTP] _parseURL(): port+path+query 3000 /index 
[AHTTP] open: conneting to hostname = 192.168.2.30:3000
[AHTTP] _connect()
[AHTTP] send()
[AHTTP] _buildRequest()
[AHTTP] _HTTPmethod = 0
[AHTTP] GET  /index   HTTP/1.1

[AHTTP] host : 192.168.2.30:3000 

[AHTTP] _send(), _request->available = 47
[AHTTP] !connected
H[AHTTP] _onError handler error = -14
[AHTTP] 
_onDisconnect handler
[AHTTP] _setReadyState : 4

**************************************
[AHTTP] responseText()
[AHTTP] responseText() no data

**************************************
[AHTTP] open( GET , url = http://192.168.2.30:3000/index
[AHTTP] _parseURL(): scheme+host HTTP:// 192.168.2.30
[AHTTP] _parseURL(): port+path+query 3000 /index 
[AHTTP] open: conneting to hostname = 192.168.2.30:3000
[AHTTP] _connect()
[AHTTP] send()
[AHTTP] _buildRequest()
[AHTTP] _HTTPmethod = 0
[AHTTP] GET  /index   HTTP/1.1

[AHTTP] host : 192.168.2.30:3000 

[AHTTP] _send(), _request->available = 47
[AHTTP] !connected
H[AHTTP] _onError handler error = -14
[AHTTP] 
_onDisconnect handler
[AHTTP] _setReadyState : 4

**************************************
[AHTTP] responseText()
[AHTTP] responseText() no data

**************************************
[AHTTP] open( GET , url = http://192.168.2.30:3000/index
[AHTTP] _parseURL(): scheme+host HTTP:// 192.168.2.30
[AHTTP] _parseURL(): port+path+query 3000 /index 
[AHTTP] open: conneting to hostname = 192.168.2.30:3000
[AHTTP] _connect()
[AHTTP] send()
[AHTTP] _buildRequest()
[AHTTP] _HTTPmethod = 0
[AHTTP] GET  /index   HTTP/1.1

[AHTTP] host : 192.168.2.30:3000 

[AHTTP] _send(), _request->available = 47
[AHTTP] !connected
H[AHTTP] _onError handler error = -14
[AHTTP] 
_onDisconnect handler
[AHTTP] _setReadyState : 4

**************************************
[AHTTP] responseText()
[AHTTP] responseText() no data

**************************************
[AHTTP] open( GET , url = http://192.168.2.30:3000/index
[AHTTP] _parseURL(): scheme+host HTTP:// 192.168.2.30
[AHTTP] _parseURL(): port+path+query 3000 /index 
[AHTTP] open: conneting to hostname = 192.168.2.30:3000
[AHTTP] _connect()
[AHTTP] send()
[AHTTP] _buildRequest()
[AHTTP] _HTTPmethod = 0
[AHTTP] GET  /index   HTTP/1.1

[AHTTP] host : 192.168.2.30:3000 

[AHTTP] _send(), _request->available = 47
[AHTTP] !connected
H[AHTTP] _onError handler error = -14
[AHTTP] 
_onDisconnect handler
[AHTTP] _setReadyState : 4

**************************************
[AHTTP] responseText()
[AHTTP] responseText() no data

**************************************
[AHTTP] open( GET , url = http://192.168.2.30:3000/index
[AHTTP] _parseURL(): scheme+host HTTP:// 192.168.2.30
[AHTTP] _parseURL(): port+path+query 3000 /index 
[AHTTP] open: conneting to hostname = 192.168.2.30:3000
[AHTTP] _connect()
[AHTTP] send()
[AHTTP] _buildRequest()
[AHTTP] _HTTPmethod = 0
[AHTTP] GET  /index   HTTP/1.1

[AHTTP] host : 192.168.2.30:3000 

[AHTTP] _send(), _request->available = 47
[AHTTP] !connected
H[AHTTP] _onError handler error = -14
[AHTTP] 
_onDisconnect handler
[AHTTP] _setReadyState : 4

**************************************
[AHTTP] responseText()
[AHTTP] responseText() no data

**************************************
...


************************************** <========== Running server again
[AHTTP] open( GET , url = http://192.168.2.30:3000/index
[AHTTP] _parseURL(): scheme+host HTTP:// 192.168.2.30
[AHTTP] _parseURL(): port+path+query 3000 /index 
[AHTTP] open: conneting to hostname = 192.168.2.30:3000
[AHTTP] _connect()
[AHTTP] send()
[AHTTP] _buildRequest()
[AHTTP] _HTTPmethod = 0
[AHTTP] GET  /index   HTTP/1.1

[AHTTP] host : 192.168.2.30:3000 

[AHTTP] _send(), _request->available = 47
[AHTTP] !connected
H[AHTTP] _onConnect handler
[AHTTP] _setReadyState : 1
[AHTTP] _send(), _request->available = 47
[AHTTP] *send 47
[AHTTP] _onData handler HTTP/1.1 200 OK
Content-Type: text/html
Date: Tue, 23 Nov 2021 01:45:55 GMT
Connection: keep-alive
Transfer-Encoding: chunked

263
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <form action="/" method="POST">
        <label>Name: </label>
        <input type="text" name="dname" value="" /><br />
        <label>Email: </label>
yer:1
h⸮⸮�⸮ , len = 536
[AHTTP] _collectHeaders()
[AHTTP] xbuf::readString: Reserved size =  18
[AHTTP] xbuf::readString: Reserved size =  26
[AHTTP] xbuf::readString: Reserved size =  38
[AHTTP] xbuf::readString: Reserved size =  25
[AHTTP] xbuf::readString: Reserved size =  29
[AHTTP] xbuf::readString: Reserved size =  3
[AHTTP] _setReadyState : 2
[AHTTP] *transfer-encoding: chunked
[AHTTP] _processChunks() 263
<!DOCTYPE h , chunks available = 403
[AHTTP] xbuf::readString: Reserved size =  6
[AHTTP] *getChunkHeader 263
 , chunkHeader length = 5
[AHTTP] _processChunks() <!DOCTYPE html>
 , chunks available = 398
[AHTTP] _setReadyState : 3
[AHTTP] _onData handler         <input type="text" name="demail" value="" /><br />
        <label>Address: </label>
        <input type="text" name="daddress" value="" /><br />
        <button>submit</button>
    </form>
</body>
</html>

���< , len = 215
[AHTTP] _onData: _processChunks
[AHTTP] _processChunks()         <input t , chunks available = 215
[AHTTP] xbuf::readString: Reserved size =  3
[AHTTP] *getChunkHeader 
 , chunkHeader length = 2
[AHTTP] *all chunks received - no disconnect
[AHTTP] _setReadyState : 4

**************************************

No reset happened at all.

I close the issue now until you can prove this is the bug of the library


BTW, the WebServer Nodejs code to test with

requestOpenResult = request.open("GET", "http://192.168.2.30:3000/index");
  1. Node.js
var http = require('http');
var fs = require('fs');

var server = http.createServer(function (req, res) {

    if (req.method === "GET") {
        res.writeHead(200, { "Content-Type": "text/html" });
        fs.createReadStream("./index.html", "UTF-8").pipe(res);
    } else if (req.method === "POST") {
    
        var body = "";
        req.on("data", function (chunk) {
            body += chunk;
        });

        req.on("end", function(){
            res.writeHead(200, { "Content-Type": "text/html" });
            res.end(body);
        });
    }

}).listen(3000);
  1. index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <form action="/" method="POST">
        <label>Name: </label>
        <input type="text" name="dname" value="" /><br />
        <label>Email: </label>
        <input type="text" name="demail" value="" /><br />
        <label>Address: </label>
        <input type="text" name="daddress" value="" /><br />
        <button>submit</button>
    </form>
</body>
</html>

@khoih-prog khoih-prog added invalid This doesn't seem right and removed question Further information is requested labels Nov 23, 2021
@andrewk123
Copy link
Author

andrewk123 commented Nov 23, 2021 via email

@andrewk123
Copy link
Author

Let me qualify my previous comment. This error is caused when the target host is not available (ie there is no response from the host at all (such as the target host is completely down). It is the lack of response that causes the issue (as described above). Try this again with

requestOpenResult = request.open("GET", "http://192.168.99.30:3000/index");

where 192.168.99.30 is a none existing IP address.

Please re-open this issue.

@khoih-prog
Copy link
Owner

Multiple requests to an internal NodeJS server when the server is disconnected causes a crash

none existing IP address.

These 2 are different scenarios, but anyway, I can duplicate the crash only with none existing IP address now and will investigate soon.

Certainly, please post anything you've investigated / experienced so far to help speed up the tests / fix. I'm opening the issue now.

@khoih-prog khoih-prog reopened this Nov 23, 2021
@khoih-prog
Copy link
Owner

OK, found the bug. I'll publish a new release by tomorrow.

khoih-prog added a commit that referenced this issue Nov 23, 2021
### Releases v1.4.0

1. Fix crashing bug when request a non-existing IP. Check [Http GET polling causes crash when host disconnected #22](#22)
2. Modify `platform.ini` to avoid compile error with PIO when using ESP8266/ESP32
khoih-prog added a commit that referenced this issue Nov 23, 2021
### Releases v1.4.0

1. Fix crashing bug when request a non-existing IP. Check [Http GET polling causes crash when host disconnected #22](#22)
2. Modify `platform.ini` to avoid compile error with PIO when using ESP8266/ESP32
@khoih-prog
Copy link
Owner

Hi @andrewk123

The AsyncHTTPRequest_Generic releases v1.4.0 has just been published.

Your contribution is noted in Contributions and Thanks.

Please have more tests to verify the bug has been squashed.

Regards,


Releases v1.4.0

  1. Fix crashing bug when request a non-existing IP. Check Http GET polling causes crash when host disconnected #22
  2. Modify platform.ini to avoid compile error with PIO when using ESP8266/ESP32

@andrewk123
Copy link
Author

Thanks! That seems to have completely resolved the issue. I will do some further testing this evening and advise if I find anything of interest. Thanks for your work on this!

@khoih-prog khoih-prog added bug Something isn't working and removed invalid This doesn't seem right labels Nov 23, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants