-
Notifications
You must be signed in to change notification settings - Fork 7.2k
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
http_client (GET / POST) stability problems err no x7004 ESP_ERR_HTTP_FETCH_HEADER (IDFGH-5271) #7036
Comments
I think |
Hi @ESP-YJM |
@AxelLin |
I simply call esp_http_client_open (with is_async=0)
sometimes I got below error: |
Hi @ESP-YJM It's indeed non-blocking: When client->is_async is false, esp_http_client_connect() calls esp_transport_connect().
In transport_tcp.c In the tcp_connect() always set socket to non-blocking: My follow up question is: what is the suggest action after hitting EINPROGRESS? |
BTW, I check my debug message, I have below tcp_poll_read select error just before esp_http_client_perform failure: E (11117856) TRANS_TCP: tcp_poll_read select error 104, errno = Connection reset by peer, fd = 52 What make me confused is why then errno changed from 104 to 119. I have http-keep-alive set, it looks like the sever closed the session. |
You can follow the flow like https://github.com/espressif/esp-idf/blob/release/v4.3/components/tcp_transport/transport_tcp.c#L134. Use |
The esp_http_client API does not allow the user to access socket. |
Maybe you execute |
O_NONBLOCK is clear immediately after connect() returned. I don't really understand why calling esp_http_client_perform(my_client); can get ENOTCONN. |
I think we both have confused the error values obtained by errno and SO_ERROR. |
Hi @ESP-YJM
|
@AxelLin Is it convenient to provide examples to reproduce the problem? |
@AxelLin I can reproduce the issue now. But i get the errno is different from you. When first esp_http_client_perform , it is successful, and the errno is 119. After 60s (HTTP Keep-alive, perr will send FIN to close the socket), and call esp_http_client_perform, errno is 128, no select error got. And then call esp_http_client_perform again, the errno is 128 and select error is 104 (RST by peer). |
@pdemianczuk07 @AxelLin Could you please modify code as follow to test. When we use
|
I already checked the errno when esp_http_client_perform() fails and call esp_http_client_close() in my application code. The point is errno may be not always correct as I mentioned. |
@AxelLin There is no proper way to know peer close the connection with FIN. It is a right way to close the connection. The LWIP will not inform the upper layer that peer sends FIN. We only call |
If you call esp_http_client_close() when errno == ENOTCONN. If in the end, the application code needs to call esp_http_client_close() anyway for other errors. |
@AxelLin |
@ESP-YJM |
@AxelLin I think application no need care about the errno, only judge the return value. I can add a new return value to tell application that need close the connection. |
This assumption is wrong. |
The fix only checks the closed by peer in esp_http_client_fetch_headers error path. |
@AxelLin If peer send FIN when happened on esp_http_client_send_post_data(), |
You mean even the tcp session is already closed-by-peer, esp_http_client_request_send() will still success? |
@AxelLin Yes, The premise is that the peer sends FIN to disconnect the socket. At this time, our tx connection is still on and can send data. I capture the packet and the result is the same. The ip 192.168.3.39 is my client. |
I test sending multiple POST requests to https server with HTTP keepalive enabled. BTW, I also have a question regarding the esp_transport_get_errno(): The esp_transport_get_errno() not only returned the sock_errno, it also clear esp_http_client_get_errno() is a public API, how do you make sure the esp_transport_get_errno() BTW, below comment says connection has been closed cleanly |
I have similar problem like in #2684 but the issue is closed.
I use ETH with W5500 module by SPI (but on wifi I also see the problem but rally rare).
My communication with server breaks sometimes.
I cannt recievd all fragments and in next attempt i see error log ESP_ERR_HTTP_FETCH_HEADER.
I have a little describe this problem in topic:
#2684 (comment)
I suspect a problem with the LWIP configuration and I have tried to tackle the problem on forum
https://www.esp32.com/viewtopic.php?f=13&t=20859&p=76493#p76493
but any one respond me.
I used ESP-IDF v4.4-dev-1254-g639e7ad49-dirty
esp_http_client_close() and/or esp_http_client_cleanup() dosnt solve the problem.
I used esp_restart() and initalization all peraph and connection and new connection.
Environment
Own product pcb using:
git describe --tags
to find it): ESP-IDF v4.4-dev-1254-g639e7ad49-dirtyxtensa-esp32-elf-gcc --version
to find it): xtensa-esp32-elf-gcc (crosstool-NG esp-2019r2) 8.2.0// 1.22.0-80-g6c4433a
Problem Description
Problem with received all fragments of response in POST method.
Expected Behavior
Stabilibty connection with server.
Actual Behavior
I (00:07:05.830) HTTP_CLIENT: HTTP_EVENT_ON_HEADER, key=content-length, value=48000
I (00:07:05.860) HTTP_CLIENT: 8192 ---> 8192
I (00:07:05.869) HTTP_CLIENT: 8192 ---> 16384
I (00:07:05.872) HTTP_CLIENT: 8192 ---> 24576
I (00:07:05.875) HTTP_CLIENT: 8192 ---> 32768
I (00:07:05.877) HTTP_CLIENT: 3940 ---> 36708
--lost communication after timeout
and next attempt with log
E (00:07:18.005) HTTP_CLIENT: HTTP POST request failed: ESP_ERR_HTTP_FETCH_HEADER no 28676 (7004)
I have tried use the same connection for GET i POST method.
Code to reproduce this issue
void test_connect()
{
esp_http_client_config_t config = {
.event_handler = _http_event_handler,
.buffer_size = 20480,
//.method=HTTP_METHOD_GET,
};
}
void http_client_set_config (esp_http_client_config_t * com_config)
{
com_config->path = (get_info_node()->addr_url);
com_config->timeout_ms = 60001; //!< Network timeout in milliseconds */
com_config->port = ADRES_PORT;
com_config->transport_type = HTTP_TRANSPORT_OVER_TCP;
com_config->buffer_size_tx = 1024,
printf("PREPARE TO connect to host \t path \t :port \n");
printf("%s%s port:%d\n", com_config->host, com_config->path, com_config->port);
}
int http_client_post(void* data, esp_http_client_handle_t * client3 )
{
printf("\n f(): %s\n", FUNCTION);
esp_err_t err;
int ret_val = 0;
const int TX_SIZE = REQ_ENDLIST*2;
}
The text was updated successfully, but these errors were encountered: