#include #include #include #include #include #include "crow.h" std::string escapeHtml(const std::string &input) { std::string escaped; for (char c : input) { switch (c) { case '&': escaped += "&"; break; case '<': escaped += "<"; break; case '>': escaped += ">"; break; case '"': escaped += """; break; case '\'': escaped += "'"; break; default: escaped += c; break; } } return escaped; } std::string generateBreadcrumb(const std::string &urlpath) { std::stringstream breadcrumb; breadcrumb << ""; return breadcrumb.str(); } bool isImage(const std::string &path) { const std::string extensions[] = {".png", ".jpg", ".jpeg", ".gif", ".bmp", ".webp"}; for (const auto &ext : extensions) { if (path.size() >= ext.size() && path.compare(path.size() - ext.size(), ext.size(), ext) == 0) { return true; } } return false; } int main() { std::string path = "/home/suwako/open-repos/"; std::string repotype = ""; crow::SimpleApp website; CROW_ROUTE(website, "/")([&]() -> crow::response { repotype = ""; std::string res = "" "" ""; res += "

/

"; res += ""; res += ""; crow::response out(200, res); out.add_header("Content-Type", "text/html; charset=utf-8"); return out; }); CROW_ROUTE(website, "/")([&](const crow::request &req, std::string urlpath) -> crow::response { std::string lspath = path + urlpath; std::cout << "FUCK " << urlpath << std::endl; if (urlpath == "soft" || urlpath == "game" || urlpath == "web" || urlpath == "misc") { repotype = ""; } std::string title = ""; std::vector ret; std::string res = "" "" ""; if (lspath.find(".svn") != std::string::npos || lspath.find(".git") != std::string::npos || lspath.find(".hg") != std::string::npos) { std::cerr << "アクセス禁止: " << lspath << std::endl; res += "

馬鹿野郎、ここは立入禁止だろう!

"; res += ""; crow::response out(403, res); out.add_header("Content-Type", "text/html; charset=utf-8"); return out; } try { if (!std::filesystem::exists(lspath)) { std::cerr << "見つかりません: " << lspath << std::endl; res += "

見つかりません。

"; crow::response out(404, res); out.add_header("Content-Type", "text/html; charset=utf-8"); return out; } if (std::filesystem::is_regular_file(lspath)) { if (isImage(lspath)) { crow::response imageResponse; std::ifstream file(lspath, std::ios::binary); if (!file.is_open()) { std::cerr << "エラー: ファイルを開くに失敗: " << lspath << std::endl; res += "

エラー: ファイルを開くに失敗。

"; crow::response out(500, res); out.add_header("Content-Type", "text/html; charset=utf-8"); return out; } std::ostringstream buffer; buffer << file.rdbuf(); file.close(); std::string contentType = "image/"; if (lspath.ends_with(".jpg") || lspath.ends_with(".jpeg")) contentType += "jpeg"; else if (lspath.ends_with(".png")) contentType += "png"; else if (lspath.ends_with(".gif")) contentType += "gif"; else if (lspath.ends_with(".bmp")) contentType += "bmp"; else if (lspath.ends_with(".webp")) contentType += "webp"; imageResponse.add_header("Content-Type", contentType); imageResponse.write(buffer.str()); return imageResponse; } std::ifstream file(lspath); if (!file.is_open()) { std::cerr << "エラー: ファイルを開くに失敗: " << lspath << std::endl; res += "

エラー: ファイルを開くに失敗。

"; crow::response out(500, res); out.add_header("Content-Type", "text/html; charset=utf-8"); return out; } std::stringstream buffer; buffer << file.rdbuf(); file.close(); std::string content = escapeHtml(buffer.str()); res += "

" + title + "

"; res += generateBreadcrumb(urlpath); if (!repotype.empty()) res += "

レポジトリ種類: " + repotype + "

"; res += "
" + content + "
"; res += ""; crow::response out(200, res); out.add_header("Content-Type", "text/html; charset=utf-8"); return out; } if (!lspath.empty() && lspath.back() != '/') lspath += '/'; if (!std::filesystem::exists(lspath)) { std::cerr << "ディレクトリが見つかりません: " << lspath << std::endl; res += "

ディレクトリが見つかりません。

"; crow::response out(404, res); out.add_header("Content-Type", "text/html; charset=utf-8"); return out; } for (const auto &entry : std::filesystem::directory_iterator(lspath)) { std::string fullpath = entry.path().string(); std::string showpath = fullpath.substr(lspath.length()); if (showpath == ".hg") { repotype = "Mercurial"; continue; } if (showpath == ".git") { repotype = "Git"; continue; } if (showpath == ".svn") { repotype = "SVN"; continue; } std::string outpath = "" + showpath + ""; ret.push_back(outpath); } } catch (const std::filesystem::filesystem_error &e) { std::cerr << "エラーが発生しました: " << e.what() << std::endl; res += "

エラーが発生しました。

"; crow::response out(500, res); out.add_header("Content-Type", "text/html; charset=utf-8"); return out; } res += "

" + title + "

"; res += generateBreadcrumb(urlpath); if (!repotype.empty()) res += "

レポジトリ種類: " + repotype + "

"; res += "
    "; for (const auto &line : ret) { res += "
  • " + line + "
  • "; } res += "
"; res += ""; crow::response out(200, res); out.add_header("Content-Type", "text/html; charset=utf-8"); return out; }); website.port(8040).run(); }