| // | |
| // upload.cc | |
| // | |
| // Copyright (c) 2026 Yuji Hirose. All rights reserved. | |
| // MIT License | |
| // | |
| #include <fstream> | |
| #include <httplib.h> | |
| #include <iostream> | |
| using namespace httplib; | |
| using namespace std; | |
| const char *html = R"( | |
| <form id="formElem"> | |
| <input type="file" name="image_file" accept="image/*"> | |
| <input type="file" name="text_file" accept="text/*"> | |
| <input type="submit"> | |
| </form> | |
| <script> | |
| formElem.onsubmit = async (e) => { | |
| e.preventDefault(); | |
| let res = await fetch('/post', { | |
| method: 'POST', | |
| body: new FormData(formElem) | |
| }); | |
| console.log(await res.text()); | |
| }; | |
| </script> | |
| )"; | |
| int main(void) { | |
| Server svr; | |
| svr.Get("/", [](const Request & /*req*/, Response &res) { | |
| res.set_content(html, "text/html"); | |
| }); | |
| svr.Post("/post", [](const Request &req, Response &res) { | |
| const auto &image_file = req.form.get_file("image_file"); | |
| const auto &text_file = req.form.get_file("text_file"); | |
| cout << "image file length: " << image_file.content.length() << endl | |
| << "image file name: " << image_file.filename << endl | |
| << "text file length: " << text_file.content.length() << endl | |
| << "text file name: " << text_file.filename << endl; | |
| // Reduce a client-supplied filename to a safe base name, or return an | |
| // empty string if it cannot be trusted (empty, ".", "..", or contains a | |
| // path separator). | |
| auto sanitize = [](const string &filename) -> string { | |
| auto name = filename.substr(filename.find_last_of("/\\") + 1); | |
| if (name.empty() || name == "." || name == ".." || | |
| name.find(':') != string::npos) { | |
| return string(); | |
| } | |
| return name; | |
| }; | |
| const auto image_name = sanitize(image_file.filename); | |
| const auto text_name = sanitize(text_file.filename); | |
| if (image_name.empty() || text_name.empty()) { | |
| res.status = StatusCode::BadRequest_400; | |
| return; | |
| } | |
| { | |
| ofstream ofs(image_name, ios::binary); | |
| if (!ofs) { | |
| res.status = StatusCode::InternalServerError_500; | |
| res.set_content("Failed to write image file", "text/plain"); | |
| return; | |
| } | |
| ofs << image_file.content; | |
| } | |
| { | |
| ofstream ofs(text_name); | |
| if (!ofs) { | |
| res.status = StatusCode::InternalServerError_500; | |
| res.set_content("Failed to write text file", "text/plain"); | |
| return; | |
| } | |
| ofs << text_file.content; | |
| } | |
| res.set_content("done", "text/plain"); | |
| }); | |
| svr.listen("localhost", 1234); | |
| } |