Files

115 lines
2.9 KiB
C++
Raw Permalink Normal View History

#pragma once
// HTTP message types: one Request, one Response hierarchy with a subclass per
// format. Subclasses are constructor conveniences over the base value type so
// handlers can return by value without slicing loss. Gap: real molo::http_msg
// in 05-request-routing.md owns the final API; this skeleton mirrors it.
#include <map>
#include <string>
#include <string_view>
#include <vector>
namespace molo::example::fw {
enum class Method {
Get,
Post,
Put,
Patch,
Delete,
Head,
Options,
Propfind,
Proppatch,
Mkcol,
Copy,
Move,
Lock,
Unlock,
Unknown,
};
Method parse_method(std::string_view name);
std::string method_name(Method method);
class Headers {
public:
void set(std::string name, std::string value);
std::string get(std::string_view name) const;
bool has(std::string_view name) const;
const std::vector<std::pair<std::string, std::string>>& entries() const;
private:
std::vector<std::pair<std::string, std::string>> entries_;
};
struct Request {
Method method = Method::Get;
std::string path = "/";
std::map<std::string, std::string> query;
Headers headers;
std::map<std::string, std::string> cookies;
std::map<std::string, std::string> path_params;
std::string body;
std::string correlation_id;
std::string query_or(std::string_view key, std::string_view fallback) const;
std::string param_or(std::string_view key, std::string_view fallback) const;
std::string cookie_or(std::string_view key, std::string_view fallback) const;
};
struct Response {
int status = 200;
Headers headers;
std::string body;
Response() = default;
Response(int status, std::string body, std::string content_type);
std::string content_type() const;
};
struct TextResponse : Response {
explicit TextResponse(std::string body, int status = 200);
};
struct HtmlResponse : Response {
explicit HtmlResponse(std::string body, int status = 200);
};
struct JsonResponse : Response {
explicit JsonResponse(std::string body, int status = 200);
};
struct XmlResponse : Response {
explicit XmlResponse(std::string body, int status = 200);
};
struct RedirectResponse : Response {
RedirectResponse(std::string location, bool permanent);
};
struct FileResponse : Response {
FileResponse(std::string body, std::string content_type, std::string filename);
};
struct StreamingResponse : Response {
explicit StreamingResponse(std::vector<std::string> chunks);
std::vector<std::string> chunks;
};
struct SseResponse : Response {
explicit SseResponse(std::vector<std::string> events);
std::vector<std::string> events;
};
std::string url_decode(std::string_view in);
std::map<std::string, std::string> parse_query(std::string_view qs);
std::map<std::string, std::string> parse_cookies(std::string_view header);
std::map<std::string, std::string> parse_form(std::string_view body);
std::string status_text(int status);
std::string json_escape(std::string_view in);
} // namespace molo::example::fw