Complete except for throttling bug.

This commit is contained in:
Robin E.R. Davies
2026-02-10 19:59:05 -05:00
parent aec88fa9f1
commit 22b63a32db
42 changed files with 2597 additions and 564 deletions
+54 -1
View File
@@ -394,6 +394,59 @@ std::string HtmlHelper::generateEtag(const std::filesystem::path &path)
static std::map<int,std::string> httpErrorStrings =
{
{200,"OK"},
{201, "Created"},
{202, "Accepted"},
{203, "Non-Authoritative Information"},
{204, "No Content"},
{205, "Reset Content"},
{206, "Partial Content"},
{300, "Multiple Choices"},
{301, "Moved Permanently"},
{302, "Found"},
{303, "See Other"},
{304, "Not Modified"},
{305, "Use Proxy"},
{307, "Temporary Redirect"},
{308, "Permanent Redirect"},
{400, "Bad Request"},
{401, "Unauthorized"},
{402, "Payment Required"},
{403, "Forbidden"},
{404, "Not Found"},
{405, "Method Not Allowed"},
{406, "Not Acceptable"},
{407, "Proxy Authentication Required"},
{408, "Request Timeout"},
{409, "Conflict"},
{410, "Gone"},
{411, "Length Required"},
{412, "Precondition Failed"},
{413, "Payload Too Large"},
{414, "URI Too Long"},
{415, "Unsupported Media Type"},
{416, "Range Not Satisfiable"},
{417, "Expectation Failed"},
{418, "I'm a teapot"},
{421, "Misdirected Request"},
{422, "Unprocessable Content"},
{423, "Locked"},
{424, "Failed Dependency"},
{426, "Upgrade Required"},
{428, "Precondition Required"},
{429, "Too Many Requests"},
{431, "Request Header Fields Too Large"},
{451, "Unavailable For Legal Reasons"},
{500, "Internal Server Error"},
{501, "Not Implemented"},
{502, "Bad Gateway"},
{503, "Service Unavailable"},
{504, "Gateway Timeout"},
{505, "HTTP Version Not Supported"},
{506, "Variant Also Negotiates"},
{507, "Insufficient Storage"},
{508, "Loop Detected"},
{510, "Not Extended"},
{511, "Network Authentication Required"}
};
@@ -405,6 +458,6 @@ std::string HtmlHelper::httpErrorString(int errorCode)
{
return SS(errorCode << " " << ff->second);
}
return SS(errorCode);
return SS(errorCode << " Unknown error");
}
+4 -2
View File
@@ -124,7 +124,9 @@ namespace pipedal
std::string ToLower(const std::string&value);
std::string safeFilenameToString(const std::string &filename);
std::string stringToSafeFilename(const std::string &name);
std::string SafeFilenameToString(const std::string &filename);
std::string StringToSafeFilename(const std::string &name);
std::string ShellEscape(const std::string &input);
}
+29 -4
View File
@@ -243,13 +243,13 @@ bool pipedal::HasWritePermissions(const std::filesystem::path &path)
return access(path.c_str(), W_OK) == 0;
}
const std::string SF_SPECIAL_CHARS = " <>@;:\"\'/[]?=+%.";
const std::string SAFE_FILENAME_SPECIAL_CHARS = "<>@;:\"\'/[]?=+%.&|*^~`#";
static std::array<bool, 256> makeSfBits()
{
std::array<bool, 256> result;
for (char c : SF_SPECIAL_CHARS)
for (char c : SAFE_FILENAME_SPECIAL_CHARS)
{
result[(unsigned char)c] = true;
}
@@ -257,6 +257,10 @@ static std::array<bool, 256> makeSfBits()
{
result[i] = true;
}
for (size_t i = 0; i < 0x20; ++i)
{
result[i] = true;
}
return result;
}
@@ -285,7 +289,7 @@ static char fromHexChars(char c1, char c2)
return (char)uc;
}
std::string pipedal::safeFilenameToString(const std::string &filename)
std::string pipedal::SafeFilenameToString(const std::string &filename)
{
size_t ix = 0;
std::ostringstream os;
@@ -315,7 +319,7 @@ std::string pipedal::safeFilenameToString(const std::string &filename)
}
return os.str();
}
std::string pipedal::stringToSafeFilename(const std::string &name)
std::string pipedal::StringToSafeFilename(const std::string &name)
{
std::ostringstream os;
for (char c : name)
@@ -338,3 +342,24 @@ std::string pipedal::stringToSafeFilename(const std::string &name)
}
return os.str();
}
std::string pipedal::ShellEscape(const std::string &input)
{
// Escape string for safe use in shell commands by using single quotes
// and escaping any single quotes in the input
std::string result = "'";
for (char c : input)
{
if (c == '\'')
{
// End quote, add escaped single quote, start quote again
result += "'\\''";
}
else
{
result += c;
}
}
result += "'";
return result;
}