Reading API Chunked Response in C

savethebrain
Posts: 1
Joined: Wed Jun 05, 2024 2:32 pm

Reading API Chunked Response in C

Postby savethebrain » Wed Jun 05, 2024 2:36 pm

I'm building a Firebase API in C for esp32-c3

Currently I'm able to construct the url and perform a request but for some reason I can't read any data from the response and response len is always 0
here's the code and the output

Code: Select all

void firebase_login_user(Firebase* self, char* email, char* password) {
    char* url = malloc(strlen(self->api_key) + 78);
    if (url == NULL) {
        ESP_LOGE(TAG, "Error allocating memory for URL");
        return;
    }
    strcpy(url, "https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyPassword?key=");
    char *full_url = strjoin(url, self->api_key);
    free(url); // Free the initial allocation

    if (!full_url) {
        ESP_LOGE(TAG, "Error joining URL");
        return;
    }

    cJSON *root = cJSON_CreateObject();
    cJSON_AddStringToObject(root, "email", email);
    cJSON_AddStringToObject(root, "password", password);
    cJSON_AddTrueToObject(root, "returnSecureToken");
    char *data = cJSON_Print(root);

    ESP_LOGI(TAG, "URL: %s", full_url);
    ESP_LOGI(TAG, "JSON: %s", data);

    esp_http_client_config_t config = {
        .url = full_url,
        .method = HTTP_METHOD_POST,
        .transport_type = HTTP_TRANSPORT_OVER_SSL,
    };
    esp_http_client_handle_t client = esp_http_client_init(&config);
    if (client == NULL) {
        ESP_LOGE(TAG, "Failed to initialize HTTP client");
        free(full_url);
        cJSON_Delete(root);
        free(data);
        return;
    }
    esp_http_client_set_header(client, "Content-Type", "application/json; charset=UTF-8");
    esp_http_client_set_post_field(client, data, strlen(data));

    esp_err_t err = esp_http_client_perform(client);
    if (err == ESP_OK) {
        ESP_LOGI(TAG, "HTTP POST Status = %d, %s", err, esp_err_to_name(err));
        int http_status = esp_http_client_get_status_code(client);
        ESP_LOGI(TAG, "HTTP Status Code = %d", http_status);
        int content_length = esp_http_client_get_content_length(client);
        ESP_LOGI(TAG, "Content Length = %d", content_length);

        if (http_status == 200) {
            if (content_length == -1) {
                // Handle chunked transfer encoding
                ESP_LOGI(TAG, "Chunked response");
                char *buffer = malloc(512);
                if (buffer == NULL) {
                    ESP_LOGE(TAG, "Error allocating memory for buffer");
                } else {
                    int total_data_read = 0;
                    int data_read;
                    do {
                        data_read = esp_http_client_read(client, buffer, 512);
                        if (data_read > 0) {
                            buffer[data_read] = '\0'; // Null-terminate the response
                            ESP_LOGI(TAG, "Chunk: %s", buffer);
                            total_data_read += data_read;
                        } else if (data_read < 0) {
                            ESP_LOGE(TAG, "Error reading data");
                        }
                    } while (data_read > 0);
                    ESP_LOGI(TAG, "Total data read: %d", total_data_read);
                    free(buffer);
                }
            } else {
                // Handle non-chunked response
                char *buffer = malloc(content_length + 1);
                if (buffer == NULL) {
                    ESP_LOGE(TAG, "Error allocating memory for buffer");
                } else {
                    int total_data_read = esp_http_client_read(client, buffer, content_length);
                    if (total_data_read >= 0) {
                        buffer[total_data_read] = '\0'; // Null-terminate the response
                        ESP_LOGI(TAG, "Response: %s", buffer);
                    } else {
                        ESP_LOGE(TAG, "Error reading data");
                    }
                    free(buffer);
                }
            }
        } else {
            ESP_LOGE(TAG, "Unexpected HTTP status code: %d", http_status);
        }
    } else {
        ESP_LOGE(TAG, "Error performing HTTP request: %s", esp_err_to_name(err));
    }

    esp_http_client_cleanup(client);
    cJSON_Delete(root);
    free(data);
    free(full_url);
}
Output

Code: Select all

I (12824) netlog: HTTP POST Status = 0, ESP_OK
I (12824) netlog: HTTP Status Code = 200
I (12824) netlog: Content Length = -1
I (12824) netlog: Chunked response
I (12834) netlog: Total data read: 0
I (12834) main_task: Returned from app_main()
Any idea what am I doing wrong?

This is the equivalent of what I'm trying to do in Python, which works perfectly

Code: Select all

    def login_user(self, email, password):
        request_link = f"https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyPassword?key={self.api_key}"
        headers = {"content-type": "application/json; charset=UTF-8"}
        data = json.dumps({"email": email, "password": password, "returnSecureToken": True})
        request_data = self.requests.post(request_link, headers=headers, data=data)
        self.error_http(request_data)
        self.currentUser = request_data.json()
        self.token = self.currentUser["idToken"]
        return request_data.json()
Thanks.

User avatar
parthbhat13
Posts: 8
Joined: Wed Oct 07, 2020 2:07 pm

Re: Reading API Chunked Response in C

Postby parthbhat13 » Tue Jul 02, 2024 9:22 am

Hi,
i wonder if the problem you are facing is actually solved?
there is even another thread where the instructions to use the

Code: Select all

esp_http_client_read
is actually very much unclear, they do mention to use the event Handel to read the data.

here is the link for the other thread i could find stating the issue. https://esp32.com/viewtopic.php?f=13&t= ... 10#p134310

and the only example which is given is the following, where

Code: Select all

esp_http_client_read
is not implemented.
https://github.com/espressif/esp-idf/bl ... _example.c

Who is online

Users browsing this forum: Bing [Bot] and 196 guests