-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhttps.c
More file actions
188 lines (144 loc) · 4.69 KB
/
Copy pathhttps.c
File metadata and controls
188 lines (144 loc) · 4.69 KB
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
//
// Created by aidankeefe on 5/19/26.
//
#include "../include/https.h"
#include <strings.h>
#include "../include/deserializeResponse.h"
struct https_route {
struct aid_string routeName;
https_method method;
https_callback callback;
};
static struct aid_LinkedList routes = {0};
static struct aid_AidAllocator allocator = {0};
void https_reg_route(https_method method, struct aid_string routeName, https_callback callback) {
struct https_route* r = aid_AidAlloc(&allocator, sizeof(struct https_route));
*r = (struct https_route){routeName, method, callback};
aid_push(&routes, (void*)r, VOIDPTR);
}
static int set_nonblocking(int sockfd) {
// 1. Get the current flags
int flags = fcntl(sockfd, F_GETFL, 0);
if (flags == -1) {
perror("fcntl(F_GETFL)");
return -1;
}
// 2. Add the O_NONBLOCK flag to the current flags using bitwise OR
if (fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) == -1) {
perror("fcntl(F_SETFL)");
return -1;
}
return 0;
}
void(*getRouteCallback(struct https_ctx* req, WOLFSSL* ssl))(WOLFSSL*, https_ctx*) {
i32 idx = 0;
bool hasQueryParams = false;
if (req->request->method == GET) {
for (; idx < req->request->route.length ; idx++) {
if (req->request->route.s[idx] == '?') {
hasQueryParams = true;
break;
}
}
}
struct aid_string routeName;
if (hasQueryParams) {
routeName = req->request->route;
routeName.length = idx;
}else {
routeName = req->request->route;
}
for (struct aid_LLNode* node = routes.head; node != nullptr; node = node->next ) {
struct https_route* route = node->VOIDPTR;
if (aid_str_cmp(&routeName, &route->routeName)) {
return route->callback;
}
}
return nullptr;
}
void handelRequest(int client, WOLFSSL_CTX* wctx) {
u8 arena_buffer[MiB(1)] = "";
aid_Arena arena = {arena_buffer, MiB(1), arena_buffer};
WOLFSSL* ssl = wolfSSL_new(wctx);
if (!ssl) {
fprintf(stderr, "wolfSSL_new failed\n");
goto CLIENT_ERROR;
}
wolfSSL_set_fd(ssl, client);
i32 ret = wolfSSL_accept(ssl);
char errorBuffer[80];
if (ret != SSL_SUCCESS) {
i32 err = wolfSSL_get_error(ssl, ret);
printf("error = %d, %s\n", err, wolfSSL_ERR_error_string(err, errorBuffer));
goto ACCEPT_ERROR;
}
char buffer[KiB(5)] = "";
u64 size = wolfSSL_read(ssl, buffer, KiB(5));
if (size <= 0) {
int err = wolfSSL_get_error(ssl, size);
fprintf(stderr, "wolfSSL_read failed, error: %d\n", err);
}
auto req = https_serializeRequest(&arena, (struct aid_string){KiB(5),size-1, 0, buffer });
https_ctx ctx = {.request = req};
auto func = getRouteCallback(&ctx, ssl);
if (func == nullptr) {
fprintf(stderr, "Invalid Route Hit\n");
}else {
func(ssl, &ctx);
}
https_freeRequest(req);
wolfSSL_shutdown(ssl);
ACCEPT_ERROR:
wolfSSL_free(ssl);
CLIENT_ERROR:
close(client);
}
void https_listen(u64 port, https_certs certs, u64 options) {
i32 initCode = wolfSSL_Init();
auto method = wolfSSLv23_server_method();
auto wctx = wolfSSL_CTX_new(method);
/* Load server certificates into WOLFSSL_CTX */
if (wolfSSL_CTX_use_certificate_file(wctx, certs.cert_path,
SSL_FILETYPE_PEM) != SSL_SUCCESS) {
fprintf(stderr, "Error loading ../certs/server-cert.pem, please"
"check the file.\n");
exit(EXIT_FAILURE);
}
/* Load keys */
if (wolfSSL_CTX_use_PrivateKey_file(wctx, certs.private_key,
SSL_FILETYPE_PEM) != SSL_SUCCESS) {
fprintf(stderr, "Error loading ../certs/server-key.pem, please check"
"the file.\n");
exit(EXIT_FAILURE);
}
SOCKADDR_IN addr;
int socket_fd;
if ((socket_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
return;
}
bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
int optval = 1;
setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
set_nonblocking(socket_fd);
if ((bind(socket_fd, (struct sockaddr*)&addr, sizeof(addr))) < 0) {
return;
}
listen(socket_fd, 1000);
int client;
while (true) {
struct sockaddr_in client_addr;
socklen_t client_addr_len = sizeof(client_addr);
client = accept(
socket_fd,
(struct sockaddr*)&client_addr,
&client_addr_len
);
if (client < 0) {
continue;
}
handelRequest(client, wctx);
}
}