Skip to content
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

[TW#27054] esp_http_client issue - Wrong content length set #2638

Closed
AadiMehta opened this issue Oct 27, 2018 · 2 comments
Closed

[TW#27054] esp_http_client issue - Wrong content length set #2638

AadiMehta opened this issue Oct 27, 2018 · 2 comments

Comments

@AadiMehta
Copy link

Environment

  • Development Kit: [ESP32-DevKitC]
  • Kit version (DevKitC): [v3]
  • Core (if using chip or module): [ESP32-Wrover|ESP-WROOM32|ESP32]
  • IDF version : 11b444b

Problem Description

esp_http_client_open() API should set "Content-Length" header to the passed size. But the content-length header is either not set or it is set to 0.

I am trying to send a file from esp32 as attachment to a server. Here is the same code for the same.

Code to reproduce this issue

FILE *f = fopen(filename, "r");
   if (f == NULL) {
      ESP_LOGE(TAG, "Failed to open file for sending");
      return -1;
   }

   esp_http_client_handle_t client = esp_http_client_init(&config);

   esp_http_client_set_header(client, "User-Agent", "abc-Node");
   esp_http_client_set_header(client, "Content-Disposition", "attachment; filename=chip.log");
   esp_http_client_set_url(client, url);
   esp_http_client_set_method(client, HTTP_METHOD_POST);

   esp_err_t err;
   if ((err = esp_http_client_open(client, size)) != ESP_OK) {
      ESP_LOGE(TAG, "Failed to open HTTP connection: %s", esp_err_to_name(err));
      free(buffer);
      return -1;
   }

   bzero(buffer, MAX_HTTP_RECV_BUFFER);
   printf("Total size : %d\n", size);

   while ((ret = fread(&buffer[0], sizeof(char), MAX_HTTP_RECV_BUFFER, f)) > 0) {
      esp_http_client_write(client, buffer, ret);
      bzero(buffer, MAX_HTTP_RECV_BUFFER);
   }
   int content_length =  esp_http_client_fetch_headers(client);
   int total_read_len = 0, read_len;
   if (total_read_len < content_length && content_length <= MAX_HTTP_RECV_BUFFER) {
      read_len = esp_http_client_read(client, buffer, content_length);
      if (read_len <= 0) {
         ESP_LOGE(TAG, "Error read data");
      }
      buffer[read_len] = 0;
      ESP_LOGI(TAG, "read_len = %d", read_len);
   }
   ESP_LOGI(TAG, "HTTP Status = %d, content_length = %d",
                       esp_http_client_get_status_code(client),
                       esp_http_client_get_content_length(client));
   esp_http_client_close(client);
   esp_http_client_cleanup(client);
   free(buffer);
   fclose(f);

Debug Logs from server

{
	"CONTENT_LENGTH": "0",
	"SERVER_PROTOCOL": "HTTP/1.1",
	"REQUEST_METHOD": "POST",
	"PATH_INFO": "/logs/api/submit",
	"REMOTE_ADDR": "192.168.2.61",
	"CONTENT_TYPE": "text/plain",
	"HTTP_USER_AGENT": "abc-Node",
	"HTTP_HOST": "192.168.2.16",
	"HTTP_CONTENT_DISPOSITION": "attachment; filename=chip.log",
}
@negativekelvin
Copy link
Contributor

You are right, the value is not used at all. It should do
client->post_len=write_len;

esp_err_t esp_http_client_open(esp_http_client_handle_t client, int write_len)
{
esp_err_t err;
if ((err = esp_http_client_connect(client)) != ESP_OK) {
return err;
}
if ((err = esp_http_client_request_send(client)) != ESP_OK) {
return err;
}
return ESP_OK;
}

@Alvin1Zhang Alvin1Zhang changed the title esp_http_client issue - Wrong content length set [TW#27054] esp_http_client issue - Wrong content length set Oct 29, 2018
@mahavirj
Copy link
Member

mahavirj commented Mar 5, 2019

Fixed with 2e3f06e, closing.

@mahavirj mahavirj closed this as completed Mar 5, 2019
catalinio pushed a commit to catalinio/pycom-esp-idf that referenced this issue Jun 28, 2019
0xFEEDC0DE64 pushed a commit to 0xFEEDC0DE64/esp-idf that referenced this issue May 5, 2021
Currently  WiFiClient::write is unable to send messages over 25Kb, because of the hard-coded retry limit of 10, that is getting decremented on every successful send. Since we cannot send more than 2*MTU bytes in one go, and have only 10 retries, write() is limited to approximately 25Kb. Technically it is not a bug, as it correctly returns the number of sent bytes and the caller can set up futher retries. But not all libs are aware of this behavior, for example, WebServer is not.
I suggest improving current behavior by resetting retry counter every time we had a successful write, so the limit of 10 retries will apply to Failed writes only, and will not apply to Successful writes. This will allow to write() blobs of arbitrary sizes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants