1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
#ifndef NET_H
#define NET_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
//#include <netinet/in.h>
#include <ifaddrs.h>
#include <unistd.h>
#include <signal.h>
#include <stdbool.h>
#include <inttypes.h>
#include <ctype.h>
#include <time.h>
#include "str/str.h"
#include "list/list.h"
#include "dir/dir.h"
#include "log/log.h"
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <poll.h>
#include <fcntl.h>
#ifdef __linux__
#include <sys/sendfile.h>
#endif
typedef enum http_method {
GET, HEAD, OPTIONS, TRACE,
DELETE, PUT, POST, PATCH
} http_method;
enum mime_type {
AVIF, BMP, CSS, CSV, GZ, GIF, HTML,
ICO, JPG, JPEG, JS, JSON, MIDI, MP3,
MP4, MPEG, PNG, PDF, PHP, RAR, TIFF, TS,
TXT, WAV, WEBA, WEBM, WEBP, XML, ZIP,
_7Z,
};
struct uri {
str path;
str query;
};
struct uri_mod {
str pattern;
struct uri output;
};
struct header {
str name;
str value;
};
#define MAX_HEADERS 16
struct http_message {
union {
str method;
str resp_ver;
};
union {
str uri;
str status;
};
union {
str req_ver;
str reason;
};
int hlen;
struct header headers[MAX_HEADERS];
str body;
};
typedef struct http_server {
str port;
int backlog;
int ssocket;
} http_server;
typedef ssize_t (*recv_func)(int,void*,size_t,int);
typedef int (*ssl_recv_func)(SSL*,void*,int);
typedef struct http_worker {
int ssocket;
int csocket;
int secure;
SSL_CTX *ssl_ctx;
SSL *ssl;
recv_func receive;
ssl_recv_func ssl_receive;
} http_worker;
#define MAX_RESPONSE_SIZE 0x0FFFFFFF
#define MAX_BODY_SIZE (MAX_RESPONSE_SIZE - 0x0FFF)
#define insert_header(hm, h) \
(hm).headers[(hm).hlen++] = (h)
http_server *setup_http_server(str port, int backlog);
void destroy_http_server(http_server **hs);
http_worker *setup_http_worker(int ssocket, int secure, str certfile, str keyfile);
void destroy_http_worker(http_worker **hw);
void reset_worker_ssl(http_worker *hw);
int accept_connection(http_worker *hw, char ip[INET_ADDRSTRLEN]);
int receive_request(http_worker *hw, str *request);
struct file generate_resource(struct uri resource, str url);
char *handlePOST(char *request);
void build_http_message(char *request, int len, struct http_message *hm);
enum http_method get_http_method(str method);
struct uri sanitize_uri(str uri);
void send_file(http_worker *hw, str filename);
int read_uri_rewrites(char *map, uint64_t size);
void free_uri_rewrites(void);
#endif
|