Skip to content

Commit e38e9d5

Browse files
committed
refactor(upload): pass file size in Content length header
Signed-off-by: Riccardo Gallo <riccardo.gallo@secomind.com>
1 parent 82cd3e8 commit e38e9d5

3 files changed

Lines changed: 22 additions & 40 deletions

File tree

lib/edgehog_device/file_transfer/upload.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,11 @@ void edgehog_ft_handle_device_to_server(
123123
http_cbk_user_data->posix_errno = posix_errno;
124124
http_cbk_user_data->message = message;
125125

126+
// TODO: add content length
126127
edgehog_http_put_data_t http_put_data = { .url = msg->url,
127128
.header_fields = (const char **) msg->http_headers,
128129
.timeout_ms = EDGEHOG_FT_HTTP_REQ_TIMEOUT_MS,
130+
.payload_size = http_cbk_user_data->total_bytes,
129131
.payload_cbk = http_put_device_to_server_payload_cbk,
130132
.user_data = http_cbk_user_data };
131133
// Perform the HTTP put request to upload the file

lib/edgehog_device/http.c

Lines changed: 18 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
#include "log.h"
2424
EDGEHOG_LOG_MODULE_REGISTER(edgehog_http, CONFIG_EDGEHOG_DEVICE_HTTP_LOG_LEVEL);
2525

26+
#define CONTENT_LENGTH_HEADER_BUF_SIZE 64
27+
2628
/************************************************
2729
* Defines, constants and typedef *
2830
***********************************************/
@@ -189,27 +191,7 @@ static int put_payload_cbk(int sock, struct http_request * /*req*/, void *user_d
189191
// Format and send the chunk to the server
190192
if (http_payload_chunk.chunk_size > 0) {
191193
int sent_bytes = 0;
192-
char buffer[HTTP_CHUNKED_PAYLOAD_CHUNK_LENGTH_BUFFER_SIZE] = { 0 };
193-
const char crlf[] = "\r\n";
194-
195-
// Format chunk header
196-
int snprintf_rc = snprintf(
197-
buffer, ARRAY_SIZE(buffer), "%zx%s", http_payload_chunk.chunk_size, crlf);
198-
if (snprintf_rc < 0 || snprintf_rc >= ARRAY_SIZE(buffer)) {
199-
EDGEHOG_LOG_ERR("Failed to format chunk header: %d", snprintf_rc);
200-
ctx->result = EDGEHOG_RESULT_HTTP_REQUEST_ERROR;
201-
return -1;
202-
}
203194

204-
// Send header
205-
sent_bytes = send_buffer_fully(sock, buffer, snprintf_rc);
206-
if (sent_bytes < 0) {
207-
EDGEHOG_LOG_ERR("Failed to send chunk header: %d", sent_bytes);
208-
ctx->result = EDGEHOG_RESULT_HTTP_REQUEST_ERROR;
209-
return -1;
210-
}
211-
total_sent_bytes += sent_bytes;
212-
// Send payload
213195
sent_bytes = send_buffer_fully(
214196
sock, http_payload_chunk.chunk_start_addr, http_payload_chunk.chunk_size);
215197
if (sent_bytes < 0) {
@@ -218,14 +200,7 @@ static int put_payload_cbk(int sock, struct http_request * /*req*/, void *user_d
218200
return -1;
219201
}
220202
total_sent_bytes += sent_bytes;
221-
// Send trailing CRLF
222-
sent_bytes = send_buffer_fully(sock, crlf, sizeof(crlf) - 1);
223-
if (sent_bytes < 0) {
224-
EDGEHOG_LOG_ERR("Failed to send trailing CRLF: %d", sent_bytes);
225-
ctx->result = EDGEHOG_RESULT_HTTP_REQUEST_ERROR;
226-
return -1;
227-
}
228-
total_sent_bytes += sent_bytes;
203+
229204
EDGEHOG_LOG_DBG("Sent chunk of size %zu bytes", http_payload_chunk.chunk_size);
230205
}
231206
}
@@ -271,21 +246,16 @@ edgehog_result_t edgehog_http_put(edgehog_http_put_data_t *data)
271246
size_t user_header_fields_number = 0;
272247
char **header_fields = NULL;
273248

274-
// Search for any "Transfer-Encoding: chunked" header in the provided headers, or
275-
// "Content-Length: " header.
249+
// Search for any "Content-Length: " header in the provided headers
276250
if (data->header_fields) {
277251
for (size_t i = 0; data->header_fields[i] != NULL; i++) {
278252
const char *header = data->header_fields[i];
279253

280-
// Check for "Transfer-Encoding:" or "Content-Length:" headers (case-insensitive)
254+
// Check for "Content-Length:" headers (case-insensitive)
281255
// If found, return immediately with an error to prevent conflicting upload directives.
282-
char transfer_encoding[] = "Transfer-Encoding:";
283-
size_t transfer_encoding_len = sizeof(transfer_encoding) - 1;
284-
char content_length[] = "Content-Length:";
256+
char content_length[] = "Content-Length: ";
285257
size_t content_length_len = sizeof(content_length) - 1;
286-
if (strncmp(header, transfer_encoding, transfer_encoding_len) == 0
287-
|| strncmp(header, content_length, content_length_len) == 0) {
288-
258+
if (strncmp(header, content_length, content_length_len) == 0) {
289259
EDGEHOG_LOG_ERR("Conflicting header provided by user: %s", header);
290260
return EDGEHOG_RESULT_HTTP_REQUEST_INVALID_HEADERS;
291261
}
@@ -294,7 +264,7 @@ edgehog_result_t edgehog_http_put(edgehog_http_put_data_t *data)
294264
}
295265
}
296266

297-
// +2 for the "Transfer-Encoding: chunked" header and the NULL terminator
267+
// +2 for the "Content-Length: " header and the NULL terminator
298268
size_t header_fields_size = user_header_fields_number + 2;
299269
header_fields = (char **) k_malloc(header_fields_size * sizeof(char *));
300270
if (header_fields == NULL) {
@@ -307,8 +277,15 @@ edgehog_result_t edgehog_http_put(edgehog_http_put_data_t *data)
307277
for (size_t i = 0; i < user_header_fields_number; i++) {
308278
header_fields[i] = (char *) data->header_fields[i];
309279
}
310-
// Add the "Transfer-Encoding: chunked" header
311-
header_fields[user_header_fields_number] = "Transfer-Encoding: chunked\r\n";
280+
// Add the "Content-Length: " header
281+
char cl_buf[CONTENT_LENGTH_HEADER_BUF_SIZE] = { 0 };
282+
snprintf(cl_buf, sizeof(cl_buf), "Content-Length: %zu\r\n", data->payload_size);
283+
char *cl_header = k_malloc(CONTENT_LENGTH_HEADER_BUF_SIZE);
284+
if (!cl_header) {
285+
return EDGEHOG_RESULT_OUT_OF_MEMORY;
286+
}
287+
memcpy(cl_header, cl_buf, CONTENT_LENGTH_HEADER_BUF_SIZE);
288+
header_fields[user_header_fields_number] = cl_header;
312289
// The last element of the array is already set to NULL by memset
313290

314291
struct request_data req_data = {
@@ -328,6 +305,7 @@ edgehog_result_t edgehog_http_put(edgehog_http_put_data_t *data)
328305
};
329306

330307
edgehog_result_t result = perform_request(&req_data);
308+
k_free((void *) cl_header);
331309
k_free((void *) header_fields);
332310
return result;
333311
}

lib/edgehog_device/include/http.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ typedef struct
8989
const char **header_fields;
9090
/** @brief Timeout to use for the HTTP operations in ms. */
9191
int32_t timeout_ms;
92+
/** @brief Size of the data transmitted by the HTTP PUT request. */
93+
size_t payload_size;
9294
/** @brief Callback for a chunk payload event. */
9395
edgehog_http_payload_cbk_t payload_cbk;
9496
/** @brief User data passed to the callback function. */

0 commit comments

Comments
 (0)