Http keep alive
This commit is contained in:
47
src/client.c
47
src/client.c
@ -14,18 +14,9 @@
|
|||||||
#include "net/http.h"
|
#include "net/http.h"
|
||||||
|
|
||||||
|
|
||||||
#define out_1(fmt) fprintf(parent_stdout, "%s" fmt "\n", log_prefix)
|
|
||||||
#define out_2(fmt, args...) fprintf(parent_stdout, "%s" fmt "\n", log_prefix, args)
|
|
||||||
|
|
||||||
#define out_x(x, arg1, arg2, arg3, arg4, arg5, arg6, arg7, FUNC, ...) FUNC
|
|
||||||
|
|
||||||
#define print(...) out_x(, ##__VA_ARGS__, out_2(__VA_ARGS__), out_2(__VA_ARGS__), out_2(__VA_ARGS__), \
|
|
||||||
out_2(__VA_ARGS__), out_2(__VA_ARGS__), out_2(__VA_ARGS__), out_1(__VA_ARGS__))
|
|
||||||
|
|
||||||
|
|
||||||
int keep_alive = 1;
|
int keep_alive = 1;
|
||||||
char *client_addr_str, *client_addr_str_ptr, *server_addr_str, *server_addr_str_ptr,
|
char *client_addr_str, *client_addr_str_ptr, *server_addr_str, *server_addr_str_ptr,
|
||||||
*log_prefix, *log_conn_prefix, *log_req_prefix;
|
*log_conn_prefix, *log_req_prefix;
|
||||||
|
|
||||||
|
|
||||||
char *format_duration(unsigned long micros, char *buf) {
|
char *format_duration(unsigned long micros, char *buf) {
|
||||||
@ -54,14 +45,44 @@ int client_websocket_handler() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int client_request_handler(sock *client, int req_num) {
|
int client_request_handler(sock *client, int req_num) {
|
||||||
// TODO implement client_request_handler
|
struct timespec begin, end;
|
||||||
|
int ret;
|
||||||
|
char buf[16];
|
||||||
|
char *msg = "HTTP/1.1 501 Not Implemented\r\nConnection: keep-alive\r\nContent-Length: 116\r\n\r\n<!DOCTYPE html><html><head><title>501 Not Implemented</title></head><body><h1>501 Not Implemented</h1></body></html>";
|
||||||
|
|
||||||
|
fd_set socket_fds;
|
||||||
|
FD_ZERO(&socket_fds);
|
||||||
|
FD_SET(client->socket, &socket_fds);
|
||||||
|
|
||||||
|
ret = select(client->socket + 1, &socket_fds, NULL, NULL, NULL);
|
||||||
|
if (ret < 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &begin);
|
||||||
|
|
||||||
|
http_req req;
|
||||||
|
ret = http_receive_request(client, &req);
|
||||||
|
if (ret != 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (client->enc) {
|
||||||
|
SSL_write(client->ssl, msg, (int) strlen(msg));
|
||||||
|
} else {
|
||||||
|
send(client->socket, msg, strlen(msg), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &end);
|
||||||
|
unsigned long micros = (end.tv_nsec - begin.tv_nsec) / 1000 + (end.tv_sec - begin.tv_sec) * 1000000;
|
||||||
|
print(ERR_STR "501 Not Implemented (%s)" CLR_STR, format_duration(micros, buf));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int client_connection_handler(sock *client) {
|
int client_connection_handler(sock *client) {
|
||||||
|
struct timespec begin, end;
|
||||||
int ret, req_num;
|
int ret, req_num;
|
||||||
char buf[16];
|
char buf[16];
|
||||||
struct timespec begin, end;
|
|
||||||
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &begin);
|
clock_gettime(CLOCK_MONOTONIC, &begin);
|
||||||
print("Connection accepted from %s (%s) [%s]", client_addr_str, client_addr_str, "N/A");
|
print("Connection accepted from %s (%s) [%s]", client_addr_str, client_addr_str, "N/A");
|
||||||
@ -100,8 +121,8 @@ int client_connection_handler(sock *client) {
|
|||||||
}
|
}
|
||||||
shutdown(client->socket, SHUT_RDWR);
|
shutdown(client->socket, SHUT_RDWR);
|
||||||
close(client->socket);
|
close(client->socket);
|
||||||
clock_gettime(CLOCK_MONOTONIC, &end);
|
|
||||||
|
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &end);
|
||||||
unsigned long micros = (end.tv_nsec - begin.tv_nsec) / 1000 + (end.tv_sec - begin.tv_sec) * 1000000;
|
unsigned long micros = (end.tv_nsec - begin.tv_nsec) / 1000 + (end.tv_sec - begin.tv_sec) * 1000000;
|
||||||
|
|
||||||
print("Connection closed (%s)", format_duration(micros, buf));
|
print("Connection closed (%s)", format_duration(micros, buf));
|
||||||
|
@ -104,6 +104,7 @@ void terminate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int status = 0;
|
int status = 0;
|
||||||
|
int wait_num = 0;
|
||||||
int ret;
|
int ret;
|
||||||
for (int i = 0; i < MAX_CHILDREN; i++) {
|
for (int i = 0; i < MAX_CHILDREN; i++) {
|
||||||
if (CHILDREN[i] != 0) {
|
if (CHILDREN[i] != 0) {
|
||||||
@ -114,10 +115,15 @@ void terminate() {
|
|||||||
CHILDREN[i] = 0;
|
CHILDREN[i] = 0;
|
||||||
} else {
|
} else {
|
||||||
kill(CHILDREN[i], SIGTERM);
|
kill(CHILDREN[i], SIGTERM);
|
||||||
|
wait_num++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wait_num > 0) {
|
||||||
|
fprintf(stderr, "Waiting for %i child process(es)...\n", wait_num);
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < MAX_CHILDREN; i++) {
|
for (int i = 0; i < MAX_CHILDREN; i++) {
|
||||||
if (CHILDREN[i] != 0) {
|
if (CHILDREN[i] != 0) {
|
||||||
ret = waitpid(CHILDREN[i], &status, 0);
|
ret = waitpid(CHILDREN[i], &status, 0);
|
||||||
|
@ -23,6 +23,8 @@
|
|||||||
#define LISTEN_BACKLOG 16
|
#define LISTEN_BACKLOG 16
|
||||||
#define REQ_PER_CONNECTION 100
|
#define REQ_PER_CONNECTION 100
|
||||||
|
|
||||||
|
#define CLIENT_MAX_HEADER_SIZE 8192
|
||||||
|
|
||||||
#define ERR_STR "\x1B[1;31m"
|
#define ERR_STR "\x1B[1;31m"
|
||||||
#define CLR_STR "\x1B[0m"
|
#define CLR_STR "\x1B[0m"
|
||||||
#define HTTP_STR "\x1B[1;31m"
|
#define HTTP_STR "\x1B[1;31m"
|
||||||
|
@ -6,3 +6,30 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "http.h"
|
#include "http.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
|
||||||
|
int http_receive_request(sock *client, http_req *req) {
|
||||||
|
char *buf = malloc(CLIENT_MAX_HEADER_SIZE);
|
||||||
|
ssize_t len;
|
||||||
|
memset(buf, 0, CLIENT_MAX_HEADER_SIZE);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
if (client->enc) {
|
||||||
|
len = SSL_read(client->ssl, buf, CLIENT_MAX_HEADER_SIZE);
|
||||||
|
if (len < 0) {
|
||||||
|
print(ERR_STR "Unable to receive: %s" CLR_STR, ssl_get_error(client->ssl, len));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
len = recv(client->socket, buf, CLIENT_MAX_HEADER_SIZE, 0);
|
||||||
|
if (len < 0) {
|
||||||
|
print(ERR_STR "Unable to receive: %s" CLR_STR, strerror(errno));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -8,4 +8,14 @@
|
|||||||
#ifndef NECRONDA_SERVER_HTTP_H
|
#ifndef NECRONDA_SERVER_HTTP_H
|
||||||
#define NECRONDA_SERVER_HTTP_H
|
#define NECRONDA_SERVER_HTTP_H
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char method[8];
|
||||||
|
char *uri;
|
||||||
|
char version[3];
|
||||||
|
char field_num;
|
||||||
|
char *fields[64][2];
|
||||||
|
} http_req;
|
||||||
|
|
||||||
|
int http_receive_request(sock *client, http_req *req);
|
||||||
|
|
||||||
#endif //NECRONDA_SERVER_HTTP_H
|
#endif //NECRONDA_SERVER_HTTP_H
|
||||||
|
10
src/utils.h
10
src/utils.h
@ -8,4 +8,14 @@
|
|||||||
#ifndef NECRONDA_SERVER_UTILS_H
|
#ifndef NECRONDA_SERVER_UTILS_H
|
||||||
#define NECRONDA_SERVER_UTILS_H
|
#define NECRONDA_SERVER_UTILS_H
|
||||||
|
|
||||||
|
char *log_prefix;
|
||||||
|
|
||||||
|
#define out_1(fmt) fprintf(parent_stdout, "%s" fmt "\n", log_prefix)
|
||||||
|
#define out_2(fmt, args...) fprintf(parent_stdout, "%s" fmt "\n", log_prefix, args)
|
||||||
|
|
||||||
|
#define out_x(x, arg1, arg2, arg3, arg4, arg5, arg6, arg7, FUNC, ...) FUNC
|
||||||
|
|
||||||
|
#define print(...) out_x(, ##__VA_ARGS__, out_2(__VA_ARGS__), out_2(__VA_ARGS__), out_2(__VA_ARGS__), \
|
||||||
|
out_2(__VA_ARGS__), out_2(__VA_ARGS__), out_2(__VA_ARGS__), out_1(__VA_ARGS__))
|
||||||
|
|
||||||
#endif //NECRONDA_SERVER_UTILS_H
|
#endif //NECRONDA_SERVER_UTILS_H
|
||||||
|
Reference in New Issue
Block a user