19#define native_static_serve_strdup _strdup
21#define native_static_serve_strdup strdup
25 char *relative = NULL;
26 char *file_path = NULL;
27 char *content_type = NULL;
30 const char *path_part = path;
31 const char *query = strchr(path,
'?');
32 size_t path_len = query != NULL ? (size_t)(query - path) : strlen(path);
33 long long content_length = 0;
34 if (strstr(path,
"..") != NULL) {
40 if (relative == NULL) {
41 if (path_len == 0 || (path_len == 1 && path[0] ==
'/')) {
43 }
else if (path[path_len - 1] ==
'/') {
44 relative = (
char *)malloc(path_len + strlen(
"index.html"));
45 if (relative != NULL) {
46 memcpy(relative, path_part + 1, path_len - 1);
47 memcpy(relative + path_len - 1,
"index.html", strlen(
"index.html") + 1);
50 relative =
dup_range(path_part + 1, path_len - 1);
53 if (relative == NULL) {
59 if (file_path == NULL) {
65 char *dir_index =
path_join(file_path,
"index.html");
67 file_path = dir_index;
74 file = fopen(file_path,
"rb");
80 if (fseek(file, 0, SEEK_END) != 0) {
85 content_length = (
long long)ftell(file);
86 if (content_length < 0 || fseek(file, 0, SEEK_SET) != 0) {
92 if (content_type == NULL) {
97 if (
starts_with(path_part,
"/api/") && strcmp(content_type,
"application/octet-stream") == 0) {
100 if (content_type == NULL) {
108 "HTTP/1.1 200 OK\r\n"
109 "Content-Type: %s\r\n"
110 "Content-Length: %lld\r\n"
111 "Connection: close\r\n"
122 while ((bytes_read = fread(chunk, 1,
sizeof(chunk), file)) > 0) {
132 if (status >= 200 && status < 400) {
134 }
else if (status > 0) {
int native_connection_write(NativeConnection *connection, const void *buffer, size_t len)
Writes bytes to a native connection.
char * native_dispatch_response_file_for_request(const char *root, const char *method, const char *path)
Resolves the response artifact file for one request using the dispatch table.
Declares dispatch-table request path helpers.
void native_write_access_log(const char *log_path, const HttpRequest *request, const char *request_path, int status_code)
Writes one access log entry for a completed HTTP request.
void native_write_error_log(const char *log_path, const char *error_report_path, const char *app_id, const HttpRequest *request, const char *request_path, const char *status_text, const char *reason, const char *resource_path, const char *detail_text)
Writes one structured error log entry and its paired JSONL error report.
Declares native access log and error log helpers.
char * mime_type_for_path(const char *path)
Resolves the MIME type that should be used for a file path.
const char * http_status_text_native(int status_code)
Returns the canonical reason phrase for one HTTP status code.
Declares HTTP logging and response formatting helpers.
void native_send_text_response(NativeConnection *connection, int status, const char *status_text, const char *body)
Sends a plain-text HTTP response with explicit content length.
int native_connection_printf(NativeConnection *connection, const char *format,...)
Writes formatted bytes to a native connection.
Declares native HTTP response writing helpers.
#define native_static_serve_strdup
int native_serve_static_file(NativeConnection *connection, const char *root, const char *path, const HttpRequest *request, const char *log_path)
Serves one static artifact response from a root directory.
Declares native static artifact serving helpers.
char * path_join(const char *left, const char *right)
Joins two path segments using the native path separator.
char * dup_range(const char *start, size_t len)
Duplicates a byte range into a newly allocated NUL-terminated string.
int path_is_directory(const char *path)
Tests whether a filesystem path refers to a directory.
int starts_with(const char *value, const char *prefix)
Tests whether one string starts with another string.
int path_exists(const char *path)
Tests whether a filesystem path currently exists.
Declares shared low-level support helpers used across the Pharos native runtime.
Parsed HTTP request fields extracted from a native connection.
Accepted client connection and its resolved transport metadata.