view seobeo/seobeo_internal.h @ 124:dbf14f84d51c

Refactor Seobeo and mrjunejune build files so it works.
author June Park <parkjune1995@gmail.com>
date Thu, 08 Jan 2026 07:31:32 -0800
parents 7b1719fa918c
children f236c895604e
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;
} Seobeo_Handle;

// HTML cache type: maps file paths (char*) to file contents (char*)
typedef Dowa_KV(char*, char*) 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;

// --- 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
);

// --- 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 --- //
extern void           Seobeo_Web_HandleClientRequest(Seobeo_Handle *cli, Seobeo_Cache_Entry *p_html_cache);

// --- 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;

  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_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 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 void                      Seobeo_WebSocket_Message_Destroy(Seobeo_WebSocket_Message *p_msg);
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);
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