Hello,
I was trying to execute multipart request for uploading log files. For testing the multipart that how does it works first I made a server through python script which I linked with ngrok so that other people can also upload files. Than I tried sending the request through postman and it was executing perfectly. The below request is what I sent through postman.
POST /upload HTTP/1.1
Host: 148a-106-51-226-188.ngrok-free.app
Content-Length: 203
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="01.00.01.52.bin"
Content-Type: <Content-Type header here>
(data)
------WebKitFormBoundary7MA4YWxkTrZu0gW--
After this I wanted to do the same thing via firmware, I was able to retrieve the ip address of the ngrok server and was able to connect with it too but while sending the request I receive:
[00:01:36.048,339] <err> home_demo_https: Failed to send HTTP multipart headers, err: -104
[00:01:36.048,706] <err> home_demo_sdcard: Failed to send request
this error. We are already saving binary files in sd card in the application so I was trying to use that binary file for upload
I am attaching the function too for reference
static void logsUpload_cb(struct http_response *rsp, enum http_final_call final_data, void *user_data)
{
//Define the callback function to print the body
LOG_INF("Response status: %s", rsp->http_status);
if (rsp->body_frag_len > 0) {
char body_buf[rsp->body_frag_len];
strncpy(body_buf, rsp->body_frag_start, rsp->body_frag_len);
body_buf[rsp->body_frag_len]='\0';
LOG_INF("Received: %s", body_buf);
}
}
int logsUpload_req(char *filename)
{
int err = 0;
///Define the structure http_request and fill the block of memory
struct http_request req;
memset(&req, 0, sizeof(req));
char multipart_header[256];
snprintf(multipart_header, sizeof(multipart_header),
"--%s\r\n"
"Content-Disposition: form-data; name=\"file\"; filename=\"%s\"\r\n"
"Content-Type: application/octet-stream\r\n",
BOUNDARY, filename);
char multipart_footer[64];
snprintf(multipart_footer, sizeof(multipart_footer),
"\r\n--%s--\r\n",
BOUNDARY);
size_t content_length = strlen(multipart_header) + bytes_read + strlen(multipart_footer);
char content_length_header[64];
snprintf(content_length_header, sizeof(content_length_header),
"Content-Length: %zu\r\n", content_length);
//Populate the http_request structure
// Include Content-Length in headers
const char *headers[] = {
"Connection: close\r\n",
"Host: 148a-106-51-226-188.ngrok-free.app\r\n",
"Content-Type: multipart/form-data; boundary=" BOUNDARY "\r\n",
content_length_header,
NULL
};
req.header_fields = headers;
req.method = HTTP_POST;
req.url = "/upload";
req.host = LOG_HOSTNAME;
req.protocol = "HTTP/1.1";
req.payload = multipart_header;
req.payload_len = strlen(multipart_header);
req.response = logsUpload_cb;
req.recv_buf = recv_buf;
req.recv_buf_len = sizeof(recv_buf);
LOG_INF("Sending multipart headers...");
err = http_client_req(sock, &req, 7000, NULL);
if (err < 0) {
LOG_ERR("Failed to send HTTP multipart headers, err: %d", err);
return err;
}
req.payload = filename; // Let the HTTP client handle streaming
req.payload_len = bytes_read;
LOG_INF("Sending file data...");
err = http_client_req(sock, &req, 7000, NULL);
if (err < 0) {
LOG_ERR("Failed to send file data, err: %d", err);
return err;
}
req.payload = multipart_footer;
req.payload_len = strlen(multipart_footer);
LOG_INF("Sending multipart footer...");
err = http_client_req(sock, &req, 7000, NULL);
if (err < 0) {
LOG_ERR("Failed to send multipart footer, err: %d", err);
return err;
}
LOG_INF("File uploaded successfully!");
//Send the request to the HTTP server
// LOG_INF("HTTP POST request: %s",req.payload);
return err;
}