using MHD; using Invercargill; using Invercargill.DataStructures; namespace Astralis { public class HttpRequest : Object { // Basic request information public string raw_path { get; private set; } public Method method { get; private set; } public string version { get; private set; } // Path and routing public Enumerable path_components { get; private set; } public string query_string { get; private set; } // Request data collections public Catalogue headers { get; private set; } public Catalogue query_params { get; private set; } public Catalogue cookies { get; private set; } // Request body public AsyncInput request_body { get; private set; } // Content information public string content_type { get; private set; } public int64 content_length { get; private set; } public string? content_encoding { get; private set; } // Client information public string? remote_address { get; private set; } public string? user_agent { get; private set; } public string? referer { get; private set; } public HttpRequest( string url, string method, string version, Catalogue headers, AsyncInput request_body, Catalogue query, Catalogue cookies, string? remote_address ) { this.raw_path = url; this.method = Method.from_string(method); this.version = version; this.headers = headers; this.request_body = request_body; this.query_params = query; this.cookies = cookies; this.remote_address = remote_address; // Parse path components var path_parts = this.raw_path.split("?"); this.path_components = Wrap.array(path_parts[0].split("/")) .select(p => Uri.unescape_string(p) ?? "") .where(p => p != "") .to_immutable_buffer(); // Extract query string this.query_string = path_parts.length > 1 ? path_parts[1] : ""; // Extract common headers this.content_type = get_header("Content-Type") ?? ""; this.content_length = parse_content_length(get_header("Content-Length")); this.content_encoding = get_header("Content-Encoding"); this.user_agent = get_header("User-Agent"); this.referer = get_header("Referer"); } // Header access methods public string? get_header(string name) { string? value; if (headers.try_get_any(name, out value)) { return value; } return null; } public string get_header_or_default(string name, string default_value) { string? value; if (headers.try_get_any(name, out value)) { return value; } return default_value; } public Enumerable get_header_all(string name) { return headers.get_or_empty(name); } public bool has_header(string name) { return headers.has(name); } // Query parameter access methods public string? get_query(string name) { string? value; if (query_params.try_get_any(name, out value)) { return value; } return null; } public string get_query_or_default(string name, string default_value) { string? value; if (query_params.try_get_any(name, out value)) { return value; } return default_value; } public Enumerable get_query_all(string name) { return query_params.get_or_empty(name); } public bool has_query(string name) { return query_params.has(name); } // Cookie access methods public string? get_cookie(string name) { string? value; if (cookies.try_get_any(name, out value)) { return value; } return null; } public string get_cookie_or_default(string name, string default_value) { string? value; if (cookies.try_get_any(name, out value)) { return value; } return default_value; } public Enumerable get_cookie_all(string name) { return cookies.get_or_empty(name); } public bool has_cookie(string name) { return cookies.has(name); } public bool is_form_urlencoded() { return content_type.contains("application/x-www-form-urlencoded"); } public bool is_json() { return content_type.contains("application/json"); } public bool is_multipart() { return content_type.contains("multipart/form-data"); } // Helper method private static int64 parse_content_length(string? value) { if (value == null) return 0; return int64.parse(value); } } public class HttpContext : Object { public HttpRequest request { get; private set; } internal HttpContext(HttpRequest request) { this.request = request; } } }