๐๐ป 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
๐๐ปHttp server basic (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.
โ๏ธ ์ฝ๋ / Code
— upload_server.cpp
#include "../httplib.h"
#include <fstream>
#include <iostream>
int main() {
httplib::Server svr;
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 http://0.0.0.0:5080\n";
svr.listen("0.0.0.0", 5080);
}
— upload_client.cpp
#include "../httplib.h"
#include <fstream>
#include <iostream>
int main() {
httplib::Client cli("http://localhost:5080");
// ์
๋ก๋ ํญ๋ชฉ / upload
httplib::UploadFormData item;
item.name = "file";
item.filename = "test.txt";
item.content_type = "text/plain";
// ํ์ผ ์ฝ๊ธฐ / read file
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++ upload_server.cpp -o upload_server -std=c++11
โ๏ธ ์๋ฒ ์คํ / Run Server
./upload_server

โ๏ธ ์ปดํ์ผ / Compiling
g++ upload_client.cpp -o upload_client -std=c++11
โ๏ธ ํด๋ผ์ด์ธํธ ์คํ / Run Client
./upload_client

โ๏ธ ํ์ผ ์ ๋ก๋ ์ํ ํ์ธ / Check file upload status

๐๐ปHttp server html (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>
โ๏ธupload_server.cpp
#include "../httplib.h"
#include <fstream>
#include <iostream>
#include <sstream>
int main() {
httplib::Server svr;
// 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;
}
// ์
๋ก๋ ์ฒ๋ฆฌ / Upload processing
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;
}
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 << "Server listening on http://0.0.0.0:5080\n";
svr.listen("0.0.0.0", 5080);
}
โ๏ธ ์ปดํ์ผ / Compiling
g++ upload_server.cpp -o upload_server -std=c++11
โ๏ธ ์๋ฒ์คํ / Run Server
./upload_server
โ๏ธ ๋ธ๋ผ์ฐ์ ์ ์ / Browser access


upload ok
