ππ» httplib μΉμλ²μμ multipart νμΌ μ
λ‘λλ₯Ό ꡬννλ μ€λͺ
μ
λλ€.
This is a description of implementing multipart file uploads on an httplib web server.
ππ» νλ‘μ νΈ λλ ν 리λ΄μ httplib.hνμΌμ λ€μ΄ λ°μ΅λλ€.
Download the httplib.h file into the project directory.
βοΈ httplib.h(0.42.0)
curl -L https://raw.githubusercontent.com/yhirose/cpp-httplib/master/httplib.h -o httplib.h
ππ»Https server basic (https_upload_server.cpp)
βοΈ μλλ cpp ν΄λΌμ΄μΈνΈμμ λ‘컬 μλ²λ‘ νμΌμ μ
λ‘λ νλ μ€λͺ
μ
λλ€.
The following is an explanation of uploading files from a C++ client to a local server.
βοΈ κΉνλΈμμ νμΌ λ€μ΄λ‘λμ basic λλ ν 리 λ΄μ μλ νμΌ μ
λλ€.
This is the file located in the basic directory when downloading from GitHub.
βοΈ μΈμ¦μλ₯Ό νμ¬ λλ κ³ λ¦¬μ 볡μ¬ν©λλ€.
Copy the certificate to the current directory.
$ sudo cp /etc/letsencrypt/live/host.domain.org/fullchain.pem ./
$ sudo cp /etc/letsencrypt/live/host.domain.org/privkey.pem ./
# λ΄ κ³μ μΌλ‘ μμ κΆ λ³κ²½ / Change ownership to my account
$ sudo chown username:username *.pem
βοΈ μ½λ / Code
— https_upload_server.cpp
#define CPPHTTPLIB_OPENSSL_SUPPORT //
#include "../httplib.h"
#include <fstream>
#include <iostream>
int main() {
//httplib::Server svr;
httplib::SSLServer svr("./fullchain.pem", "./privkey.pem");
if (!svr.is_valid()) {
std::cerr << "SSL server setup failed\n";
return 1;
}
svr.Post("/upload", [&](const httplib::Request& req, httplib::Response& res,
const httplib::ContentReader& content_reader) {
if (!req.is_multipart_form_data()) {
res.status = 400;
res.set_content("Not multipart/form-data", "text/plain");
return;
}
std::string filename;
std::ofstream ofs;
content_reader(
[&](const httplib::FormData& item) {
if (item.name != "file") return true;
filename = httplib::sanitize_filename(item.filename);
if (filename.empty()) {
res.status = 400;
res.set_content("Invalid filename", "text/plain");
return false;
}
// file upload directory
ofs.open("../uploads/" + filename, std::ios::binary);
if (!ofs) {
res.status = 500;
res.set_content("Failed to open file", "text/plain");
return false;
}
return true;
},
[&](const char* data, size_t len) {
if (ofs) ofs.write(data, len);
return true;
}
);
if (ofs) ofs.close();
res.set_content("Upload OK", "text/plain");
});
std::cout << "Upload server listening on https://0.0.0.0:5080\n";
svr.listen("0.0.0.0", 5080);
}
— https_upload_client.cpp
#define CPPHTTPLIB_OPENSSL_SUPPORT
#include "../httplib.h"
#include <fstream>
#include <iostream>
int main() {
// HTTPS Client
httplib::SSLClient cli("host.domain.org", 5080);
// μ
λ‘λ νλͺ© / Upload item
httplib::UploadFormData item;
item.name = "file";
item.filename = "test.txt";
item.content_type = "text/plain";
std::ifstream ifs("test.txt", std::ios::binary);
if (!ifs) {
std::cerr << "cannot open file\n";
return 1;
}
item.content.assign((std::istreambuf_iterator<char>(ifs)),
std::istreambuf_iterator<char>());
httplib::UploadFormDataItems items;
items.push_back(item);
httplib::Headers headers;
if (auto res = cli.Post("/upload", headers, items)) {
std::cout << "status: " << res->status << "\n";
std::cout << res->body << "\n";
} else {
std::cerr << "request failed\n";
}
}
βοΈ μ»΄νμΌ / Compiling
g++ https_upload_server.cpp -o https_upload_server -std=c++17 -pthread -lssl -lcrypto
βοΈ μλ² μ€ν / Run Server
./https_upload_server

βοΈ μ»΄νμΌ / Compiling
g++ https_upload_client.cpp -o https_client_server -std=c++17 -pthread -lssl -lcrypto
βοΈ ν΄λΌμ΄μΈνΈ μ€ν / Run Client
./https_upload_client

βοΈ νμΌ μ λ‘λ μν νμΈ / Check file upload status

ππ»Https server html (https_upload_server.cpp)
βοΈ μλλ htmlνμΌμμ νμΌμ μ
λ‘λ νλ μ€λͺ
μ
λλ€.
Below is an explanation of how to upload a file in an HTML file.
βοΈ κΉνλΈμμ νμΌ λ€μ΄λ‘λμ uploads_html λλ ν 리 λ΄μ μλ νμΌ μ
λλ€.
This is the file located in the uploads_html directory when downloading from GitHub.
βοΈ www λλ ν λ¦¬κ° μμΌλ©΄ λλ ν 리λ₯Ό λ§λ¦λλ€.
If the www directory does not exist, create the directory.
βοΈ www λλ ν 리 μμ κ°λ¨ν index.htmlνμΌμ λ§λ¦λλ€.
Create a simple index.html file inside the www directory.
βοΈ index.html
<!doctype html>
<html lang="ko">
<head>
<meta charset="utf-8" />
<title>File Upload</title>
</head>
<body>
<h1>νμΌ μ
λ‘λ/File Upload</h1>
<form action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="file" />
<button type="submit">μ
λ‘λ/Upload</button>
</form>
</body>
</html>
βοΈ μΈμ¦μλ₯Ό νμ¬ λλ ν 리μ 볡μ¬ν©λλ€.
Copy the certificate to the current directory.
$ sudo cp /etc/letsencrypt/live/host.domain.org/fullchain.pem ./
$ sudo cp /etc/letsencrypt/live/host.domain.org/privkey.pem ./
# λ΄ κ³μ μΌλ‘ μμ κΆ λ³κ²½ / Change ownership to my account
$ sudo chown username:username *.pem
βοΈ μ½λ / Code
— https_upload_server.cpp
#define CPPHTTPLIB_OPENSSL_SUPPORT //
#include "../httplib.h"
#include <fstream>
#include <iostream>
int main() {
//httplib::Server svr;
httplib::SSLServer svr("./fullchain.pem", "./privkey.pem");
if (!svr.is_valid()) {
std::cerr << "SSL server setup failed\n";
return 1;
}
// html upload form
if (!svr.set_mount_point("/", "./www")) {
std::cerr << "κ²½λ‘ ν΄λλ₯Ό μ°Ύμ μ μμ΅λλ€! κ²½λ‘λ₯Ό νμΈνμΈμ./The path folder cannot be found! Please check the path." << std::endl;
return 1;
}
svr.Post("/upload", [&](const httplib::Request& req, httplib::Response& res,
const httplib::ContentReader& content_reader) {
if (!req.is_multipart_form_data()) {
res.status = 400;
res.set_content("Not multipart/form-data", "text/plain");
return;
}
std::string filename;
std::ofstream ofs;
content_reader(
[&](const httplib::FormData& item) {
if (item.name != "file") return true;
filename = httplib::sanitize_filename(item.filename);
if (filename.empty()) {
res.status = 400;
res.set_content("Invalid filename", "text/plain");
return false;
}
// file upload directory
ofs.open("../uploads/" + filename, std::ios::binary);
if (!ofs) {
res.status = 500;
res.set_content("Failed to open file", "text/plain");
return false;
}
return true;
},
[&](const char* data, size_t len) {
if (ofs) ofs.write(data, len);
return true;
}
);
if (ofs) ofs.close();
res.set_content("Upload OK", "text/plain");
});
std::cout << "Upload server listening on https://0.0.0.0:5080\n";
svr.listen("0.0.0.0", 5080);
}
βοΈ μ»΄νμΌ / Compiling
g++ https_upload_server.cpp -o https_upload_server -std=c++17 -pthread -lssl -lcrypto
βοΈ μλ² μ€ν / Run Server
./https_upload_server

βοΈ λΈλΌμ°μ μ μ / Browser access


βοΈ νμΌ μ λ‘λ μν νμΈ / Check file upload status
