view seobeo/seobeo.h @ 112:d6d578b49a19

[PostDog] Got CRUD working.
author June Park <parkjune1995@gmail.com>
date Sun, 04 Jan 2026 11:38:44 -0800
parents 70401cf61e97
children c39582f937e5
line wrap: on
line source

#ifndef SEOBEO_SERVER_H
#define SEOBEO_SERVER_H

/**
 * Seobeo
 * ------
 *
 * Library for starting TCP, UDP server and serving static file or path.
 */

#include "seobeo/seobeo_internal.h"

/* Included in dowa
  #include <stdio.h>
  #include <stdlib.h>
*/
#include <stdarg.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#include <fcntl.h>
#include <pthread.h>


#define INITIAL_BUFFER_CAPACITY 4096

// HTTP STATUS CODE
#define HTTP_OK 200
#define HTTP_CREATED 201
#define HTTP_MOVED_PERMANENTLY 301
#define HTTP_FOUND 302
#define HTTP_BAD_REQUEST 400
#define HTTP_UNAUTHORIZED 401
#define HTTP_FORBIDDEN 403
#define HTTP_NOT_FOUND 404
#define HTTP_INTERNAL_ERROR 500

#define CREATE_REDIRECT_HANDLER(name, target_url) \
Seobeo_Request_Entry* GetRedirect##name(Seobeo_Request_Entry *req, Dowa_Arena *arena) \
{ \
  Seobeo_Request_Entry *resp = NULL; \
  Dowa_HashMap_Push_Arena(resp, "status", "301", arena); \
  Dowa_HashMap_Push_Arena(resp, "content-type", "text/plain", arena); \
  Dowa_HashMap_Push_Arena(resp, "Body", "", arena); \
  Dowa_HashMap_Push_Arena(resp, "Location", target_url, arena); \
  return resp; \
}

extern volatile sig_atomic_t stop_server;

// --- TCP --- //
// --- Generate a Server Handle. ---//
extern Seobeo_Handle *Seobeo_Stream_Handle_Server_Create(const char *host,  const char* port);
// --- Generate a Client Handle. ---//
extern Seobeo_Handle *Seobeo_Stream_Handle_Client_Create(const char *host,  const char* port, boolean use_tls);
// --- Generate a Client Handle from given Server Handle. ---//
extern Seobeo_Handle *Seobeo_Stream_Handle_Server_Accept(Seobeo_Handle *p_server_handle);

// --- Web --- //
/* Generate HTTP 1.1 Header value with given content_types and length. */
extern void           Seobeo_Web_Header_Generate(void *buffer, int status, const char *content_type, const int content_length);
/* Start a Generic HTTP static file server with given folder. It will store folder into memory. */
extern int            Seobeo_Web_Server_Start(const char *folder_path, const char *port, Seobeo_ServerMode mode, int thread_count);
/* Generic HTTP GET Rquest to given host and port with path. It will mimic chrome. */
extern int            Seobeo_Web_Client_Get(const char *host, const char *port, const char *path);
/* Initialize the router system (called automatically by Seobeo_Web_Server_Start) */
extern void           Seobeo_Router_Init();
/* Register an API route handler. Call before starting server. */
extern void           Seobeo_Router_Register(const char *method, const char *path_pattern, Seobeo_Route_Handler handler);
/* Clean up router resources */
extern void           Seobeo_Router_Destroy();
/* Find matching route handler (internal use) */
extern Seobeo_Route_Handler Seobeo_Router_Find_Handler(const char *method, const char *path, Seobeo_Request_Entry **pp_request_map, Dowa_Arena *p_arena);
/* Send HTTP response from response map (internal use) */
extern void           Seobeo_Router_Send_Response(Seobeo_Handle *p_handle, Seobeo_Request_Entry *p_response_map, Dowa_Arena *p_arena);
extern char          *Seobeo_Web_LoadFile(const char *file_path, size_t *p_file_size);

// --- Helper functions --- //
/* Destroy handle. It will handle all NULL poointers. */
extern void           Seobeo_Handle_Destroy(Seobeo_Handle *p_handle);
/* Write to socket from write_buffer in the handle. */
extern int            Seobeo_Handle_Flush(Seobeo_Handle *p_handle); 
/* Write to socket with given data source, if the data source is bigger than the write buffer for handle then we just directly write from the data source. */
extern int            Seobeo_Handle_Queue(Seobeo_Handle *p_handle, const uint8_t *data, uint32_t data_size); 
/* Read to socket from read_buffer in the handle. */
extern int            Seobeo_Handle_Read(Seobeo_Handle *p_handle); 
/* Move to read_buffer to front and we already consumed the given amount in the handle. */
extern void           Seobeo_Handle_Consume(Seobeo_Handle *p_handle, uint32 consumed);
/* Assign IP4 or IP6 to sockaddr. TODO: Maybe create my own struct for this? */
extern void          *Seobeo_Get_IP4_Or_IP6(struct sockaddr *sa);
/* Logging */
typedef enum {
  SEOBEO_INFO = 0,
  SEOBEO_WARNING,
  SEOBEO_ERROR,
  SEOBEO_DEBUG,
} Seobeo_Log_Level;
extern int            Seobeo_Log(Seobeo_Log_Level level, const char *format, ...);
#endif