readme.md and implementation.md
This commit is contained in:
149
include/ginxsom.h
Normal file
149
include/ginxsom.h
Normal file
@@ -0,0 +1,149 @@
|
||||
#ifndef GINXSOM_H
|
||||
#define GINXSOM_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <fcgi_stdio.h>
|
||||
#include <sqlite3.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/obj_mac.h>
|
||||
|
||||
/* Constants */
|
||||
#define GINXSOM_VERSION "0.1.0"
|
||||
#define MAX_PATH_LEN 4096
|
||||
#define MAX_CONFIG_LINE 1024
|
||||
#define SHA256_HEX_LEN 64
|
||||
#define SHA256_DIGEST_LEN 32
|
||||
#define MAX_PUBKEY_HEX_LEN 64
|
||||
#define MAX_MIME_TYPE_LEN 128
|
||||
#define MAX_FILENAME_LEN 256
|
||||
#define MAX_CONTENT_LEN 1024
|
||||
#define DEFAULT_MAX_FILE_SIZE (100 * 1024 * 1024) // 100MB
|
||||
#define DEFAULT_MAX_BLOBS_PER_USER 1000
|
||||
#define DEFAULT_RATE_LIMIT 10
|
||||
|
||||
/* Error codes */
|
||||
typedef enum {
|
||||
GINXSOM_OK = 0,
|
||||
GINXSOM_ERROR = -1,
|
||||
GINXSOM_ERROR_CONFIG = -2,
|
||||
GINXSOM_ERROR_DB = -3,
|
||||
GINXSOM_ERROR_AUTH = -4,
|
||||
GINXSOM_ERROR_STORAGE = -5,
|
||||
GINXSOM_ERROR_MEMORY = -6,
|
||||
GINXSOM_ERROR_INVALID_REQUEST = -7,
|
||||
GINXSOM_ERROR_FILE_TOO_LARGE = -8,
|
||||
GINXSOM_ERROR_RATE_LIMIT = -9,
|
||||
GINXSOM_ERROR_NOT_FOUND = -10
|
||||
} ginxsom_error_t;
|
||||
|
||||
/* Configuration structure */
|
||||
typedef struct {
|
||||
char socket_path[MAX_PATH_LEN];
|
||||
size_t max_file_size;
|
||||
char storage_path[MAX_PATH_LEN];
|
||||
char database_path[MAX_PATH_LEN];
|
||||
|
||||
bool require_auth_upload;
|
||||
bool require_auth_get;
|
||||
bool require_auth_list;
|
||||
|
||||
int max_blobs_per_user;
|
||||
int rate_limit_uploads;
|
||||
} ginxsom_config_t;
|
||||
|
||||
/* Blob descriptor structure */
|
||||
typedef struct {
|
||||
char sha256[SHA256_HEX_LEN + 1];
|
||||
char pubkey[MAX_PUBKEY_HEX_LEN + 1];
|
||||
size_t size;
|
||||
char mime_type[MAX_MIME_TYPE_LEN];
|
||||
time_t uploaded;
|
||||
char filename[MAX_FILENAME_LEN];
|
||||
} ginxsom_blob_t;
|
||||
|
||||
/* Nostr event structure */
|
||||
typedef struct {
|
||||
char id[SHA256_HEX_LEN + 1];
|
||||
char pubkey[MAX_PUBKEY_HEX_LEN + 1];
|
||||
int kind;
|
||||
char content[MAX_CONTENT_LEN];
|
||||
time_t created_at;
|
||||
time_t expiration;
|
||||
char verb[16]; // t tag value: get, upload, list, delete
|
||||
char x_hashes[10][SHA256_HEX_LEN + 1]; // x tag values (up to 10)
|
||||
int x_count;
|
||||
char server[MAX_PATH_LEN]; // server tag value
|
||||
char signature[128];
|
||||
} nostr_event_t;
|
||||
|
||||
/* FastCGI context structure */
|
||||
typedef struct {
|
||||
ginxsom_config_t config;
|
||||
sqlite3 *db;
|
||||
char *request_method;
|
||||
char *request_uri;
|
||||
char *content_type;
|
||||
char *content_length_str;
|
||||
size_t content_length;
|
||||
char *authorization;
|
||||
} ginxsom_context_t;
|
||||
|
||||
/* Function declarations */
|
||||
|
||||
/* config.c */
|
||||
int ginxsom_load_config(const char *config_path, ginxsom_config_t *config);
|
||||
void ginxsom_config_init_defaults(ginxsom_config_t *config);
|
||||
|
||||
/* database.c */
|
||||
int ginxsom_db_init(sqlite3 **db, const char *db_path);
|
||||
int ginxsom_db_close(sqlite3 *db);
|
||||
int ginxsom_db_store_blob(sqlite3 *db, const ginxsom_blob_t *blob);
|
||||
int ginxsom_db_delete_blob(sqlite3 *db, const char *sha256, const char *pubkey);
|
||||
int ginxsom_db_list_blobs(sqlite3 *db, const char *pubkey, ginxsom_blob_t **blobs, int *count);
|
||||
int ginxsom_db_blob_exists(sqlite3 *db, const char *sha256);
|
||||
int ginxsom_db_get_user_blob_count(sqlite3 *db, const char *pubkey);
|
||||
|
||||
/* auth.c */
|
||||
int ginxsom_parse_auth_header(const char *auth_header, nostr_event_t *event);
|
||||
int ginxsom_verify_nostr_event(const nostr_event_t *event);
|
||||
int ginxsom_validate_auth_for_upload(const nostr_event_t *event, const char *sha256);
|
||||
int ginxsom_validate_auth_for_delete(const nostr_event_t *event, const char *sha256);
|
||||
int ginxsom_validate_auth_for_list(const nostr_event_t *event);
|
||||
|
||||
/* storage.c */
|
||||
int ginxsom_store_blob(const char *storage_path, const char *sha256,
|
||||
const char *data, size_t size, const char *mime_type);
|
||||
int ginxsom_delete_blob(const char *storage_path, const char *sha256);
|
||||
char *ginxsom_detect_mime_type(const char *data, size_t size);
|
||||
int ginxsom_calculate_sha256(const char *data, size_t size, char *sha256_hex);
|
||||
|
||||
/* server.c */
|
||||
int ginxsom_handle_upload(ginxsom_context_t *ctx);
|
||||
int ginxsom_handle_upload_head(ginxsom_context_t *ctx);
|
||||
int ginxsom_handle_list(ginxsom_context_t *ctx, const char *pubkey);
|
||||
int ginxsom_handle_delete(ginxsom_context_t *ctx, const char *sha256);
|
||||
void ginxsom_send_response(int status, const char *content_type,
|
||||
const char *body, size_t body_len);
|
||||
void ginxsom_send_error(int status, const char *reason);
|
||||
|
||||
/* utils.c */
|
||||
char *ginxsom_read_request_body(size_t content_length);
|
||||
int ginxsom_hex_to_bytes(const char *hex, unsigned char *bytes, size_t bytes_len);
|
||||
void ginxsom_bytes_to_hex(const unsigned char *bytes, size_t bytes_len, char *hex);
|
||||
int ginxsom_parse_query_params(const char *query_string, char *params[][2], int max_params);
|
||||
char *ginxsom_url_decode(const char *encoded);
|
||||
int ginxsom_create_directory(const char *path);
|
||||
|
||||
#endif /* GINXSOM_H */
|
||||
Reference in New Issue
Block a user