Help with HTTP_EVENT_DISCONNECTED

austinp
Posts: 1
Joined: Thu May 05, 2022 4:00 am

Help with HTTP_EVENT_DISCONNECTED

Postby austinp » Thu May 05, 2022 4:17 am

I'm running into an issue where I'm unable to read the response body of an http response.

When I make the request I'm able to get the response code (200 in this case), but the output_buffer gets freed since the event was HTTP_EVENT_DISCONNECTED.

Does anyone have an ideas on how I could troubleshoot this.

http event handler (from https://github.com/espressif/esp-idf/bl ... _example.c) and request helper function

Code: Select all

char local_response_buffer[MAX_HTTP_OUTPUT_BUFFER] = {0};


esp_err_t _http_event_handler(esp_http_client_event_t *evt)
{
    static char *output_buffer;  // Buffer to store response of http request from event handler
    static int output_len;       // Stores number of bytes read
    switch(evt->event_id) {
        case HTTP_EVENT_ERROR:
            ESP_LOGD(HTTP_TAG, "HTTP_EVENT_ERROR");
            break;
        case HTTP_EVENT_ON_CONNECTED:
            ESP_LOGD(HTTP_TAG, "HTTP_EVENT_ON_CONNECTED");
            break;
        case HTTP_EVENT_HEADER_SENT:
            ESP_LOGD(HTTP_TAG, "HTTP_EVENT_HEADER_SENT");
            break;
        case HTTP_EVENT_ON_HEADER:
            ESP_LOGD(HTTP_TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value);
            break;
        case HTTP_EVENT_ON_DATA:
            ESP_LOGD(HTTP_TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);
            /*
             *  Check for chunked encoding is added as the URL for chunked encoding used in this example returns binary data.
             *  However, event handler can also be used in case chunked encoding is used.
             */
            if (!esp_http_client_is_chunked_response(evt->client)) {
                // If user_data buffer is configured, copy the response into the buffer
                if (evt->user_data) {
                    memcpy(evt->user_data + output_len, evt->data, evt->data_len);
                } else {
                    if (output_buffer == NULL) {
                        output_buffer = (char *) malloc(esp_http_client_get_content_length(evt->client));
                        output_len = 0;
                        if (output_buffer == NULL) {
                            ESP_LOGE(HTTP_TAG, "Failed to allocate memory for output buffer");
                            return ESP_FAIL;
                        }
                    }
                    memcpy(output_buffer + output_len, evt->data, evt->data_len);
                }
                output_len += evt->data_len;
            }

            break;
        case HTTP_EVENT_ON_FINISH:
            ESP_LOGD(HTTP_TAG, "HTTP_EVENT_ON_FINISH");
            if (output_buffer != NULL) {
                // Response is accumulated in output_buffer. Uncomment the below line to print the accumulated response
                // ESP_LOG_BUFFER_HEX(HTTP_TAG, output_buffer, output_len);
                free(output_buffer);
                output_buffer = NULL;
            }
            output_len = 0;
            break;
        case HTTP_EVENT_DISCONNECTED:
            ESP_LOGI(HTTP_TAG, "HTTP_EVENT_DISCONNECTED");
            int mbedtls_err = 0;
            esp_err_t err = esp_tls_get_and_clear_last_error((esp_tls_error_handle_t)evt->data, &mbedtls_err, NULL);
            if (err != 0) {
                ESP_LOGI(HTTP_TAG, "Last esp error code: 0x%x", err);
                ESP_LOGI(HTTP_TAG, "%s", esp_err_to_name(err));
                ESP_LOGI(HTTP_TAG, "Last mbedtls failure: 0x%x", mbedtls_err);
            }
            if (output_buffer != NULL) {
                free(output_buffer);
                output_buffer = NULL;
            }
            output_len = 0;
            break;
        case HTTP_EVENT_REDIRECT:
            ESP_LOGD(HTTP_TAG, "HTTP_EVENT_REDIRECT");
            esp_http_client_set_header(evt->client, "From", "user@example.com");
            esp_http_client_set_header(evt->client, "Accept", "text/html");
            break;
    }
    return ESP_OK;
}


HTTPResponse_t https_request(const char* url, esp_http_client_method_t method, char* postData, const char* query) {
    esp_http_client_config_t config = {
        .user_data = local_response_buffer,
        .crt_bundle_attach = esp_crt_bundle_attach,
        .event_handler = _http_event_handler,
        .url = url,
        .method = method,
        .timeout_ms = 5000
    };
    if (query) {
        config.query = query;
    };

    esp_http_client_handle_t client = esp_http_client_init(&config);
    if (postData) {
        esp_http_client_set_header(client, "Content-Type", "application/json");
        esp_http_client_set_post_field(client, postData, strlen(postData));
    };

    ESP_LOGI(HTTP_TAG, "%s", "REQUESTING");
    esp_err_t err = esp_http_client_perform(client);
    ESP_LOGI(HTTP_TAG, "%s", esp_err_to_name(err));
    ESP_LOGI(HTTP_TAG, "%s", "FINISHED");
    ESP_LOGI("RESPONSE", "%s", (const char *) local_response_buffer);
    ESP_LOGI("CODE", "%i", esp_http_client_get_status_code(client));
    ESP_LOGI("ERROR", "%i", esp_http_client_get_errno(client));
    HTTPResponse_t response = {
        .code = esp_http_client_get_status_code(client),
        .body = cJSON_Parse(local_response_buffer),
    };
    esp_http_client_cleanup(client);
    return response;
}
Making the request

Code: Select all

...
  HTTPResponse tokenResponse = https_request("https://oauth2.googleapis.com/token", HTTP_METHOD_POST, cJSON_Print(grantJSON), nullptr);
  ESP_LOGI("grantJSON", "%s", cJSON_Print(tokenResponse.body));
  ...

The resulting output

Code: Select all

I (4722) HTTP_CLIENT: REQUESTING
I (4942) esp-x509-crt-bundle: Certificate validated
I (6552) HTTP_CLIENT: ESP_OK
I (6552) HTTP_CLIENT: FINISHED
I (6552) RESPONSE: 
I (6552) CODE: 200
I (6552) ERROR: 0
I (6552) HTTP_CLIENT: HTTP_EVENT_DISCONNECTED
Guru Meditation Error: Core  0 panic'ed (LoadProhibited). Exception was unhandled.

Core  0 register dump:
PC      : 0x400014fd  PS      : 0x00060e30  A0      : 0x8016f2c4  A1      : 0x3ffbc500  
A2      : 0x00000000  A3      : 0xfffffffc  A4      : 0x000000ff  A5      : 0x0000ff00  
A6      : 0x00ff0000  A7      : 0xff000000  A8      : 0x00000000  A9      : 0x3ffbc4c0  
A10     : 0x00000000  A11     : 0x3f403ee9  A12     : 0x3ffbc744  A13     : 0x3ffaf02c  
A14     : 0x00000000  A15     : 0x00000001  SAR     : 0x00000004  EXCCAUSE: 0x0000001c  
EXCVADDR: 0x00000000  LBEG    : 0x400014fd  LEND    : 0x4000150d  LCOUNT  : 0xffffffff
I tested this event handler and request function with some get/post requests to httpbin and I was able to read the responses just fine.

Any help would be appreciated.

ESP_YJM
Posts: 300
Joined: Fri Feb 26, 2021 10:30 am

Re: Help with HTTP_EVENT_DISCONNECTED

Postby ESP_YJM » Wed May 11, 2022 7:04 am

I think you can deal with the data in evnet HTTP_EVENT_ON_DATA. This example is only a n example that tells the reader where and when i can get the HTTP response.

vritzka
Posts: 30
Joined: Wed Sep 07, 2022 5:33 am

Re: Help with HTTP_EVENT_DISCONNECTED

Postby vritzka » Fri Jan 31, 2025 5:02 pm

For anyone else struggling with this, keep in mind that most logs in the example are ESP_LOGD, which are not printed on standard log level settings. Replace with ESP_LOGI or change log level to see them.

Who is online

Users browsing this forum: Bing [Bot], Majestic-12 [Bot] and 51 guests