Mercurial
view seobeo/seobeo_internal.h @ 279:b3b547563ec7
Add Google connector service and agent wiki
Implement the C/Seobeo Google Drive and Gmail connector with encrypted OAuth storage, Zenbu authentication, browser testing, AI tool discovery, chunked HTTP decoding, and Bazel coverage. Consolidate repository guidance into progressive wiki documentation and enforce arena-first allocation for new first-party C code.
Co-authored-by: Copilot <[email protected]>
Copilot-Session: 84c338fd-0939-4bb3-b7f3-1062eb213e5d
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Mon, 17 Aug 2026 22:22:36 -0700 |
| parents | 04fee26ecce0 |
| children |
line wrap: on
line source
#ifndef SEOBEO_SERVER_INTERNAL_H #define SEOBEO_SERVER_INTERNAL_H #ifndef SEOBEO_NO_SSL #include <openssl/ssl.h> #include <openssl/err.h> #define SSL_CTX_TYPE SSL_CTX #define SSL_TYPE SSL #else #define SSL_CTX_TYPE void #define SSL_TYPE void #endif // For web socket usages as body length are determine this... #define MAX_INT_16 65536 #define MAX_FRAGMENT_SIZE 1024 * 1024 #include "dowa/dowa.h" #include <stdatomic.h> typedef enum { SEOBEO_STREAM_TYPE_SERVER, SEOBEO_STREAM_TYPE_CLIENT, } Seobeo_SocketType; typedef struct { int32 socket; Seobeo_SocketType type; boolean connected; char *host; char *port; SSL_CTX_TYPE *ssl_ctx; SSL_TYPE *ssl; uint8 *read_buffer; uint32 read_buffer_capacity; uint32 read_buffer_len; // current size uint32 read_buffer_used; // TODO: Implement this for client uint8 *write_buffer; uint32 write_buffer_capacity; uint32 write_buffer_len; // current size void *file; void *text_copy; char *file_name; atomic_bool destroyed; // Keep-alive support time_t last_activity; // Timestamp of last request/response boolean keep_alive; // Whether this connection should be kept alive boolean is_sse; // SSE takeover; edge loop only watches disconnects } Seobeo_Handle; // Cached file entry with content and size (for binary file support) typedef struct { char *content; size_t size; } Seobeo_Cached_File; // HTML cache type: maps file paths (char*) to cached file entries (Seobeo_Cached_File*) typedef Dowa_KV(char*, Seobeo_Cached_File*) Seobeo_Cache_Entry; typedef struct { Seobeo_Handle *srv; Seobeo_Cache_Entry *cache; } WorkerArgs; typedef enum { SEOBEO_MODE_FORK, SEOBEO_MODE_EDGE, } Seobeo_ServerMode; // HTTP request map type: maps header names to header values typedef Dowa_KV(char*, char*) Seobeo_Request_Entry; typedef struct Seobeo_SSE_Stream { Seobeo_Handle *p_handle; char *path; void *p_pending_frames; size_t pending_offset; atomic_uint ref_count; boolean started; boolean closed; boolean managed; /* Optional client-disconnect callback. Called from * Seobeo_SSE_Server_Detach_Handle AFTER g_sse_mutex is released so that * the callback may safely acquire its own locks. */ void (*detach_cb)(struct Seobeo_SSE_Stream *, void *); void *detach_ctx; } Seobeo_SSE_Stream; typedef struct { const char *event; const char *id; const char *data; int32 retry_ms; } Seobeo_SSE_Event; // --- Router Types --- // // Forward declaration typedef struct Seobeo_Route_Struct Seobeo_Route; // Route handler function type typedef Seobeo_Request_Entry* (*Seobeo_Route_Handler)( Seobeo_Request_Entry *p_request_map, Dowa_Arena *p_arena ); // Streaming handler - gets direct access to client handle for streaming responses typedef void (*Seobeo_Stream_Handler)( Seobeo_Handle *p_client_handle, Seobeo_Request_Entry *p_request_map, Dowa_Arena *p_arena ); typedef void (*Seobeo_SSE_Handler)( Seobeo_SSE_Stream *p_stream, Seobeo_Request_Entry *p_request_map, Dowa_Arena *p_arena ); extern Seobeo_SSE_Stream *Seobeo_SSE_Server_Attach( Seobeo_Handle *p_handle, const char *path); extern void Seobeo_SSE_Server_Detach_Handle(Seobeo_Handle *p_handle); extern void Seobeo_SSE_Server_Destroy(void); // --- Parse Header into Dowa Map ---// extern int Seobeo_Web_Header_Parse(Seobeo_Handle *p_handle, Seobeo_Request_Entry **pp_map, Dowa_Arena *p_arena); // --- Handle Request --- // /* Handle a client request. Returns TRUE if connection should be kept alive. */ extern boolean Seobeo_Web_ClientHandle_Request(Seobeo_Handle *p_cli_handle, Seobeo_Cache_Entry *p_html_cache, boolean use_keep_alive); extern boolean Seobeo_Web_Server_Is_Stopping(void); // --- SSL --- // extern void Seobeo_Web_SSL_Init(); extern void Seobeo_Web_SSL_Cleanup(); // Not used extern int Seobeo_SSL_Setup_Client(Seobeo_Handle *p_handle, const char *host, int socket_fd); extern void Seobeo_SSL_Cleanup(Seobeo_Handle *p_handle); extern int32 Seobeo_SSL_Write(Seobeo_Handle *p_handle, const uint8 *data, uint32 length); extern int32 Seobeo_SSL_Read(Seobeo_Handle *p_handle, uint8 *buffer, uint32 length); // --- Serving using Edge --- // extern void *Seobeo_Web_Edge_Worker(void *vargs); extern void Seobeo_Web_Edge(Seobeo_Handle *p_server_handle, int thread_count, Seobeo_Cache_Entry *p_html_cache); // --- HTTP Client Types --- // typedef struct { char *method; char *url; char *host; char *port; char *path; boolean use_tls; // Headers can be either HashMap or Array Seobeo_Request_Entry *headers_map; char **headers_array; char *body; size_t body_length; boolean follow_redirects; int32 max_redirects; int32 timeout_ms; char *download_path; Dowa_Arena *p_arena; } Seobeo_Client_Request; typedef struct { int32 status_code; char *status_text; Seobeo_Request_Entry *headers; char *body; size_t body_length; char *redirect_url; Dowa_Arena *p_arena; } Seobeo_Client_Response; // --- HTTP Client Functions --- // extern Seobeo_Client_Request *Seobeo_Client_Request_Create(const char *url); extern void Seobeo_Client_Request_Set_Method(Seobeo_Client_Request *p_req, const char *method); extern void Seobeo_Client_Request_Add_Header_Map(Seobeo_Client_Request *p_req, const char *key, const char *value); extern void Seobeo_Client_Request_Add_Header_Array(Seobeo_Client_Request *p_req, const char *header); extern void Seobeo_Client_Request_Set_Body(Seobeo_Client_Request *p_req, const char *body, size_t length); extern void Seobeo_Client_Request_Set_Follow_Redirects(Seobeo_Client_Request *p_req, boolean follow, int32 max_redirects); extern void Seobeo_Client_Request_Set_Timeout_Milliseconds(Seobeo_Client_Request *p_req, int32 timeout_ms); extern void Seobeo_Client_Request_Set_Download_Path(Seobeo_Client_Request *p_req, const char *path); extern Seobeo_Client_Response *Seobeo_Client_Request_Execute(Seobeo_Client_Request *p_req); extern void Seobeo_Client_Request_Destroy(Seobeo_Client_Request *p_req); extern void Seobeo_Client_Response_Destroy(Seobeo_Client_Response *p_resp); // --- WebSocket Types --- // typedef enum { SEOBEO_WS_OPCODE_CONTINUATION = 0x0, SEOBEO_WS_OPCODE_TEXT = 0x1, SEOBEO_WS_OPCODE_BINARY = 0x2, SEOBEO_WS_OPCODE_CLOSE = 0x8, SEOBEO_WS_OPCODE_PING = 0x9, SEOBEO_WS_OPCODE_PONG = 0xA } Seobeo_WebSocket_Opcode; typedef enum { SEOBEO_WS_STATE_CONNECTING = 0, SEOBEO_WS_STATE_OPEN, SEOBEO_WS_STATE_CLOSING, SEOBEO_WS_STATE_CLOSED } Seobeo_WebSocket_State; typedef struct { Seobeo_WebSocket_Opcode opcode; uint8 *data; size_t length; boolean is_final; } Seobeo_WebSocket_Message; typedef struct { Seobeo_Handle *p_handle; char *url; char *host; char *port; char *path; boolean use_tls; Seobeo_WebSocket_State state; uint8 *fragment_buffer; size_t fragment_length; size_t fragment_capacity; Seobeo_WebSocket_Opcode fragment_opcode; Dowa_Arena *p_arena; } Seobeo_WebSocket; // --- WebSocket Common Functions --- // extern void Seobeo_WebSocket_Mask_Data(uint8 *data, size_t length, const uint8 *mask); extern void Seobeo_WebSocket_Message_Destroy(Seobeo_WebSocket_Message *p_msg); // --- WebSocket Client Functions --- // extern Seobeo_WebSocket *Seobeo_WebSocket_Connect(const char *url); extern int32 Seobeo_WebSocket_Send_Text(Seobeo_WebSocket *p_ws, const char *text); extern int32 Seobeo_WebSocket_Send_Binary(Seobeo_WebSocket *p_ws, const uint8 *data, size_t length); extern int32 Seobeo_WebSocket_Send_Ping(Seobeo_WebSocket *p_ws, const char *payload); extern int32 Seobeo_WebSocket_Send_Pong(Seobeo_WebSocket *p_ws, const char *payload); extern Seobeo_WebSocket_Message *Seobeo_WebSocket_Receive(Seobeo_WebSocket *p_ws); extern int32 Seobeo_WebSocket_Close(Seobeo_WebSocket *p_ws, uint16 code, const char *reason); extern void Seobeo_WebSocket_Destroy(Seobeo_WebSocket *p_ws); // --- WebSocket Server Types --- // typedef struct Seobeo_WebSocket_Server_Connection_Struct Seobeo_WebSocket_Server_Connection; struct Seobeo_WebSocket_Server_Connection_Struct { Seobeo_Handle *p_handle; char *client_id; boolean is_active; uint8 *fragment_buffer; size_t fragment_length; size_t fragment_capacity; Seobeo_WebSocket_Opcode fragment_opcode; Seobeo_WebSocket_Server_Connection *next; }; typedef void (*Seobeo_WebSocket_Server_Handler)( Seobeo_WebSocket_Server_Connection *p_conn, Seobeo_WebSocket_Message *p_msg, void *p_user_data ); typedef struct { char *path; Seobeo_WebSocket_Server_Handler handler; void *p_user_data; } Seobeo_WebSocket_Server_Route; // --- WebSocket Server Functions --- // extern void Seobeo_WebSocket_Server_Init(); extern void Seobeo_WebSocket_Server_Register(const char *path, Seobeo_WebSocket_Server_Handler handler, void *p_user_data); extern boolean Seobeo_WebSocket_Server_Handle_Upgrade(Seobeo_Handle *p_handle, Seobeo_Request_Entry *p_req_map, const char *path); extern void Seobeo_WebSocket_Server_Handle_Connection(Seobeo_WebSocket_Server_Connection *p_conn); extern int32 Seobeo_WebSocket_Server_Send_Text(Seobeo_WebSocket_Server_Connection *p_conn, const char *text); extern int32 Seobeo_WebSocket_Server_Send_Binary(Seobeo_WebSocket_Server_Connection *p_conn, const uint8 *data, size_t length); extern void Seobeo_WebSocket_Server_Broadcast_Text(const char *text, Seobeo_WebSocket_Server_Connection *origin_p_conn); extern void Seobeo_WebSocket_Server_Broadcast_Binary(const uint8 *data, size_t length); extern void Seobeo_WebSocket_Server_Connection_Close(Seobeo_WebSocket_Server_Connection *p_conn, uint16 code, const char *reason); extern void Seobeo_WebSocket_Server_Connection_Destroy(Seobeo_WebSocket_Server_Connection *p_conn); #endif