Refactor for shared library use
This commit is contained in:
23
Makefile
23
Makefile
@ -1,19 +1,28 @@
|
||||
.DEFAULT_GOAL := install
|
||||
|
||||
CFLAGS=-std=c11 -Wall
|
||||
INCLUDE=-lssl -lcrypto -lmagic -lz -lmaxminddb
|
||||
LIBS=src/lib/*.c
|
||||
|
||||
packages:
|
||||
@echo "Installing packages..."
|
||||
sudo apt-get install gcc libmagic-dev libssl-dev php-fpm
|
||||
sudo apt install gcc php-fpm libmagic-dev libssl-dev libmaxminddb-dev
|
||||
@echo "Finished downloading!"
|
||||
|
||||
permit:
|
||||
sudo setcap 'cap_net_bind_service=+ep' "$(shell pwd)/bin/necronda-server"
|
||||
|
||||
compile:
|
||||
@mkdir -p bin
|
||||
gcc src/necronda-server.c -o bin/necronda-server -std=c11 -lssl -lcrypto -lmagic -lz -lmaxminddb -Wall
|
||||
gcc $(LIBS) -o bin/libnecronda-server.so --shared -fPIC $(CFLAGS) $(INCLUDE)
|
||||
gcc src/necronda-server.c -o bin/necronda-server $(CFLAGS) $(INCLUDE) \
|
||||
-Lbin -lnecronda-server \
|
||||
-Wl,-rpath=$(shell pwd)/bin
|
||||
|
||||
compile-debian:
|
||||
@mkdir -p bin
|
||||
gcc src/necronda-server.c -o bin/necronda-server -std=c11 -lssl -lcrypto -lmagic -lz -lmaxminddb -Wall \
|
||||
gcc $(LIBS) -o bin/libnecronda-server.so --shared -fPIC $(CFLAGS) $(INCLUDE)
|
||||
gcc src/necronda-server.c -o bin/necronda-server $(CFLAGS) $(INCLUDE) \
|
||||
-Lbin -lnecronda-server \
|
||||
-Wl,-rpath=$(shell pwd)/bin \
|
||||
-D MAGIC_FILE="\"/usr/share/file/magic.mgc\"" \
|
||||
-D PHP_FPM_SOCKET="\"/var/run/php/php7.3-fpm.sock\""
|
||||
|
||||
install: | packages compile
|
||||
@echo "Finished!"
|
||||
|
25
src/client.c
25
src/client.c
@ -6,7 +6,30 @@
|
||||
*/
|
||||
|
||||
#include "client.h"
|
||||
#include "lib/utils.h"
|
||||
#include "lib/config.h"
|
||||
#include "lib/sock.h"
|
||||
#include "lib/http.h"
|
||||
#include "lib/rev_proxy.h"
|
||||
#include "lib/fastcgi.h"
|
||||
#include "lib/cache.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/select.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#include <signal.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
int server_keep_alive = 1;
|
||||
struct timeval client_timeout = {.tv_sec = CLIENT_TIMEOUT, .tv_usec = 0};
|
||||
|
||||
int server_keep_alive;
|
||||
char *log_client_prefix, *log_conn_prefix, *log_req_prefix, *client_geoip;
|
||||
char *client_addr_str, *client_addr_str_ptr, *server_addr_str, *server_addr_str_ptr, *client_host_str;
|
||||
struct timeval client_timeout;
|
||||
|
||||
host_config *get_host_config(const char *host) {
|
||||
for (int i = 0; i < MAX_HOST_CONFIG; i++) {
|
||||
@ -400,7 +423,7 @@ int client_request_handler(sock *client, unsigned long client_num, unsigned int
|
||||
|
||||
respond:
|
||||
if (!use_rev_proxy) {
|
||||
if (conf->type == CONFIG_TYPE_LOCAL && uri.is_static && res.status->code == 405) {
|
||||
if (conf != NULL && conf->type == CONFIG_TYPE_LOCAL && uri.is_static && res.status->code == 405) {
|
||||
http_add_header_field(&res.hdr, "Allow", "GET, HEAD, TRACE");
|
||||
}
|
||||
if (http_get_header_field(&res.hdr, "Accept-Ranges") == NULL) {
|
||||
|
15
src/client.h
15
src/client.h
@ -8,16 +8,11 @@
|
||||
#ifndef NECRONDA_SERVER_CLIENT_H
|
||||
#define NECRONDA_SERVER_CLIENT_H
|
||||
|
||||
#include "necronda-server.h"
|
||||
#include "utils.h"
|
||||
#include "uri.h"
|
||||
#include "http.h"
|
||||
#include "fastcgi.h"
|
||||
#include <sys/time.h>
|
||||
|
||||
|
||||
int server_keep_alive = 1;
|
||||
char *log_client_prefix, *log_conn_prefix, *log_req_prefix, *client_geoip;
|
||||
|
||||
struct timeval client_timeout = {.tv_sec = CLIENT_TIMEOUT, .tv_usec = 0};
|
||||
extern int server_keep_alive;
|
||||
extern char *log_client_prefix, *log_conn_prefix, *log_req_prefix, *client_geoip;
|
||||
extern char *client_addr_str, *client_addr_str_ptr, *server_addr_str, *server_addr_str_ptr, *client_host_str;
|
||||
extern struct timeval client_timeout;
|
||||
|
||||
#endif //NECRONDA_SERVER_CLIENT_H
|
||||
|
@ -1,12 +1,26 @@
|
||||
/**
|
||||
* Necronda Web Server
|
||||
* File cache implementation
|
||||
* src/cache.c
|
||||
* src/lib/cache.c
|
||||
* Lorenz Stechauner, 2020-12-19
|
||||
*/
|
||||
|
||||
#include "cache.h"
|
||||
#include "utils.h"
|
||||
#include "../necronda-server.h"
|
||||
#include <stdio.h>
|
||||
#include <zlib.h>
|
||||
#include <magic.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <openssl/sha.h>
|
||||
|
||||
int cache_continue = 1;
|
||||
magic_t magic;
|
||||
cache_entry *cache;
|
||||
|
||||
int magic_init() {
|
||||
magic = magic_open(MAGIC_MIME);
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* Necronda Web Server
|
||||
* File cache implementation (header file)
|
||||
* src/cache.h
|
||||
* src/lib/cache.h
|
||||
* Lorenz Stechauner, 2020-12-19
|
||||
*/
|
||||
|
||||
@ -10,15 +10,6 @@
|
||||
|
||||
#include "uri.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <zlib.h>
|
||||
#include <magic.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
|
||||
|
||||
magic_t magic;
|
||||
|
||||
typedef struct {
|
||||
char filename[256];
|
||||
unsigned char webroot_len;
|
||||
@ -26,9 +17,9 @@ typedef struct {
|
||||
meta_data meta;
|
||||
} cache_entry;
|
||||
|
||||
cache_entry *cache;
|
||||
extern cache_entry *cache;
|
||||
|
||||
int cache_continue = 1;
|
||||
extern int cache_continue;
|
||||
|
||||
int magic_init();
|
||||
|
@ -1,12 +1,22 @@
|
||||
/**
|
||||
* Necronda Web Server
|
||||
* Configuration file loader
|
||||
* src/config.c
|
||||
* src/lib/config.c
|
||||
* Lorenz Stechauner, 2021-01-05
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "../necronda-server.h"
|
||||
#include <stdio.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <malloc.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
host_config *config;
|
||||
char cert_file[256], key_file[256], geoip_dir[256], dns_server[256];
|
||||
|
||||
int config_init() {
|
||||
int shm_id = shmget(SHM_KEY_CONFIG, MAX_HOST_CONFIG * sizeof(host_config), IPC_CREAT | IPC_EXCL | 0640);
|
@ -1,25 +1,19 @@
|
||||
/**
|
||||
* Necronda Web Server
|
||||
* Configuration file loader (header file)
|
||||
* src/config.h
|
||||
* src/lib/config.h
|
||||
* Lorenz Stechauner, 2021-01-05
|
||||
*/
|
||||
|
||||
|
||||
#ifndef NECRONDA_SERVER_CONFIG_H
|
||||
#define NECRONDA_SERVER_CONFIG_H
|
||||
|
||||
#include "uri.h"
|
||||
|
||||
#define CONFIG_TYPE_UNSET 0
|
||||
#define CONFIG_TYPE_LOCAL 1
|
||||
#define CONFIG_TYPE_REVERSE_PROXY 2
|
||||
|
||||
#include "uri.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
int type;
|
||||
char name[256];
|
||||
@ -36,10 +30,8 @@ typedef struct {
|
||||
};
|
||||
} host_config;
|
||||
|
||||
|
||||
host_config *config;
|
||||
char cert_file[256], key_file[256], geoip_dir[256], dns_server[256];
|
||||
|
||||
extern host_config *config;
|
||||
extern char cert_file[256], key_file[256], geoip_dir[256], dns_server[256];
|
||||
|
||||
int config_init();
|
||||
|
@ -1,12 +1,19 @@
|
||||
/**
|
||||
* Necronda Web Server
|
||||
* FastCGI interface implementation
|
||||
* src/fastcgi.c
|
||||
* src/lib/fastcgi.c
|
||||
* Lorenz Stechauner, 2020-12-26
|
||||
*/
|
||||
|
||||
#include "fastcgi.h"
|
||||
|
||||
#include "utils.h"
|
||||
#include "../client.h"
|
||||
#include "../necronda-server.h"
|
||||
#include <sys/un.h>
|
||||
#include <zlib.h>
|
||||
#include <sys/socket.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
char *fastcgi_add_param(char *buf, const char *key, const char *value) {
|
||||
char *ptr = buf;
|
41
src/lib/fastcgi.h
Normal file
41
src/lib/fastcgi.h
Normal file
@ -0,0 +1,41 @@
|
||||
/**
|
||||
* Necronda Web Server
|
||||
* FastCGI interface implementation (header file)
|
||||
* src/lib/fastcgi.h
|
||||
* Lorenz Stechauner, 2020-12-26
|
||||
*/
|
||||
|
||||
#ifndef NECRONDA_SERVER_FASTCGI_H
|
||||
#define NECRONDA_SERVER_FASTCGI_H
|
||||
|
||||
#include "include/fastcgi.h"
|
||||
#include "http.h"
|
||||
#include "uri.h"
|
||||
|
||||
#define FASTCGI_CHUNKED 1
|
||||
#define FASTCGI_COMPRESS 2
|
||||
|
||||
typedef struct {
|
||||
int socket;
|
||||
unsigned short req_id;
|
||||
char *out_buf;
|
||||
unsigned short out_len;
|
||||
unsigned short out_off;
|
||||
} fastcgi_conn;
|
||||
|
||||
char *fastcgi_add_param(char *buf, const char *key, const char *value);
|
||||
|
||||
int fastcgi_init(fastcgi_conn *conn, unsigned int client_num, unsigned int req_num, const sock *client,
|
||||
const http_req *req, const http_uri *uri);
|
||||
|
||||
int fastcgi_close_stdin(fastcgi_conn *conn);
|
||||
|
||||
int fastcgi_php_error(const char *msg, int msg_len, char *err_msg);
|
||||
|
||||
int fastcgi_header(fastcgi_conn *conn, http_res *res, char *err_msg);
|
||||
|
||||
int fastcgi_send(fastcgi_conn *conn, sock *client, int flags);
|
||||
|
||||
int fastcgi_receive(fastcgi_conn *conn, sock *client, unsigned long len);
|
||||
|
||||
#endif //NECRONDA_SERVER_FASTCGI_H
|
@ -1,12 +1,14 @@
|
||||
/**
|
||||
* Necronda Web Server
|
||||
* HTTP implementation
|
||||
* src/net/http.c
|
||||
* src/lib/http.c
|
||||
* Lorenz Stechauner, 2020-12-09
|
||||
*/
|
||||
|
||||
#include "http.h"
|
||||
|
||||
#include "utils.h"
|
||||
#include "../necronda-server.h"
|
||||
#include <string.h>
|
||||
|
||||
void http_to_camel_case(char *str, int mode) {
|
||||
char last = '-';
|
||||
@ -245,7 +247,7 @@ int http_send_request(sock *server, http_req *req) {
|
||||
}
|
||||
|
||||
const http_status *http_get_status(unsigned short status_code) {
|
||||
for (int i = 0; i < sizeof(http_statuses) / sizeof(http_status); i++) {
|
||||
for (int i = 0; i < http_statuses_size / sizeof(http_status); i++) {
|
||||
if (http_statuses[i].code == status_code) {
|
||||
return &http_statuses[i];
|
||||
}
|
||||
@ -255,7 +257,7 @@ const http_status *http_get_status(unsigned short status_code) {
|
||||
|
||||
const http_status_msg *http_get_error_msg(const http_status *status) {
|
||||
unsigned short code = status->code;
|
||||
for (int i = 0; i < sizeof(http_status_messages) / sizeof(http_status_msg); i++) {
|
||||
for (int i = 0; i < http_status_messages_size / sizeof(http_status_msg); i++) {
|
||||
if (http_status_messages[i].code == code) {
|
||||
return &http_status_messages[i];
|
||||
}
|
111
src/lib/http.h
Normal file
111
src/lib/http.h
Normal file
@ -0,0 +1,111 @@
|
||||
/**
|
||||
* Necronda Web Server
|
||||
* HTTP implementation (header file)
|
||||
* src/lib/http.h
|
||||
* Lorenz Stechauner, 2020-12-09
|
||||
*/
|
||||
|
||||
#ifndef NECRONDA_SERVER_HTTP_H
|
||||
#define NECRONDA_SERVER_HTTP_H
|
||||
|
||||
#include "sock.h"
|
||||
|
||||
#define HTTP_PRESERVE 0
|
||||
#define HTTP_LOWER 1
|
||||
#define HTTP_CAMEL 2
|
||||
|
||||
#define HTTP_REMOVE_ONE 0
|
||||
#define HTTP_REMOVE_ALL 1
|
||||
#define HTTP_REMOVE_LAST 2
|
||||
|
||||
#define HTTP_COLOR_SUCCESS "#008000"
|
||||
#define HTTP_COLOR_INFO "#606060"
|
||||
#define HTTP_COLOR_WARNING "#E0C000"
|
||||
#define HTTP_COLOR_ERROR "#C00000"
|
||||
|
||||
typedef struct {
|
||||
unsigned short code;
|
||||
char type[16];
|
||||
char msg[32];
|
||||
} http_status;
|
||||
|
||||
typedef struct {
|
||||
unsigned short code;
|
||||
const char *msg;
|
||||
} http_status_msg;
|
||||
|
||||
typedef struct {
|
||||
char mode[8];
|
||||
char color[8];
|
||||
const char *icon;
|
||||
const char *doc;
|
||||
} http_doc_info;
|
||||
|
||||
typedef struct {
|
||||
char field_num;
|
||||
char *fields[64][2];
|
||||
} http_hdr;
|
||||
|
||||
typedef struct {
|
||||
char method[16];
|
||||
char *uri;
|
||||
char version[3];
|
||||
http_hdr hdr;
|
||||
} http_req;
|
||||
|
||||
typedef struct {
|
||||
const http_status *status;
|
||||
char version[3];
|
||||
http_hdr hdr;
|
||||
} http_res;
|
||||
|
||||
extern const http_status http_statuses[];
|
||||
extern const http_status_msg http_status_messages[];
|
||||
extern const int http_statuses_size;
|
||||
extern const int http_status_messages_size;
|
||||
|
||||
extern const char http_default_document[];
|
||||
extern const char http_error_document[];
|
||||
extern const char http_error_icon[];
|
||||
extern const char http_warning_document[];
|
||||
extern const char http_warning_icon[];
|
||||
extern const char http_success_document[];
|
||||
extern const char http_success_icon[];
|
||||
extern const char http_info_document[];
|
||||
extern const char http_info_icon[];
|
||||
|
||||
void http_to_camel_case(char *str, int mode);
|
||||
|
||||
void http_free_hdr(http_hdr *hdr);
|
||||
|
||||
void http_free_req(http_req *req);
|
||||
|
||||
void http_free_res(http_res *res);
|
||||
|
||||
int http_receive_request(sock *client, http_req *req);
|
||||
|
||||
int http_parse_header_field(http_hdr *hdr, const char *buf, const char *end_ptr) ;
|
||||
|
||||
char *http_get_header_field(const http_hdr *hdr, const char *field_name);
|
||||
|
||||
void http_add_header_field(http_hdr *hdr, const char *field_name, const char *field_value);
|
||||
|
||||
void http_remove_header_field(http_hdr *hdr, const char *field_name, int mode);
|
||||
|
||||
int http_send_response(sock *client, http_res *res);
|
||||
|
||||
int http_send_request(sock *server, http_req *req);
|
||||
|
||||
const http_status *http_get_status(unsigned short status_code);
|
||||
|
||||
const http_status_msg *http_get_error_msg(const http_status *status);
|
||||
|
||||
const char *http_get_status_color(const http_status *status);
|
||||
|
||||
char *http_format_date(time_t time, char *buf, size_t size);
|
||||
|
||||
char *http_get_date(char *buf, size_t size);
|
||||
|
||||
const http_doc_info *http_get_status_info(const http_status *status);
|
||||
|
||||
#endif //NECRONDA_SERVER_HTTP_H
|
@ -1,67 +1,14 @@
|
||||
/**
|
||||
* Necronda Web Server
|
||||
* HTTP implementation (header file)
|
||||
* src/net/http.h
|
||||
* Lorenz Stechauner, 2020-12-09
|
||||
* HTTP static implementation
|
||||
* src/lib/http_static.c
|
||||
* Lorenz Stechauner, 2021-05-03
|
||||
*/
|
||||
|
||||
#ifndef NECRONDA_SERVER_HTTP_H
|
||||
#define NECRONDA_SERVER_HTTP_H
|
||||
#include "http.h"
|
||||
#include "../necronda-server.h"
|
||||
|
||||
#define HTTP_PRESERVE 0
|
||||
#define HTTP_LOWER 1
|
||||
#define HTTP_CAMEL 2
|
||||
|
||||
#define HTTP_REMOVE_ONE 0
|
||||
#define HTTP_REMOVE_ALL 1
|
||||
#define HTTP_REMOVE_LAST 2
|
||||
|
||||
#define HTTP_COLOR_SUCCESS "#008000"
|
||||
#define HTTP_COLOR_INFO "#606060"
|
||||
#define HTTP_COLOR_WARNING "#E0C000"
|
||||
#define HTTP_COLOR_ERROR "#C00000"
|
||||
|
||||
#include "sock.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned short code;
|
||||
char type[16];
|
||||
char msg[32];
|
||||
} http_status;
|
||||
|
||||
typedef struct {
|
||||
unsigned short code;
|
||||
const char *msg;
|
||||
} http_status_msg;
|
||||
|
||||
typedef struct {
|
||||
char mode[8];
|
||||
char color[8];
|
||||
const char *icon;
|
||||
const char *doc;
|
||||
} http_doc_info;
|
||||
|
||||
typedef struct {
|
||||
char field_num;
|
||||
char *fields[64][2];
|
||||
} http_hdr;
|
||||
|
||||
typedef struct {
|
||||
char method[16];
|
||||
char *uri;
|
||||
char version[3];
|
||||
http_hdr hdr;
|
||||
} http_req;
|
||||
|
||||
typedef struct {
|
||||
const http_status *status;
|
||||
char version[3];
|
||||
http_hdr hdr;
|
||||
} http_res;
|
||||
|
||||
static const http_status http_statuses[] = {
|
||||
const http_status http_statuses[] = {
|
||||
{100, "Informational", "Continue"},
|
||||
{101, "Informational", "Switching Protocols"},
|
||||
|
||||
@ -109,7 +56,7 @@ static const http_status http_statuses[] = {
|
||||
{505, "Server Error", "HTTP Version Not Supported"},
|
||||
};
|
||||
|
||||
static const http_status_msg http_status_messages[] = {
|
||||
const http_status_msg http_status_messages[] = {
|
||||
{100, "The client SHOULD continue with its request."},
|
||||
{101, "The server understands and is willing to comply with the clients request, via the Upgrade message header field, for a change in the application protocol being used on this connection."},
|
||||
|
||||
@ -156,7 +103,7 @@ static const http_status_msg http_status_messages[] = {
|
||||
{505, "The server does not support, or refuses to support, the HTTP protocol version that was used in the request message."}
|
||||
};
|
||||
|
||||
static const char http_default_document[] =
|
||||
const char http_default_document[] =
|
||||
"<!DOCTYPE html>\n"
|
||||
"<html lang=\"en\">\n"
|
||||
"<head>\n"
|
||||
@ -196,90 +143,56 @@ static const char http_default_document[] =
|
||||
"</body>\n"
|
||||
"</html>\n";
|
||||
|
||||
static const char http_error_document[] =
|
||||
const char http_error_document[] =
|
||||
"\t\t\t<h1>%1$i</h1>\n"
|
||||
"\t\t\t<h2>%2$s :(</h2>\n"
|
||||
"\t\t\t<p>%3$s</p>\n"
|
||||
"\t\t\t<p>%4$s</p>\n";
|
||||
|
||||
static const char http_error_icon[] =
|
||||
const char http_error_icon[] =
|
||||
"\t<link rel=\"alternate icon\" type=\"image/svg+xml\" sizes=\"any\" href=\"data:image/svg+xml;base64,"
|
||||
"PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAw"
|
||||
"L3N2ZyI+PHRleHQgeD0iNCIgeT0iMTIiIGZpbGw9IiNDMDAwMDAiIHN0eWxlPSJmb250LWZhbWls"
|
||||
"eTonQXJpYWwnLHNhbnMtc2VyaWYiPjooPC90ZXh0Pjwvc3ZnPgo=\"/>\n";
|
||||
|
||||
|
||||
static const char http_warning_document[] =
|
||||
const char http_warning_document[] =
|
||||
"\t\t\t<h1>%1$i</h1>\n"
|
||||
"\t\t\t<h2>%2$s :o</h2>\n"
|
||||
"\t\t\t<p>%3$s</p>\n"
|
||||
"\t\t\t<p>%4$s</p>\n";
|
||||
|
||||
static const char http_warning_icon[] =
|
||||
const char http_warning_icon[] =
|
||||
"\t<link rel=\"alternate icon\" type=\"image/svg+xml\" sizes=\"any\" href=\"data:image/svg+xml;base64,"
|
||||
"PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAw"
|
||||
"L3N2ZyI+PHRleHQgeD0iNCIgeT0iMTIiIGZpbGw9IiNFMEMwMDAiIHN0eWxlPSJmb250LWZhbWls"
|
||||
"eTonQXJpYWwnLHNhbnMtc2VyaWYiPjpvPC90ZXh0Pjwvc3ZnPgo=\"/>\n";
|
||||
|
||||
|
||||
static const char http_success_document[] =
|
||||
const char http_success_document[] =
|
||||
"\t\t\t<h1>%1$i</h1>\n"
|
||||
"\t\t\t<h2>%2$s :)</h2>\n"
|
||||
"\t\t\t<p>%3$s</p>\n"
|
||||
"\t\t\t<p>%4$s</p>\n";
|
||||
|
||||
static const char http_success_icon[] =
|
||||
const char http_success_icon[] =
|
||||
"\t<link rel=\"alternate icon\" type=\"image/svg+xml\" sizes=\"any\" href=\"data:image/svg+xml;base64,"
|
||||
"PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAw"
|
||||
"L3N2ZyI+PHRleHQgeD0iNCIgeT0iMTIiIGZpbGw9IiMwMDgwMDAiIHN0eWxlPSJmb250LWZhbWls"
|
||||
"eTonQXJpYWwnLHNhbnMtc2VyaWYiPjopPC90ZXh0Pjwvc3ZnPgo=\"/>\n";
|
||||
|
||||
|
||||
static const char http_info_document[] =
|
||||
const char http_info_document[] =
|
||||
"\t\t\t<h1>%1$i</h1>\n"
|
||||
"\t\t\t<h2>%2$s :)</h2>\n"
|
||||
"\t\t\t<p>%3$s</p>\n"
|
||||
"\t\t\t<p>%4$s</p>\n";
|
||||
|
||||
static const char http_info_icon[] =
|
||||
const char http_info_icon[] =
|
||||
"\t<link rel=\"alternate icon\" type=\"image/svg+xml\" sizes=\"any\" href=\"data:image/svg+xml;base64,"
|
||||
"PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAw"
|
||||
"L3N2ZyI+PHRleHQgeD0iNCIgeT0iMTIiIGZpbGw9IiM2MDYwNjAiIHN0eWxlPSJmb250LWZhbWls"
|
||||
"eTonQXJpYWwnLHNhbnMtc2VyaWYiPjopPC90ZXh0Pjwvc3ZnPgo=\"/>\n";
|
||||
|
||||
|
||||
void http_to_camel_case(char *str, int mode);
|
||||
|
||||
void http_free_hdr(http_hdr *hdr);
|
||||
|
||||
void http_free_req(http_req *req);
|
||||
|
||||
void http_free_res(http_res *res);
|
||||
|
||||
int http_receive_request(sock *client, http_req *req);
|
||||
|
||||
int http_parse_header_field(http_hdr *hdr, const char *buf, const char *end_ptr) ;
|
||||
|
||||
char *http_get_header_field(const http_hdr *hdr, const char *field_name);
|
||||
|
||||
void http_add_header_field(http_hdr *hdr, const char *field_name, const char *field_value);
|
||||
|
||||
void http_remove_header_field(http_hdr *hdr, const char *field_name, int mode);
|
||||
|
||||
int http_send_response(sock *client, http_res *res);
|
||||
|
||||
int http_send_request(sock *server, http_req *req);
|
||||
|
||||
const http_status *http_get_status(unsigned short status_code);
|
||||
|
||||
const http_status_msg *http_get_error_msg(const http_status *status);
|
||||
|
||||
const char *http_get_status_color(const http_status *status);
|
||||
|
||||
char *http_format_date(time_t time, char *buf, size_t size);
|
||||
|
||||
char *http_get_date(char *buf, size_t size);
|
||||
|
||||
const http_doc_info *http_get_status_info(const http_status *status);
|
||||
|
||||
#endif //NECRONDA_SERVER_HTTP_H
|
||||
const int http_statuses_size = sizeof(http_statuses);
|
||||
const int http_status_messages_size = sizeof(http_status_messages);
|
@ -1,48 +1,12 @@
|
||||
/**
|
||||
* Necronda Web Server
|
||||
* FastCGI interface implementation (header file)
|
||||
* src/fastcgi.h
|
||||
* Lorenz Stechauner, 2020-12-26
|
||||
* FastCGI header file
|
||||
* src/lib/include/fastcgi.h
|
||||
* Lorenz Stechauner, 2021-05-03
|
||||
*/
|
||||
|
||||
#ifndef NECRONDA_SERVER_FASTCGI_H
|
||||
#define NECRONDA_SERVER_FASTCGI_H
|
||||
|
||||
#define FASTCGI_CHUNKED 1
|
||||
#define FASTCGI_COMPRESS 2
|
||||
|
||||
#include "necronda-server.h"
|
||||
#include "http.h"
|
||||
#include "uri.h"
|
||||
#include "client.h"
|
||||
|
||||
#include <sys/un.h>
|
||||
#include <zlib.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
int socket;
|
||||
unsigned short req_id;
|
||||
char *out_buf;
|
||||
unsigned short out_len;
|
||||
unsigned short out_off;
|
||||
} fastcgi_conn;
|
||||
|
||||
char *fastcgi_add_param(char *buf, const char *key, const char *value);
|
||||
|
||||
int fastcgi_init(fastcgi_conn *conn, unsigned int client_num, unsigned int req_num, const sock *client,
|
||||
const http_req *req, const http_uri *uri);
|
||||
|
||||
int fastcgi_close_stdin(fastcgi_conn *conn);
|
||||
|
||||
int fastcgi_php_error(const char *msg, int msg_len, char *err_msg);
|
||||
|
||||
int fastcgi_header(fastcgi_conn *conn, http_res *res, char *err_msg);
|
||||
|
||||
int fastcgi_send(fastcgi_conn *conn, sock *client, int flags);
|
||||
|
||||
int fastcgi_receive(fastcgi_conn *conn, sock *client, unsigned long len);
|
||||
|
||||
#ifndef NECRONDA_SERVER_EXTERN_FASTCGI_H
|
||||
#define NECRONDA_SERVER_EXTERN_FASTCGI_H
|
||||
|
||||
/*
|
||||
* Listening socket file number
|
||||
@ -155,4 +119,4 @@ typedef struct {
|
||||
FCGI_UnknownTypeBody body;
|
||||
} FCGI_UnknownTypeRecord;
|
||||
|
||||
#endif //NECRONDA_SERVER_FASTCGI_H
|
||||
#endif //NECRONDA_SERVER_EXTERN_FASTCGI_H
|
@ -1,16 +1,33 @@
|
||||
/**
|
||||
* Necronda Web Server
|
||||
* Reverse proxy
|
||||
* src/rev_proxy.c
|
||||
* src/lib/rev_proxy.c
|
||||
* Lorenz Stechauner, 2021-01-07
|
||||
*/
|
||||
|
||||
#include "rev_proxy.h"
|
||||
#include "utils.h"
|
||||
#include "../client.h"
|
||||
#include "../necronda-server.h"
|
||||
#include <openssl/ssl.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <openssl/err.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
sock rev_proxy;
|
||||
char *rev_proxy_host = NULL;
|
||||
struct timeval server_timeout = {.tv_sec = SERVER_TIMEOUT, .tv_usec = 0};
|
||||
|
||||
int rev_proxy_preload() {
|
||||
rev_proxy.buf = NULL;
|
||||
rev_proxy.buf_len = 0;
|
||||
rev_proxy.buf_off = 0;
|
||||
rev_proxy.ctx = SSL_CTX_new(TLS_client_method());
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rev_proxy_request_header(http_req *req, int enc) {
|
||||
char buf1[256];
|
||||
char buf2[256];
|
@ -1,13 +1,20 @@
|
||||
/**
|
||||
* Necronda Web Server
|
||||
* Reverse proxy (header file)
|
||||
* src/rev_proxy.h
|
||||
* src/lib/rev_proxy.h
|
||||
* Lorenz Stechauner, 2021-01-07
|
||||
*/
|
||||
|
||||
#ifndef NECRONDA_SERVER_REV_PROXY_H
|
||||
#define NECRONDA_SERVER_REV_PROXY_H
|
||||
|
||||
#include "http.h"
|
||||
#include "config.h"
|
||||
|
||||
extern sock rev_proxy;
|
||||
|
||||
int rev_proxy_preload();
|
||||
|
||||
int rev_proxy_request_header(http_req *req, int enc);
|
||||
|
||||
int rev_proxy_response_header(http_req *req, http_res *res);
|
@ -1,11 +1,16 @@
|
||||
/**
|
||||
* Necronda Web Server
|
||||
* Basic TCP and TLS socket
|
||||
* src/sock.c
|
||||
* src/lib/sock.c
|
||||
* Lorenz Stechauner, 2021-01-07
|
||||
*/
|
||||
|
||||
#include "sock.h"
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
|
||||
const char *sock_strerror(sock *s) {
|
||||
if (s->_last_ret == 0) {
|
@ -1,19 +1,14 @@
|
||||
/**
|
||||
* Necronda Web Server
|
||||
* Basic TCP and TLS socket (header file)
|
||||
* src/sock.h
|
||||
* src/lib/sock.h
|
||||
* Lorenz Stechauner, 2021-01-07
|
||||
*/
|
||||
|
||||
#ifndef NECRONDA_SERVER_SOCK_H
|
||||
#define NECRONDA_SERVER_SOCK_H
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/conf.h>
|
||||
#include <openssl/engine.h>
|
||||
#include <openssl/dh.h>
|
||||
#include <openssl/crypto.h>
|
||||
|
||||
typedef struct {
|
||||
unsigned int enc:1;
|
@ -1,12 +1,14 @@
|
||||
/**
|
||||
* Necronda Web Server
|
||||
* URI and path handlers
|
||||
* src/uri.c
|
||||
* src/lib/uri.c
|
||||
* Lorenz Stechauner, 2020-12-13
|
||||
*/
|
||||
|
||||
#include "uri.h"
|
||||
|
||||
#include "utils.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int path_is_directory(const char *path) {
|
||||
struct stat statbuf;
|
||||
@ -51,12 +53,12 @@ int uri_init(http_uri *uri, const char *webroot, const char *uri_str, int dir_mo
|
||||
} else {
|
||||
query[0] = 0;
|
||||
query++;
|
||||
ssize_t size = strlen(query) + 1;
|
||||
long size = (long) strlen(query) + 1;
|
||||
uri->query = malloc(size);
|
||||
strcpy(uri->query, query);
|
||||
}
|
||||
|
||||
ssize_t size = strlen(uri_str) + 1;
|
||||
long size = (long) strlen(uri_str) + 1;
|
||||
uri->req_path = malloc(size);
|
||||
url_decode(uri_str, uri->req_path, &size);
|
||||
if (query != NULL) {
|
||||
@ -66,7 +68,7 @@ int uri_init(http_uri *uri, const char *webroot, const char *uri_str, int dir_mo
|
||||
return 2;
|
||||
}
|
||||
|
||||
size = strlen(uri->req_path) + 1;
|
||||
size = (long) strlen(uri->req_path) + 1;
|
||||
uri->path = malloc(size);
|
||||
uri->pathinfo = malloc(size);
|
||||
|
||||
@ -109,7 +111,7 @@ int uri_init(http_uri *uri, const char *webroot, const char *uri_str, int dir_mo
|
||||
char *ptr;
|
||||
parent_dir:
|
||||
ptr = strrchr(uri->path, '/');
|
||||
size = strlen(ptr);
|
||||
size = (long) strlen(ptr);
|
||||
sprintf(buf3, "%.*s%s", (int) size, ptr, uri->pathinfo);
|
||||
strcpy(uri->pathinfo, buf3);
|
||||
ptr[0] = 0;
|
||||
@ -122,7 +124,7 @@ int uri_init(http_uri *uri, const char *webroot, const char *uri_str, int dir_mo
|
||||
if (path_is_file(buf0)) {
|
||||
uri->filename = malloc(strlen(buf0) + 1);
|
||||
strcpy(uri->filename, buf0);
|
||||
ssize_t len = strlen(uri->path);
|
||||
long len = (long) strlen(uri->path);
|
||||
if (strcmp(uri->path + len - 5, ".html") == 0) {
|
||||
uri->path[len - 5] = 0;
|
||||
} else if (strcmp(uri->path + len - 4, ".php") == 0) {
|
@ -1,21 +1,20 @@
|
||||
/**
|
||||
* Necronda Web Server
|
||||
* URI and path handlers (header file)
|
||||
* src/uri.h
|
||||
* src/lib/uri.h
|
||||
* Lorenz Stechauner, 2020-12-13
|
||||
*/
|
||||
|
||||
#ifndef NECRONDA_SERVER_URI_H
|
||||
#define NECRONDA_SERVER_URI_H
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#define URI_DIR_MODE_NO_VALIDATION 0
|
||||
#define URI_DIR_MODE_FORBIDDEN 1
|
||||
#define URI_DIR_MODE_LIST 2
|
||||
#define URI_DIR_MODE_INFO 3
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
char etag[64];
|
||||
char type[24];
|
@ -1,12 +1,15 @@
|
||||
/**
|
||||
* Necronda Web Server
|
||||
* Utilities
|
||||
* src/utils.c
|
||||
* src/lib/utils.c
|
||||
* Lorenz Stechauner, 2020-12-03
|
||||
*/
|
||||
|
||||
#include "utils.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
char *log_prefix;
|
||||
|
||||
char *format_duration(unsigned long micros, char *buf) {
|
||||
if (micros < 10000) {
|
||||
@ -99,6 +102,20 @@ int url_decode(const char *str, char *dec, ssize_t *size) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mime_is_compressible(const char *type) {
|
||||
return
|
||||
strncmp(type, "text/", 5) == 0 ||
|
||||
strncmp(type, "message/", 7) == 0 ||
|
||||
strstr(type, "+xml") != NULL ||
|
||||
strcmp(type, "application/javascript") == 0 ||
|
||||
strcmp(type, "application/json") == 0 ||
|
||||
strcmp(type, "application/xml") == 0 ||
|
||||
strcmp(type, "application/x-www-form-urlencoded") == 0 ||
|
||||
strcmp(type, "application/x-tex") == 0 ||
|
||||
strcmp(type, "application/x-httpd-php") == 0 ||
|
||||
strcmp(type, "application/x-latex") == 0;
|
||||
}
|
||||
|
||||
MMDB_entry_data_list_s *mmdb_json(MMDB_entry_data_list_s *list, char *str, long *str_off, long str_len) {
|
||||
switch (list->entry_data.type) {
|
||||
case MMDB_DATA_TYPE_MAP:
|
||||
@ -159,17 +176,3 @@ MMDB_entry_data_list_s *mmdb_json(MMDB_entry_data_list_s *list, char *str, long
|
||||
}
|
||||
return next;
|
||||
}
|
||||
|
||||
int mime_is_compressible(const char *type) {
|
||||
return
|
||||
strncmp(type, "text/", 5) == 0 ||
|
||||
strncmp(type, "message/", 7) == 0 ||
|
||||
strstr(type, "+xml") != NULL ||
|
||||
strcmp(type, "application/javascript") == 0 ||
|
||||
strcmp(type, "application/json") == 0 ||
|
||||
strcmp(type, "application/xml") == 0 ||
|
||||
strcmp(type, "application/x-www-form-urlencoded") == 0 ||
|
||||
strcmp(type, "application/x-tex") == 0 ||
|
||||
strcmp(type, "application/x-httpd-php") == 0 ||
|
||||
strcmp(type, "application/x-latex") == 0;
|
||||
}
|
@ -1,14 +1,16 @@
|
||||
/**
|
||||
* Necronda Web Server
|
||||
* Utilities (header file)
|
||||
* src/utils.h
|
||||
* src/lib/utils.h
|
||||
* Lorenz Stechauner, 2020-12-03
|
||||
*/
|
||||
|
||||
#ifndef NECRONDA_SERVER_UTILS_H
|
||||
#define NECRONDA_SERVER_UTILS_H
|
||||
|
||||
char *log_prefix;
|
||||
#include <maxminddb.h>
|
||||
|
||||
extern char *log_prefix;
|
||||
|
||||
#define out_1(fmt) fprintf(stdout, "%s" fmt "\n", log_prefix)
|
||||
#define out_2(fmt, args...) fprintf(stdout, "%s" fmt "\n", log_prefix, args)
|
||||
@ -28,6 +30,8 @@ int url_encode(const char *str, char *enc, ssize_t *size);
|
||||
|
||||
int url_decode(const char *str, char *dec, ssize_t *size);
|
||||
|
||||
int mime_is_text(const char *type);
|
||||
int mime_is_compressible(const char *type);
|
||||
|
||||
MMDB_entry_data_list_s *mmdb_json(MMDB_entry_data_list_s *list, char *str, long *str_off, long str_len);
|
||||
|
||||
#endif //NECRONDA_SERVER_UTILS_H
|
@ -8,21 +8,35 @@
|
||||
#define _POSIX_C_SOURCE 199309L
|
||||
|
||||
#include "necronda-server.h"
|
||||
|
||||
#include "config.c"
|
||||
#include "utils.c"
|
||||
#include "uri.c"
|
||||
#include "cache.c"
|
||||
#include "sock.c"
|
||||
#include "http.c"
|
||||
#include "rev_proxy.c"
|
||||
#include "client.c"
|
||||
#include "fastcgi.c"
|
||||
|
||||
#include "lib/cache.h"
|
||||
#include "lib/config.h"
|
||||
#include "lib/sock.h"
|
||||
#include "lib/rev_proxy.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/socket.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/select.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <wait.h>
|
||||
#include <sys/types.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/conf.h>
|
||||
#include <maxminddb.h>
|
||||
#include <dirent.h>
|
||||
|
||||
int active = 1;
|
||||
const char *config_file;
|
||||
|
||||
int sockets[NUM_SOCKETS];
|
||||
pid_t children[MAX_CHILDREN];
|
||||
MMDB_s mmdbs[MAX_MMDB];
|
||||
|
||||
void openssl_init() {
|
||||
SSL_library_init();
|
||||
@ -273,10 +287,7 @@ int main(int argc, const char *argv[]) {
|
||||
SSL_CTX_set_cipher_list(client.ctx, "HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4");
|
||||
SSL_CTX_set_ecdh_auto(client.ctx, 1);
|
||||
|
||||
rev_proxy.buf = NULL;
|
||||
rev_proxy.buf_len = 0;
|
||||
rev_proxy.buf_off = 0;
|
||||
rev_proxy.ctx = SSL_CTX_new(TLS_client_method());
|
||||
rev_proxy_preload();
|
||||
|
||||
if (SSL_CTX_use_certificate_chain_file(client.ctx, cert_file) != 1) {
|
||||
fprintf(stderr, ERR_STR "Unable to load certificate chain file: %s: %s" CLR_STR "\n",
|
||||
|
@ -8,26 +8,8 @@
|
||||
#ifndef NECRONDA_SERVER_NECRONDA_SERVER_H
|
||||
#define NECRONDA_SERVER_NECRONDA_SERVER_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/socket.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/select.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <wait.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/conf.h>
|
||||
#include <openssl/engine.h>
|
||||
#include <openssl/dh.h>
|
||||
#include <maxminddb.h>
|
||||
#include <dirent.h>
|
||||
|
||||
|
||||
#define NUM_SOCKETS 2
|
||||
#define MAX_CHILDREN 1024
|
||||
@ -77,10 +59,8 @@
|
||||
#define DEFAULT_CONFIG_FILE "/etc/necronda-server/necronda-server.conf"
|
||||
#endif
|
||||
|
||||
int sockets[NUM_SOCKETS];
|
||||
pid_t children[MAX_CHILDREN];
|
||||
MMDB_s mmdbs[MAX_MMDB];
|
||||
|
||||
char *client_addr_str, *client_addr_str_ptr, *server_addr_str, *server_addr_str_ptr, *client_host_str;
|
||||
extern int sockets[NUM_SOCKETS];
|
||||
extern pid_t children[MAX_CHILDREN];
|
||||
extern MMDB_s mmdbs[MAX_MMDB];
|
||||
|
||||
#endif //NECRONDA_SERVER_NECRONDA_SERVER_H
|
||||
|
Reference in New Issue
Block a user