ascii-chat
Binary v0.15.83-53-gb711d8720
Library lib/v0.3.2-701-gb711d8720
Video chat in your terminal
Loading...
Searching...
No Matches
server_internal.h File Reference

Go to the source code of this file.

Typedefs

typedef asciichat_error_t(* http3_submit_response_fn) (void *context, unsigned status, const http_header_t *headers, size_t header_count, const void *body, size_t body_length)

Functions

size_t http_server_max_request_body (const http_server_t *server)
size_t http_server_max_response_body (const http_server_t *server)
void http_server_invalidate_http3_context (http_server_t *server, void *context)
asciichat_error_t http_server_dispatch_http3 (http_server_t *server, const char *method, const char *path, const http_header_t *headers, size_t header_count, const void *body, size_t body_length, const char *peer_address, http3_submit_response_fn submit, void *submit_context)

Typedef Documentation

◆ http3_submit_response_fn

typedef asciichat_error_t(* http3_submit_response_fn) (void *context, unsigned status, const http_header_t *headers, size_t header_count, const void *body, size_t body_length)

Definition at line 5 of file server_internal.h.

Function Documentation

◆ http_server_dispatch_http3()

asciichat_error_t http_server_dispatch_http3 ( http_server_t * server,
const char * method,
const char * path,
const http_header_t * headers,
size_t header_count,
const void * body,
size_t body_length,
const char * peer_address,
http3_submit_response_fn submit,
void * submit_context )

Definition at line 793 of file lib/network/http/server/server.c.

796 {
797 if (!server || !method || !path || (header_count && !headers) || (!body && body_length) || !submit ||
798 body_length > server->config.max_request_body_bytes)
799 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid HTTP/3 request");
800 char path_copy[2048];
801 if (strlen(path) >= sizeof(path_copy))
802 return SET_ERRNO(ERROR_NETWORK_SIZE, "HTTP/3 request path is too long");
803 platform_strncpy(path_copy, sizeof(path_copy), path, sizeof(path_copy) - 1);
804 char *query = strchr(path_copy, '?');
805 if (query)
806 *query++ = 0;
807 http_request_t request = {0};
808 request.info = (http_request_info_t){.method = method,
809 .path = path_copy,
810 .query = query,
811 .protocol = HTTP_PROTOCOL_3,
812 .headers = headers,
813 .header_count = header_count,
814 .peer_address = peer_address,
815 .user_data = server->config.user_data};
816 request.storage = (char *)body;
817 request.body_length = body_length;
819 const char *peer = peer_address ? peer_address : "unknown";
820 bool allowed = false;
821 if (rate_limiter_check(server->rate_limiter, peer, RATE_EVENT_HTTP_REQUEST, &server->request_rate_limit, &allowed) !=
822 ASCIICHAT_OK ||
823 !allowed) {
825 http_response_t limited = {.server = server,
826 .protocol = HTTP_PROTOCOL_3,
827 .status = 429,
828 .max_body_length = http_max_response_body(server),
829 .http3_submit = submit,
830 .http3_context = submit_context};
831 return http_response_finish(&limited);
832 }
836 uint64_t request_start = time_get_ns();
837 if (!http_request_admit(server)) {
838 http_response_t limited = {.server = server,
839 .protocol = HTTP_PROTOCOL_3,
840 .status = 429,
841 .max_body_length = http_max_response_body(server),
842 .http3_submit = submit,
843 .http3_context = submit_context};
844 return http_response_finish(&limited);
845 }
846 http_response_t response = {.server = server,
847 .protocol = HTTP_PROTOCOL_3,
848 .status = 200,
849 .max_body_length = http_max_response_body(server),
850 .inflight_accounted = true,
851 .http3_submit = submit,
852 .http3_context = submit_context};
853 ASCII_OTEL_SCOPE(HTTP);
854 ASCII_OTEL_ATTR_STRING("http.method", method);
855 ASCII_OTEL_ATTR_STRING("http.route", request.info.path);
856 ASCII_OTEL_ATTR_STRING("http.protocol", "3");
857 ASCII_OTEL_ATTR_STRING("http.backend", "quic-ngtcp2-nghttp3");
858 if (http_server_authorize(&server->config.basic_auth, &request.info, &response))
859 server->config.on_request(&request, &response, server->config.user_data);
860 if (!response.finished && !response.deferred) {
861 asciichat_error_t result = http_response_finish(&response);
862 ASCII_OTEL_ATTR_INT("http.status", response.status);
863 ASCII_OTEL_ATTR_INT("http.response_bytes", (int64_t)response.body_length);
866 if (result == ASCIICHAT_OK && response.protocol == HTTP_PROTOCOL_3)
868 SAFE_FREE(response.body);
869 return result;
870 }
873 SAFE_FREE(response.body);
874 return ASCIICHAT_OK;
875}
#define SET_ERRNO(code,...)
bool http_server_authorize(const http_basic_auth_config_t *config, const struct http_request_info *request, struct http_response *response)
Definition basic_auth.c:119
#define SAFE_FREE(ptr)
Definition common.h:377
unsigned long long uint64_t
Definition common.h:63
asciichat_error_t
Error and exit codes - unified status values (0-255).
Definition error_codes.h:44
@ ASCIICHAT_OK
Definition error_codes.h:46
@ ERROR_NETWORK_SIZE
Definition error_codes.h:77
@ ERROR_INVALID_PARAM
struct http_request http_request_t
struct http_request_info http_request_info_t
struct http_response http_response_t
@ STATS_COUNTER_HTTP_BYTES_RECEIVED
@ STATS_GAUGE_HTTP_STREAMS_ACTIVE
asciichat_error_t http_response_finish(http_response_t *r)
void stats_counter_add(stats_scope_t *scope, stats_counter_id_t id, uint64_t amount)
void stats_duration_record(stats_scope_t *scope, stats_duration_id_t id, uint64_t elapsed_ns)
void stats_gauge_set(stats_scope_t *scope, stats_gauge_id_t id, uint64_t value)
#define ASCII_OTEL_SCOPE(id)
Definition otel.h:72
#define ASCII_OTEL_ATTR_INT(key, value)
Definition otel.h:67
#define ASCII_OTEL_ATTR_STRING(key, value)
Definition otel.h:66
asciichat_error_t rate_limiter_record(rate_limiter_t *limiter, const char *ip_address, rate_event_type_t event_type)
Record a rate limit event.
Definition rate_limit.c:162
asciichat_error_t rate_limiter_check(rate_limiter_t *limiter, const char *ip_address, rate_event_type_t event_type, const rate_limit_config_t *config, bool *allowed)
Check if an event from an IP address should be rate limited.
Definition rate_limit.c:138
@ RATE_EVENT_HTTP_REQUEST
HTTP requests from a client identity.
Definition rate_limit.h:61
stats_scope_t * stats_runtime_scope(void)
Definition runtime.c:80
http_server_config_t config
rate_limiter_t * rate_limiter
rate_limit_config_t request_rate_limit

References ASCII_OTEL_ATTR_INT, ASCII_OTEL_ATTR_STRING, ASCII_OTEL_SCOPE, ASCIICHAT_OK, http_server_config_t::basic_auth, http_response::body, http_request::body_length, http_response::body_length, http_server::config, http_response::deferred, ERROR_INVALID_PARAM, ERROR_NETWORK_SIZE, http_response::finished, HTTP_PROTOCOL_3, http_response_finish(), http_server_authorize(), http_request::info, http_server_config_t::max_request_body_bytes, http_server_config_t::on_request, http_request_info::path, http_response::protocol, RATE_EVENT_HTTP_REQUEST, http_server::rate_limiter, rate_limiter_check(), rate_limiter_record(), http_server::request_rate_limit, SAFE_FREE, SET_ERRNO, stats_counter_add(), STATS_COUNTER_HTTP_BYTES_RECEIVED, STATS_COUNTER_HTTP_BYTES_SENT, STATS_COUNTER_HTTP_REJECTED, STATS_COUNTER_HTTP_REQUESTS, STATS_DURATION_HTTP_REQUEST, stats_duration_record(), STATS_GAUGE_HTTP_STREAMS_ACTIVE, stats_gauge_set(), stats_runtime_scope(), http_response::status, http_request::storage, and http_server_config_t::user_data.

◆ http_server_invalidate_http3_context()

void http_server_invalidate_http3_context ( http_server_t * server,
void * context )

Definition at line 138 of file lib/network/http/server/server.c.

138 {
139 if (!server || !context)
140 return;
141 mutex_lock(&server->response_mutex);
142 for (http_response_t *response = server->retained_responses; response; response = response->next_retained) {
143 if (response->http3_context == context) {
144 response->http3_submit = NULL;
145 response->http3_context = NULL;
146 response->cancelled = true;
147 }
148 }
149 mutex_unlock(&server->response_mutex);
150}
http_response_t * retained_responses

References http_response::next_retained, http_server::response_mutex, and http_server::retained_responses.

Referenced by http_server_http3_destroy().

◆ http_server_max_request_body()

size_t http_server_max_request_body ( const http_server_t * server)

Definition at line 885 of file lib/network/http/server/server.c.

885 {
886 return server ? server->config.max_request_body_bytes : 0;
887}

References http_server::config, and http_server_config_t::max_request_body_bytes.

◆ http_server_max_response_body()

size_t http_server_max_response_body ( const http_server_t * server)

Definition at line 135 of file lib/network/http/server/server.c.

135 {
136 return server ? http_max_response_body(server) : 0;
137}