feat: implement MoloApp plans 01-15 with integration
Full C++23 framework tree: runtime, observability, security, data, app, realtime, supervisor, clients, CLI, example plus enterprise tenancy, audit, operability, governance, supplychain. Postgres via docker compose for tests.
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
#include "Negotiate.hpp"
|
||||
|
||||
#include <cctype>
|
||||
|
||||
namespace molo::example::fw {
|
||||
|
||||
namespace {
|
||||
|
||||
std::string trim(std::string s) {
|
||||
while (!s.empty() && (s.front() == ' ' || s.front() == '\t')) s.erase(s.begin());
|
||||
while (!s.empty() && (s.back() == ' ' || s.back() == '\t')) s.pop_back();
|
||||
return s;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
std::string negotiate(const std::string& accept,
|
||||
const std::vector<std::string>& available) {
|
||||
if (available.empty()) throw HttpError(500, "no_offers", "no offers");
|
||||
if (accept.empty()) return available.front();
|
||||
struct Range {
|
||||
std::string type;
|
||||
double q = 1.0;
|
||||
};
|
||||
std::vector<Range> ranges;
|
||||
std::size_t start = 0;
|
||||
while (start < accept.size()) {
|
||||
std::size_t comma = accept.find(',', start);
|
||||
if (comma == std::string::npos) comma = accept.size();
|
||||
std::string part = trim(accept.substr(start, comma - start));
|
||||
std::size_t semi = part.find(';');
|
||||
Range r{trim(part.substr(0, semi)), 1.0};
|
||||
if (semi != std::string::npos) {
|
||||
std::string params = part.substr(semi + 1);
|
||||
std::size_t q = params.find("q=");
|
||||
if (q != std::string::npos) {
|
||||
try {
|
||||
r.q = std::stod(params.substr(q + 2));
|
||||
} catch (...) {
|
||||
r.q = 1.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
ranges.push_back(r);
|
||||
start = comma + 1;
|
||||
}
|
||||
std::string best;
|
||||
double best_q = -1.0;
|
||||
for (const auto& a : available) {
|
||||
for (const auto& r : ranges) {
|
||||
bool hit = r.type == "*/*" || r.type == a;
|
||||
if (!hit) {
|
||||
std::size_t slash = a.find('/');
|
||||
std::string wild = slash == std::string::npos
|
||||
? "*/*"
|
||||
: a.substr(0, slash) + "/*";
|
||||
hit = r.type == wild;
|
||||
}
|
||||
if (hit && r.q > best_q) {
|
||||
best_q = r.q;
|
||||
best = a;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (best.empty() || best_q <= 0.0)
|
||||
throw HttpError(406, "not_acceptable", "no acceptable format");
|
||||
return best;
|
||||
}
|
||||
|
||||
} // namespace molo::example::fw
|
||||
Reference in New Issue
Block a user