FastCGI working buggy
This commit is contained in:
77
src/client.c
77
src/client.c
@ -9,6 +9,7 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "uri.h"
|
#include "uri.h"
|
||||||
#include "http.h"
|
#include "http.h"
|
||||||
|
#include "fastcgi.h"
|
||||||
|
|
||||||
|
|
||||||
int server_keep_alive = 1;
|
int server_keep_alive = 1;
|
||||||
@ -22,7 +23,7 @@ char *get_webroot(const char *http_host) {
|
|||||||
unsigned long len = strlen(webroot_base);
|
unsigned long len = strlen(webroot_base);
|
||||||
while (webroot_base[len - 1] == '/') len--;
|
while (webroot_base[len - 1] == '/') len--;
|
||||||
long pos = strchr(http_host, ':') - http_host;
|
long pos = strchr(http_host, ':') - http_host;
|
||||||
sprintf(webroot, "%.*s/%.*s", (int) len, webroot_base, (int) (pos == -1 ? strlen(http_host) : pos), http_host);
|
sprintf(webroot, "%.*s/%.*s", (int) len, webroot_base, (int) (pos < 0 ? strlen(http_host) : pos), http_host);
|
||||||
return webroot;
|
return webroot;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,7 +36,7 @@ int client_websocket_handler() {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int client_request_handler(sock *client, int req_num) {
|
int client_request_handler(sock *client, unsigned long client_num, unsigned int req_num) {
|
||||||
struct timespec begin, end;
|
struct timespec begin, end;
|
||||||
int ret, client_keep_alive, dir_mode;
|
int ret, client_keep_alive, dir_mode;
|
||||||
char buf0[1024], buf1[1024];
|
char buf0[1024], buf1[1024];
|
||||||
@ -43,10 +44,12 @@ int client_request_handler(sock *client, int req_num) {
|
|||||||
char buffer[CHUNK_SIZE];
|
char buffer[CHUNK_SIZE];
|
||||||
err_msg[0] = 0;
|
err_msg[0] = 0;
|
||||||
char *host, *hdr_connection, *webroot;
|
char *host, *hdr_connection, *webroot;
|
||||||
unsigned long content_length = 0;
|
long content_length = 0;
|
||||||
FILE *file = NULL;
|
FILE *file = NULL;
|
||||||
msg_buf[0] = 0;
|
msg_buf[0] = 0;
|
||||||
int accept_if_modified_since = 0;
|
int accept_if_modified_since = 0;
|
||||||
|
int use_fastcgi = 0;
|
||||||
|
fastcgi_conn php_fpm = {.socket = 0, .req_id = 0};
|
||||||
|
|
||||||
http_res res;
|
http_res res;
|
||||||
sprintf(res.version, "1.1");
|
sprintf(res.version, "1.1");
|
||||||
@ -221,21 +224,42 @@ int client_request_handler(sock *client, int req_num) {
|
|||||||
fseek(file, 0, SEEK_END);
|
fseek(file, 0, SEEK_END);
|
||||||
content_length = ftell(file);
|
content_length = ftell(file);
|
||||||
fseek(file, 0, SEEK_SET);
|
fseek(file, 0, SEEK_SET);
|
||||||
|
} else {
|
||||||
|
res.status = http_get_status(200);
|
||||||
|
if (fastcgi_init(&php_fpm, client_num, req_num, client, &req, &uri) != 0) {
|
||||||
|
res.status = http_get_status(502);
|
||||||
|
sprintf(err_msg, "Unable to communicate with PHP-FPM.");
|
||||||
|
goto respond;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strncmp(req.method, "POST", 4) == 0 || strncmp(req.method, "PUT", 3) == 0) {
|
||||||
|
// TODO send content to fastcgi
|
||||||
|
} else {
|
||||||
|
fastcgi_close_stdin(&php_fpm);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *accept_encoding = http_get_header_field(&req.hdr, "Accept-Encoding", HTTP_LOWER);
|
||||||
|
if (accept_encoding != NULL && strstr(accept_encoding, "deflate") != NULL) {
|
||||||
|
//http_add_header_field(&res.hdr, "Content-Encoding", "deflate");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fastcgi_header(&php_fpm, &res, err_msg) != 0) {
|
||||||
|
goto respond;
|
||||||
|
}
|
||||||
|
|
||||||
|
content_length = -1;
|
||||||
|
use_fastcgi = 1;
|
||||||
|
if (http_get_header_field(&res.hdr, "Content-Length", HTTP_PRESERVE_UPPER) == NULL) {
|
||||||
|
http_add_header_field(&res.hdr, "Transfer-Encoding", "chunked");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
respond:
|
respond:
|
||||||
if (server_keep_alive && client_keep_alive) {
|
|
||||||
http_add_header_field(&res.hdr, "Connection", "keep-alive");
|
|
||||||
sprintf(buf0, "timeout=%i, max=%i", CLIENT_TIMEOUT, REQ_PER_CONNECTION);
|
|
||||||
http_add_header_field(&res.hdr, "Keep-Alive", buf0);
|
|
||||||
} else {
|
|
||||||
http_add_header_field(&res.hdr, "Connection", "close");
|
|
||||||
}
|
|
||||||
if (http_get_header_field(&res.hdr, "Accept-Ranges", HTTP_PRESERVE_UPPER) == NULL) {
|
if (http_get_header_field(&res.hdr, "Accept-Ranges", HTTP_PRESERVE_UPPER) == NULL) {
|
||||||
http_add_header_field(&res.hdr, "Accept-Ranges", "none");
|
http_add_header_field(&res.hdr, "Accept-Ranges", "none");
|
||||||
}
|
}
|
||||||
|
if (!use_fastcgi && file == NULL && res.status->code >= 400 && res.status->code < 600) {
|
||||||
if (res.status->code >= 400 && res.status->code < 600) {
|
|
||||||
http_error_msg *http_msg = http_get_error_msg(res.status->code);
|
http_error_msg *http_msg = http_get_error_msg(res.status->code);
|
||||||
sprintf(msg_pre_buf, http_error_document, res.status->code, res.status->msg,
|
sprintf(msg_pre_buf, http_error_document, res.status->code, res.status->msg,
|
||||||
http_msg != NULL ? http_msg->err_msg : "", err_msg[0] != 0 ? err_msg : "");
|
http_msg != NULL ? http_msg->err_msg : "", err_msg[0] != 0 ? err_msg : "");
|
||||||
@ -244,8 +268,19 @@ int client_request_handler(sock *client, int req_num) {
|
|||||||
http_error_icon, "#C00000");
|
http_error_icon, "#C00000");
|
||||||
http_add_header_field(&res.hdr, "Content-Type", "text/html; charset=UTF-8");
|
http_add_header_field(&res.hdr, "Content-Type", "text/html; charset=UTF-8");
|
||||||
}
|
}
|
||||||
sprintf(buf0, "%li", content_length);
|
if (content_length >= 0) {
|
||||||
http_add_header_field(&res.hdr, "Content-Length", buf0);
|
sprintf(buf0, "%li", content_length);
|
||||||
|
http_add_header_field(&res.hdr, "Content-Length", buf0);
|
||||||
|
} else if (http_get_header_field(&res.hdr, "Transfer-Encoding", HTTP_PRESERVE_UPPER) == NULL) {
|
||||||
|
server_keep_alive = 0;
|
||||||
|
}
|
||||||
|
if (server_keep_alive && client_keep_alive) {
|
||||||
|
http_add_header_field(&res.hdr, "Connection", "keep-alive");
|
||||||
|
sprintf(buf0, "timeout=%i, max=%i", CLIENT_TIMEOUT, REQ_PER_CONNECTION);
|
||||||
|
http_add_header_field(&res.hdr, "Keep-Alive", buf0);
|
||||||
|
} else {
|
||||||
|
http_add_header_field(&res.hdr, "Connection", "close");
|
||||||
|
}
|
||||||
|
|
||||||
http_send_response(client, &res);
|
http_send_response(client, &res);
|
||||||
clock_gettime(CLOCK_MONOTONIC, &end);
|
clock_gettime(CLOCK_MONOTONIC, &end);
|
||||||
@ -294,6 +329,12 @@ int client_request_handler(sock *client, int req_num) {
|
|||||||
}
|
}
|
||||||
snd_len += ret;
|
snd_len += ret;
|
||||||
}
|
}
|
||||||
|
} else if (use_fastcgi) {
|
||||||
|
char *transfer_encoding = http_get_header_field(&res.hdr, "Transfer-Encoding", HTTP_PRESERVE_UPPER);
|
||||||
|
int chunked = transfer_encoding != NULL && strncmp(transfer_encoding, "chunked", 7) == 0;
|
||||||
|
char *content_encoding = http_get_header_field(&res.hdr, "Content-Encoding", HTTP_PRESERVE_UPPER);
|
||||||
|
int comp = content_encoding != NULL && strncmp(content_encoding, "deflate", 7) == 0;
|
||||||
|
fastcgi_send(&php_fpm, client, (chunked ? FASTCGI_CHUNKED : 0) | (comp ? FASTCGI_COMPRESS : 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,7 +349,7 @@ int client_request_handler(sock *client, int req_num) {
|
|||||||
return !client_keep_alive;
|
return !client_keep_alive;
|
||||||
}
|
}
|
||||||
|
|
||||||
int client_connection_handler(sock *client) {
|
int client_connection_handler(sock *client, unsigned long client_num) {
|
||||||
struct timespec begin, end;
|
struct timespec begin, end;
|
||||||
int ret, req_num;
|
int ret, req_num;
|
||||||
char buf[16];
|
char buf[16];
|
||||||
@ -344,7 +385,7 @@ int client_connection_handler(sock *client) {
|
|||||||
req_num = 0;
|
req_num = 0;
|
||||||
ret = 0;
|
ret = 0;
|
||||||
while (ret == 0 && server_keep_alive && req_num < REQ_PER_CONNECTION) {
|
while (ret == 0 && server_keep_alive && req_num < REQ_PER_CONNECTION) {
|
||||||
ret = client_request_handler(client, req_num++);
|
ret = client_request_handler(client, client_num, req_num++);
|
||||||
log_prefix = log_conn_prefix;
|
log_prefix = log_conn_prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -363,7 +404,7 @@ int client_connection_handler(sock *client) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int client_handler(sock *client, long client_num, struct sockaddr_in6 *client_addr) {
|
int client_handler(sock *client, unsigned long client_num, struct sockaddr_in6 *client_addr) {
|
||||||
int ret;
|
int ret;
|
||||||
struct sockaddr_in6 *server_addr;
|
struct sockaddr_in6 *server_addr;
|
||||||
struct sockaddr_storage server_addr_storage;
|
struct sockaddr_storage server_addr_storage;
|
||||||
@ -404,7 +445,7 @@ int client_handler(sock *client, long client_num, struct sockaddr_in6 *client_ad
|
|||||||
|
|
||||||
print("Started child process with PID %i", getpid());
|
print("Started child process with PID %i", getpid());
|
||||||
|
|
||||||
ret = client_connection_handler(client);
|
ret = client_connection_handler(client, client_num);
|
||||||
free(client_addr_str_ptr);
|
free(client_addr_str_ptr);
|
||||||
free(server_addr_str_ptr);
|
free(server_addr_str_ptr);
|
||||||
free(log_conn_prefix);
|
free(log_conn_prefix);
|
||||||
|
436
src/fastcgi.c
436
src/fastcgi.c
@ -1,8 +1,442 @@
|
|||||||
/**
|
/**
|
||||||
* Necronda Web Server
|
* Necronda Web Server
|
||||||
* FastCGI implementation
|
* FastCGI interface implementation
|
||||||
* src/fastcgi.c
|
* src/fastcgi.c
|
||||||
* Lorenz Stechauner, 2020-12-26
|
* Lorenz Stechauner, 2020-12-26
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "fastcgi.h"
|
#include "fastcgi.h"
|
||||||
|
#include "necronda-server.h"
|
||||||
|
|
||||||
|
#include <sys/un.h>
|
||||||
|
|
||||||
|
|
||||||
|
char *fastcgi_add_param(char *buf, const char *key, const char *value) {
|
||||||
|
char *ptr = buf;
|
||||||
|
unsigned long key_len = strlen(key);
|
||||||
|
unsigned long val_len = strlen(value);
|
||||||
|
|
||||||
|
|
||||||
|
if (key_len <= 127) {
|
||||||
|
ptr[0] = (char) (key_len & 0x7F);
|
||||||
|
ptr++;
|
||||||
|
} else {
|
||||||
|
ptr[0] = (char) (0x80 | (key_len >> 24));
|
||||||
|
ptr[1] = (char) ((key_len >> 16) & 0xFF);
|
||||||
|
ptr[2] = (char) ((key_len >> 8) & 0xFF);
|
||||||
|
ptr[3] = (char) (key_len & 0xFF);
|
||||||
|
ptr += 4;
|
||||||
|
}
|
||||||
|
if (val_len <= 127) {
|
||||||
|
ptr[0] = (char) (val_len & 0x7F);
|
||||||
|
ptr++;
|
||||||
|
} else {
|
||||||
|
ptr[0] = (char) (0x80 | (val_len >> 24));
|
||||||
|
ptr[1] = (char) ((val_len >> 16) & 0xFF);
|
||||||
|
ptr[2] = (char) ((val_len >> 8) & 0xFF);
|
||||||
|
ptr[3] = (char) (val_len & 0xFF);
|
||||||
|
ptr += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(ptr, key, key_len);
|
||||||
|
ptr += key_len;
|
||||||
|
memcpy(ptr, value, val_len);
|
||||||
|
ptr += val_len;
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
unsigned short req_id = (client_num & 0xFFF) << 4;
|
||||||
|
if (client_num == 0) {
|
||||||
|
req_id |= (req_num + 1) & 0xF;
|
||||||
|
} else {
|
||||||
|
req_id |= req_num & 0xF;
|
||||||
|
}
|
||||||
|
conn->req_id = req_id;
|
||||||
|
conn->out_buf = NULL;
|
||||||
|
conn->out_off = 0;
|
||||||
|
|
||||||
|
int php_fpm = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
|
if (php_fpm < 0) {
|
||||||
|
fprintf(stderr, ERR_STR "Unable to create unix socket: %s" CLR_STR "\n", strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
conn->socket = php_fpm;
|
||||||
|
|
||||||
|
struct sockaddr_un php_fpm_addr = {AF_UNIX, PHP_FPM_SOCKET};
|
||||||
|
if (connect(conn->socket, (struct sockaddr *) &php_fpm_addr, sizeof(php_fpm_addr)) < 0) {
|
||||||
|
fprintf(stderr, ERR_STR "Unable to connect to unix socket of PHP-FPM: %s" CLR_STR "\n", strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
FCGI_Header header = {
|
||||||
|
.version = FCGI_VERSION_1,
|
||||||
|
.requestIdB1 = req_id >> 8,
|
||||||
|
.requestIdB0 = req_id & 0xFF,
|
||||||
|
.paddingLength = 0,
|
||||||
|
.reserved = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
header.type = FCGI_BEGIN_REQUEST;
|
||||||
|
header.contentLengthB1 = 0;
|
||||||
|
header.contentLengthB0 = sizeof(FCGI_BeginRequestBody);
|
||||||
|
FCGI_BeginRequestRecord begin = {
|
||||||
|
header,
|
||||||
|
{.roleB1 = (FCGI_RESPONDER >> 8) & 0xFF, .roleB0 = FCGI_RESPONDER & 0xFF, .flags = 0}
|
||||||
|
};
|
||||||
|
if (send(conn->socket, &begin, sizeof(begin), 0) != sizeof(begin)) {
|
||||||
|
fprintf(stderr, ERR_STR "Unable to send to PHP-FPM: %s" CLR_STR "\n", strerror(errno));
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
char param_buf[4096];
|
||||||
|
char buf0[256];
|
||||||
|
char *param_ptr = param_buf + sizeof(header);
|
||||||
|
|
||||||
|
param_ptr = fastcgi_add_param(param_ptr, "REDIRECT_STATUS", "CGI");
|
||||||
|
param_ptr = fastcgi_add_param(param_ptr, "DOCUMENT_ROOT", uri->webroot);
|
||||||
|
param_ptr = fastcgi_add_param(param_ptr, "GATEWAY_INTERFACE", "CGI/1.1");
|
||||||
|
param_ptr = fastcgi_add_param(param_ptr, "SERVER_SOFTWARE", SERVER_STR);
|
||||||
|
param_ptr = fastcgi_add_param(param_ptr, "SERVER_PROTOCOL", "HTTP/1.1");
|
||||||
|
param_ptr = fastcgi_add_param(param_ptr, "SERVER_NAME", http_get_header_field(&req->hdr, "Host", HTTP_LOWER));
|
||||||
|
if (client->enc) {
|
||||||
|
param_ptr = fastcgi_add_param(param_ptr, "HTTPS", "on");
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sockaddr_storage addr_storage;
|
||||||
|
struct sockaddr_in6 *addr;
|
||||||
|
socklen_t len = sizeof(addr_storage);
|
||||||
|
getsockname(client->socket, (struct sockaddr *) &addr_storage, &len);
|
||||||
|
addr = (struct sockaddr_in6 *) &addr_storage;
|
||||||
|
sprintf(buf0, "%i", addr->sin6_port);
|
||||||
|
param_ptr = fastcgi_add_param(param_ptr, "SERVER_PORT", buf0);
|
||||||
|
|
||||||
|
len = sizeof(addr_storage);
|
||||||
|
getpeername(client->socket, (struct sockaddr *) &addr_storage, &len);
|
||||||
|
addr = (struct sockaddr_in6 *) &addr_storage;
|
||||||
|
sprintf(buf0, "%i", addr->sin6_port);
|
||||||
|
param_ptr = fastcgi_add_param(param_ptr, "REMOTE_PORT", buf0);
|
||||||
|
|
||||||
|
char addr_str[INET6_ADDRSTRLEN];
|
||||||
|
char *addr_ptr;
|
||||||
|
inet_ntop(addr->sin6_family, (void *) &addr->sin6_addr, addr_str, INET6_ADDRSTRLEN);
|
||||||
|
if (strncmp(addr_str, "::ffff:", 7) == 0) {
|
||||||
|
addr_ptr = addr_str + 7;
|
||||||
|
} else {
|
||||||
|
addr_ptr = addr_str;
|
||||||
|
}
|
||||||
|
param_ptr = fastcgi_add_param(param_ptr, "REMOTE_ADDR", addr_ptr);
|
||||||
|
param_ptr = fastcgi_add_param(param_ptr, "REMOTE_HOST", addr_ptr);
|
||||||
|
//param_ptr = fastcgi_add_param(param_ptr, "REMOTE_IDENT", "");
|
||||||
|
//param_ptr = fastcgi_add_param(param_ptr, "REMOTE_USER", "");
|
||||||
|
|
||||||
|
param_ptr = fastcgi_add_param(param_ptr, "REQUEST_METHOD", req->method);
|
||||||
|
param_ptr = fastcgi_add_param(param_ptr, "REQUEST_URI", req->uri);
|
||||||
|
param_ptr = fastcgi_add_param(param_ptr, "SCRIPT_NAME", uri->filename + strlen(uri->webroot));
|
||||||
|
param_ptr = fastcgi_add_param(param_ptr, "SCRIPT_FILENAME", uri->filename);
|
||||||
|
//param_ptr = fastcgi_add_param(param_ptr, "PATH_TRANSLATED", uri->filename);
|
||||||
|
|
||||||
|
param_ptr = fastcgi_add_param(param_ptr, "QUERY_STRING", uri->query != NULL ? uri->query : "");
|
||||||
|
if (uri->pathinfo != NULL && strlen(uri->pathinfo) > 0) {
|
||||||
|
sprintf(buf0, "/%s", uri->pathinfo);
|
||||||
|
} else {
|
||||||
|
sprintf(buf0, "");
|
||||||
|
}
|
||||||
|
param_ptr = fastcgi_add_param(param_ptr, "PATH_INFO", buf0);
|
||||||
|
|
||||||
|
//param_ptr = fastcgi_add_param(param_ptr, "AUTH_TYPE", "");
|
||||||
|
char *content_length = http_get_header_field(&req->hdr, "Content-Length", HTTP_LOWER);
|
||||||
|
param_ptr = fastcgi_add_param(param_ptr, "CONTENT_LENGTH", content_length != NULL ? content_length : "");
|
||||||
|
char *content_type = http_get_header_field(&req->hdr, "Content-Type", HTTP_LOWER);
|
||||||
|
param_ptr = fastcgi_add_param(param_ptr, "CONTENT_TYPE", content_type != NULL ? content_type : "");
|
||||||
|
|
||||||
|
for (int i = 0; i < req->hdr.field_num; i++) {
|
||||||
|
char *ptr = buf0;
|
||||||
|
ptr += sprintf(ptr, "HTTP_");
|
||||||
|
for (int j = 0; j < strlen(req->hdr.fields[i][0]); j++, ptr++) {
|
||||||
|
char ch = req->hdr.fields[i][0][j];
|
||||||
|
if ((ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9')) {
|
||||||
|
ch = ch;
|
||||||
|
} else if (ch >= 'a' && ch <= 'z') {
|
||||||
|
ch &= 0x5F;
|
||||||
|
} else {
|
||||||
|
ch = '_';
|
||||||
|
}
|
||||||
|
ptr[0] = ch;
|
||||||
|
ptr[1] = 0;
|
||||||
|
}
|
||||||
|
param_ptr = fastcgi_add_param(param_ptr, buf0, req->hdr.fields[i][1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned short param_len = param_ptr - param_buf - sizeof(header);
|
||||||
|
header.type = FCGI_PARAMS;
|
||||||
|
header.contentLengthB1 = param_len >> 8;
|
||||||
|
header.contentLengthB0 = param_len & 0xFF;
|
||||||
|
memcpy(param_buf, &header, sizeof(header));
|
||||||
|
if (send(conn->socket, param_buf, param_len + sizeof(header), 0) != param_len + sizeof(header)) {
|
||||||
|
fprintf(stderr, ERR_STR "Unable to send to PHP-FPM: %s" CLR_STR "\n", strerror(errno));
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *f = fopen("/home/lorenz/Desktop/test.dmp", "wb");
|
||||||
|
fwrite(param_buf, 1, param_len, f);
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
header.type = FCGI_PARAMS;
|
||||||
|
header.contentLengthB1 = 0;
|
||||||
|
header.contentLengthB0 = 0;
|
||||||
|
if (send(conn->socket, &header, sizeof(header), 0) != sizeof(header)) {
|
||||||
|
fprintf(stderr, ERR_STR "Unable to send to PHP-FPM: %s" CLR_STR "\n", strerror(errno));
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fastcgi_close_stdin(fastcgi_conn *conn) {
|
||||||
|
FCGI_Header header = {
|
||||||
|
.version = FCGI_VERSION_1,
|
||||||
|
.type = FCGI_STDIN,
|
||||||
|
.requestIdB1 = conn->req_id >> 8,
|
||||||
|
.requestIdB0 = conn->req_id & 0xFF,
|
||||||
|
.contentLengthB1 = 0,
|
||||||
|
.contentLengthB0 = 0,
|
||||||
|
.paddingLength = 0,
|
||||||
|
.reserved = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
if (send(conn->socket, &header, sizeof(header), 0) != sizeof(header)) {
|
||||||
|
fprintf(stderr, ERR_STR "Unable to send to PHP-FPM: %s" CLR_STR "\n", strerror(errno));
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fastcgi_php_error(char *msg, int msg_len, char *err_msg) {
|
||||||
|
char *msg_str = malloc(msg_len + 1);
|
||||||
|
char *ptr0 = msg_str;
|
||||||
|
strncpy(msg_str, msg, msg_len);
|
||||||
|
char *ptr1 = NULL;
|
||||||
|
int len;
|
||||||
|
int err = 0;
|
||||||
|
while (1) {
|
||||||
|
ptr1 = strstr(ptr0, "PHP message: ");
|
||||||
|
if (ptr1 == NULL) {
|
||||||
|
len = (int) (msg_len - (ptr0 - msg_str));
|
||||||
|
} else {
|
||||||
|
len = (int) (ptr1 - ptr0);
|
||||||
|
}
|
||||||
|
if (len == 0) {
|
||||||
|
goto next;
|
||||||
|
}
|
||||||
|
|
||||||
|
int msg_type = 0;
|
||||||
|
int msg_pre_len = 0;
|
||||||
|
if (len >= 14 && strncmp(ptr0, "PHP Warning: ", 14) == 0) {
|
||||||
|
msg_type = 1;
|
||||||
|
msg_pre_len = 14;
|
||||||
|
} else if (len >= 18 && strncmp(ptr0, "PHP Fatal error: ", 18) == 0) {
|
||||||
|
msg_type = 2;
|
||||||
|
msg_pre_len = 18;
|
||||||
|
} else if (len >= 18 && strncmp(ptr0, "PHP Parse error: ", 18) == 0) {
|
||||||
|
msg_type = 2;
|
||||||
|
msg_pre_len = 18;
|
||||||
|
} else if (len >= 18 && strncmp(ptr0, "PHP Notice: ", 13) == 0) {
|
||||||
|
msg_type = 1;
|
||||||
|
msg_pre_len = 13;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *ptr2 = ptr0;
|
||||||
|
char *ptr3;
|
||||||
|
int len2;
|
||||||
|
while (ptr2 - ptr0 < len) {
|
||||||
|
ptr3 = strchr(ptr2, '\n');
|
||||||
|
len2 = (int) (len - (ptr2 - ptr0));
|
||||||
|
if (ptr3 != NULL && (ptr3 - ptr2) < len2) {
|
||||||
|
len2 = (int) (ptr3 - ptr2);
|
||||||
|
}
|
||||||
|
print("%s%.*s%s", msg_type == 1 ? WRN_STR : msg_type == 2 ? ERR_STR: "", len2, ptr2, msg_type != 0 ? CLR_STR : "");
|
||||||
|
if (msg_type == 2 && ptr2 == ptr0) {
|
||||||
|
sprintf(err_msg, "%.*s", len2, ptr2);
|
||||||
|
err = 1;
|
||||||
|
}
|
||||||
|
if (ptr3 == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ptr2 = ptr3 + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
next:
|
||||||
|
if (ptr1 == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ptr0 = ptr1 + 13;
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fastcgi_header(fastcgi_conn *conn, http_res *res, char *err_msg) {
|
||||||
|
FCGI_Header header;
|
||||||
|
char *content;
|
||||||
|
unsigned short content_len, req_id;
|
||||||
|
int ret;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
ret = recv(conn->socket, &header, sizeof(header), 0);
|
||||||
|
if (ret < 0) {
|
||||||
|
res->status = http_get_status(502);
|
||||||
|
sprintf(err_msg, "Unable to communicate with PHP-FPM.");
|
||||||
|
fprintf(stderr, ERR_STR "Unable to receive from PHP-FPM: %s" CLR_STR "\n", strerror(errno));
|
||||||
|
return -1;
|
||||||
|
} else if (ret != sizeof(header)) {
|
||||||
|
res->status = http_get_status(502);
|
||||||
|
sprintf(err_msg, "Unable to communicate with PHP-FPM.");
|
||||||
|
fprintf(stderr, ERR_STR "Unable to receive from PHP-FPM" CLR_STR "\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
req_id = (header.requestIdB1 << 8) | header.requestIdB0;
|
||||||
|
content_len = (header.contentLengthB1 << 8) | header.contentLengthB0;
|
||||||
|
content = malloc(content_len + header.paddingLength);
|
||||||
|
ret = recv(conn->socket, content, content_len + header.paddingLength, 0);
|
||||||
|
if (ret < 0) {
|
||||||
|
res->status = http_get_status(502);
|
||||||
|
sprintf(err_msg, "Unable to communicate with PHP-FPM.");
|
||||||
|
fprintf(stderr, ERR_STR "Unable to receive from PHP-FPM: %s" CLR_STR "\n", strerror(errno));
|
||||||
|
free(content);
|
||||||
|
return -1;
|
||||||
|
} else if (ret != (content_len + header.paddingLength)) {
|
||||||
|
res->status = http_get_status(502);
|
||||||
|
sprintf(err_msg, "Unable to communicate with PHP-FPM.");
|
||||||
|
fprintf(stderr, ERR_STR "Unable to receive from PHP-FPM" CLR_STR "\n");
|
||||||
|
free(content);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req_id != conn->req_id) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (header.type == FCGI_END_REQUEST) {
|
||||||
|
FCGI_EndRequestBody *body = (FCGI_EndRequestBody *) content;
|
||||||
|
int app_status = (body->appStatusB3 << 24) | (body->appStatusB2 << 16) | (body->appStatusB1 << 8) |
|
||||||
|
body->appStatusB0;
|
||||||
|
if (body->protocolStatus != FCGI_REQUEST_COMPLETE) {
|
||||||
|
print(ERR_STR "FastCGI protocol error: %i" CLR_STR, body->protocolStatus);
|
||||||
|
}
|
||||||
|
if (app_status != 0) {
|
||||||
|
print(ERR_STR "Script terminated with exit code %i" CLR_STR, app_status);
|
||||||
|
}
|
||||||
|
close(conn->socket);
|
||||||
|
conn->socket = 0;
|
||||||
|
free(content);
|
||||||
|
return -2;
|
||||||
|
} else if (header.type == FCGI_STDERR) {
|
||||||
|
err = err || fastcgi_php_error(content, content_len, err_msg);
|
||||||
|
} else if (header.type == FCGI_STDOUT) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, ERR_STR "Unknown FastCGI type: %i" CLR_STR "\n", header.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(content);
|
||||||
|
}
|
||||||
|
if (err) {
|
||||||
|
res->status = http_get_status(500);
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
conn->out_buf = content;
|
||||||
|
conn->out_len = content_len;
|
||||||
|
conn->out_off = (unsigned short) (strstr(content, "\r\n\r\n") - content + 4);
|
||||||
|
|
||||||
|
// TODO process headers and add fields to res
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fastcgi_send(fastcgi_conn *conn, sock *client, int flags) {
|
||||||
|
FCGI_Header header;
|
||||||
|
int ret;
|
||||||
|
char buf0[256];
|
||||||
|
int len;
|
||||||
|
char *content, *ptr;
|
||||||
|
unsigned short req_id, content_len;
|
||||||
|
|
||||||
|
if (conn->out_buf != NULL && conn->out_len > conn->out_off) {
|
||||||
|
content = conn->out_buf;
|
||||||
|
ptr = content + conn->out_off;
|
||||||
|
content_len = conn->out_len - conn->out_off;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
ret = recv(conn->socket, &header, sizeof(header), 0);
|
||||||
|
if (ret < 0) {
|
||||||
|
fprintf(stderr, ERR_STR "Unable to receive from PHP-FPM: %s" CLR_STR "\n", strerror(errno));
|
||||||
|
return -1;
|
||||||
|
} else if (ret != sizeof(header)) {
|
||||||
|
fprintf(stderr, ERR_STR "Unable to receive from PHP-FPM" CLR_STR "\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
req_id = (header.requestIdB1 << 8) | header.requestIdB0;
|
||||||
|
content_len = (header.contentLengthB1 << 8) | header.contentLengthB0;
|
||||||
|
content = malloc(content_len + header.paddingLength);
|
||||||
|
ptr = content;
|
||||||
|
ret = recv(conn->socket, content, content_len + header.paddingLength, 0);
|
||||||
|
if (ret < 0) {
|
||||||
|
fprintf(stderr, ERR_STR "Unable to receive from PHP-FPM: %s" CLR_STR "\n", strerror(errno));
|
||||||
|
free(content);
|
||||||
|
return -1;
|
||||||
|
} else if (ret != (content_len + header.paddingLength)) {
|
||||||
|
fprintf(stderr, ERR_STR "Unable to receive from PHP-FPM" CLR_STR "\n");
|
||||||
|
free(content);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (header.type == FCGI_END_REQUEST) {
|
||||||
|
FCGI_EndRequestBody *body = (FCGI_EndRequestBody *) content;
|
||||||
|
int app_status = (body->appStatusB3 << 24) | (body->appStatusB2 << 16) | (body->appStatusB1 << 8) |
|
||||||
|
body->appStatusB0;
|
||||||
|
if (body->protocolStatus != FCGI_REQUEST_COMPLETE) {
|
||||||
|
print(ERR_STR "FastCGI protocol error: %i" CLR_STR, body->protocolStatus);
|
||||||
|
}
|
||||||
|
if (app_status != 0) {
|
||||||
|
print(ERR_STR "Script terminated with exit code %i" CLR_STR, app_status);
|
||||||
|
}
|
||||||
|
close(conn->socket);
|
||||||
|
conn->socket = 0;
|
||||||
|
free(content);
|
||||||
|
|
||||||
|
if (flags & FASTCGI_CHUNKED) {
|
||||||
|
if (client->enc) {
|
||||||
|
SSL_write(client->ssl, "0\r\n\r\n", 5);
|
||||||
|
} else {
|
||||||
|
send(client->socket, "0\r\n\r\n", 5, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
} else if (header.type == FCGI_STDERR) {
|
||||||
|
print(ERR_STR "%.*s" CLR_STR, content_len, content);
|
||||||
|
} else if (header.type == FCGI_STDOUT) {
|
||||||
|
out:
|
||||||
|
len = sprintf(buf0, "%X\r\n", content_len);
|
||||||
|
if (client->enc) {
|
||||||
|
if (flags & FASTCGI_CHUNKED) SSL_write(client->ssl, buf0, len);
|
||||||
|
SSL_write(client->ssl, ptr, content_len);
|
||||||
|
if (flags & FASTCGI_CHUNKED) SSL_write(client->ssl, "\r\n", 2);
|
||||||
|
} else {
|
||||||
|
if (flags & FASTCGI_CHUNKED) send(client->socket, buf0, len, 0);
|
||||||
|
send(client->socket, ptr, content_len, 0);
|
||||||
|
if (flags & FASTCGI_CHUNKED) send(client->socket, "\r\n", 2, 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, ERR_STR "Unknown FastCGI type: %i" CLR_STR "\n", header.type);
|
||||||
|
}
|
||||||
|
free(content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
136
src/fastcgi.h
136
src/fastcgi.h
@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Necronda Web Server
|
* Necronda Web Server
|
||||||
* FastCGI implementation (header file)
|
* FastCGI interface implementation (header file)
|
||||||
* src/fastcgi.h
|
* src/fastcgi.h
|
||||||
* Lorenz Stechauner, 2020-12-26
|
* Lorenz Stechauner, 2020-12-26
|
||||||
*/
|
*/
|
||||||
@ -8,4 +8,138 @@
|
|||||||
#ifndef NECRONDA_SERVER_FASTCGI_H
|
#ifndef NECRONDA_SERVER_FASTCGI_H
|
||||||
#define NECRONDA_SERVER_FASTCGI_H
|
#define NECRONDA_SERVER_FASTCGI_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_header(fastcgi_conn *conn, http_res *res, char *err_msg);
|
||||||
|
|
||||||
|
int fastcgi_send(fastcgi_conn *conn, sock *client, int flags);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Listening socket file number
|
||||||
|
*/
|
||||||
|
#define FCGI_LISTENSOCK_FILENO 0
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned char version;
|
||||||
|
unsigned char type;
|
||||||
|
unsigned char requestIdB1;
|
||||||
|
unsigned char requestIdB0;
|
||||||
|
unsigned char contentLengthB1;
|
||||||
|
unsigned char contentLengthB0;
|
||||||
|
unsigned char paddingLength;
|
||||||
|
unsigned char reserved;
|
||||||
|
} FCGI_Header;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Number of bytes in a FCGI_Header. Future versions of the protocol
|
||||||
|
* will not reduce this number.
|
||||||
|
*/
|
||||||
|
#define FCGI_HEADER_LEN 8
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Value for version component of FCGI_Header
|
||||||
|
*/
|
||||||
|
#define FCGI_VERSION_1 1
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Values for type component of FCGI_Header
|
||||||
|
*/
|
||||||
|
#define FCGI_BEGIN_REQUEST 1
|
||||||
|
#define FCGI_ABORT_REQUEST 2
|
||||||
|
#define FCGI_END_REQUEST 3
|
||||||
|
#define FCGI_PARAMS 4
|
||||||
|
#define FCGI_STDIN 5
|
||||||
|
#define FCGI_STDOUT 6
|
||||||
|
#define FCGI_STDERR 7
|
||||||
|
#define FCGI_DATA 8
|
||||||
|
#define FCGI_GET_VALUES 9
|
||||||
|
#define FCGI_GET_VALUES_RESULT 10
|
||||||
|
#define FCGI_UNKNOWN_TYPE 11
|
||||||
|
#define FCGI_MAXTYPE (FCGI_UNKNOWN_TYPE)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Value for requestId component of FCGI_Header
|
||||||
|
*/
|
||||||
|
#define FCGI_NULL_REQUEST_ID 0
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned char roleB1;
|
||||||
|
unsigned char roleB0;
|
||||||
|
unsigned char flags;
|
||||||
|
unsigned char reserved[5];
|
||||||
|
} FCGI_BeginRequestBody;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
FCGI_Header header;
|
||||||
|
FCGI_BeginRequestBody body;
|
||||||
|
} FCGI_BeginRequestRecord;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Mask for flags component of FCGI_BeginRequestBody
|
||||||
|
*/
|
||||||
|
#define FCGI_KEEP_CONN 1
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Values for role component of FCGI_BeginRequestBody
|
||||||
|
*/
|
||||||
|
#define FCGI_RESPONDER 1
|
||||||
|
#define FCGI_AUTHORIZER 2
|
||||||
|
#define FCGI_FILTER 3
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned char appStatusB3;
|
||||||
|
unsigned char appStatusB2;
|
||||||
|
unsigned char appStatusB1;
|
||||||
|
unsigned char appStatusB0;
|
||||||
|
unsigned char protocolStatus;
|
||||||
|
unsigned char reserved[3];
|
||||||
|
} FCGI_EndRequestBody;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
FCGI_Header header;
|
||||||
|
FCGI_EndRequestBody body;
|
||||||
|
} FCGI_EndRequestRecord;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Values for protocolStatus component of FCGI_EndRequestBody
|
||||||
|
*/
|
||||||
|
#define FCGI_REQUEST_COMPLETE 0
|
||||||
|
#define FCGI_CANT_MPX_CONN 1
|
||||||
|
#define FCGI_OVERLOADED 2
|
||||||
|
#define FCGI_UNKNOWN_ROLE 3
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Variable names for FCGI_GET_VALUES / FCGI_GET_VALUES_RESULT records
|
||||||
|
*/
|
||||||
|
#define FCGI_MAX_CONNS "FCGI_MAX_CONNS"
|
||||||
|
#define FCGI_MAX_REQS "FCGI_MAX_REQS"
|
||||||
|
#define FCGI_MPXS_CONNS "FCGI_MPXS_CONNS"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned char type;
|
||||||
|
unsigned char reserved[7];
|
||||||
|
} FCGI_UnknownTypeBody;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
FCGI_Header header;
|
||||||
|
FCGI_UnknownTypeBody body;
|
||||||
|
} FCGI_UnknownTypeRecord;
|
||||||
|
|
||||||
#endif //NECRONDA_SERVER_FASTCGI_H
|
#endif //NECRONDA_SERVER_FASTCGI_H
|
||||||
|
@ -156,7 +156,7 @@ int http_receive_request(sock *client, http_req *req) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char *http_get_header_field(http_hdr *hdr, const char *field_name, int strict) {
|
char *http_get_header_field(const http_hdr *hdr, const char *field_name, int strict) {
|
||||||
size_t len = strlen(field_name);
|
size_t len = strlen(field_name);
|
||||||
char *_field_name = malloc(len + 1);
|
char *_field_name = malloc(len + 1);
|
||||||
strcpy(_field_name, field_name);
|
strcpy(_field_name, field_name);
|
||||||
|
@ -164,7 +164,7 @@ void http_free_res(http_res *res);
|
|||||||
|
|
||||||
int http_receive_request(sock *client, http_req *req);
|
int http_receive_request(sock *client, http_req *req);
|
||||||
|
|
||||||
char *http_get_header_field(http_hdr *hdr, const char *field_name, int strict);
|
char *http_get_header_field(const http_hdr *hdr, const char *field_name, int strict);
|
||||||
|
|
||||||
void http_add_header_field(http_hdr *hdr, const char *field_name, const char *field_value);
|
void http_add_header_field(http_hdr *hdr, const char *field_name, const char *field_value);
|
||||||
|
|
||||||
|
@ -238,23 +238,23 @@ int main(int argc, const char *argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sockets[0] = socket(AF_INET6, SOCK_STREAM, 0);
|
sockets[0] = socket(AF_INET6, SOCK_STREAM, 0);
|
||||||
if (sockets[0] == -1) goto socket_err;
|
if (sockets[0] < 0) goto socket_err;
|
||||||
sockets[1] = socket(AF_INET6, SOCK_STREAM, 0);
|
sockets[1] = socket(AF_INET6, SOCK_STREAM, 0);
|
||||||
if (sockets[1] == -1) {
|
if (sockets[1] < 0) {
|
||||||
socket_err:
|
socket_err:
|
||||||
fprintf(stderr, ERR_STR "Unable to create socket: %s" CLR_STR "\n", strerror(errno));
|
fprintf(stderr, ERR_STR "Unable to create socket: %s" CLR_STR "\n", strerror(errno));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < NUM_SOCKETS; i++) {
|
for (int i = 0; i < NUM_SOCKETS; i++) {
|
||||||
if (setsockopt(sockets[i], SOL_SOCKET, SO_REUSEADDR, &YES, sizeof(YES)) == -1) {
|
if (setsockopt(sockets[i], SOL_SOCKET, SO_REUSEADDR, &YES, sizeof(YES)) < 0) {
|
||||||
fprintf(stderr, ERR_STR "Unable to set options for socket %i: %s" CLR_STR "\n", i, strerror(errno));
|
fprintf(stderr, ERR_STR "Unable to set options for socket %i: %s" CLR_STR "\n", i, strerror(errno));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bind(sockets[0], (struct sockaddr *) &addresses[0], sizeof(addresses[0])) == -1) goto bind_err;
|
if (bind(sockets[0], (struct sockaddr *) &addresses[0], sizeof(addresses[0])) < 0) goto bind_err;
|
||||||
if (bind(sockets[1], (struct sockaddr *) &addresses[1], sizeof(addresses[1])) == -1) {
|
if (bind(sockets[1], (struct sockaddr *) &addresses[1], sizeof(addresses[1])) < 0) {
|
||||||
bind_err:
|
bind_err:
|
||||||
fprintf(stderr, ERR_STR "Unable to bind socket to address: %s" CLR_STR "\n", strerror(errno));
|
fprintf(stderr, ERR_STR "Unable to bind socket to address: %s" CLR_STR "\n", strerror(errno));
|
||||||
return 1;
|
return 1;
|
||||||
@ -294,7 +294,7 @@ int main(int argc, const char *argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < NUM_SOCKETS; i++) {
|
for (int i = 0; i < NUM_SOCKETS; i++) {
|
||||||
if (listen(sockets[i], LISTEN_BACKLOG) == -1) {
|
if (listen(sockets[i], LISTEN_BACKLOG) < 0) {
|
||||||
fprintf(stderr, ERR_STR "Unable to listen on socket %i: %s" CLR_STR "\n", i, strerror(errno));
|
fprintf(stderr, ERR_STR "Unable to listen on socket %i: %s" CLR_STR "\n", i, strerror(errno));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -315,7 +315,7 @@ int main(int argc, const char *argv[]) {
|
|||||||
timeout.tv_usec = 0;
|
timeout.tv_usec = 0;
|
||||||
read_socket_fds = socket_fds;
|
read_socket_fds = socket_fds;
|
||||||
ready_sockets_num = select(max_socket_fd + 1, &read_socket_fds, NULL, NULL, &timeout);
|
ready_sockets_num = select(max_socket_fd + 1, &read_socket_fds, NULL, NULL, &timeout);
|
||||||
if (ready_sockets_num == -1) {
|
if (ready_sockets_num < 0) {
|
||||||
fprintf(stderr, ERR_STR "Unable to select sockets: %s" CLR_STR "\n", strerror(errno));
|
fprintf(stderr, ERR_STR "Unable to select sockets: %s" CLR_STR "\n", strerror(errno));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -323,7 +323,7 @@ int main(int argc, const char *argv[]) {
|
|||||||
for (int i = 0; i < NUM_SOCKETS; i++) {
|
for (int i = 0; i < NUM_SOCKETS; i++) {
|
||||||
if (FD_ISSET(sockets[i], &read_socket_fds)) {
|
if (FD_ISSET(sockets[i], &read_socket_fds)) {
|
||||||
client_fd = accept(sockets[i], (struct sockaddr *) &client_addr, &client_addr_len);
|
client_fd = accept(sockets[i], (struct sockaddr *) &client_addr, &client_addr_len);
|
||||||
if (client_fd == -1) {
|
if (client_fd < 0) {
|
||||||
fprintf(stderr, ERR_STR "Unable to accept connection: %s" CLR_STR "\n", strerror(errno));
|
fprintf(stderr, ERR_STR "Unable to accept connection: %s" CLR_STR "\n", strerror(errno));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
#define ERR_STR "\x1B[1;31m"
|
#define ERR_STR "\x1B[1;31m"
|
||||||
#define CLR_STR "\x1B[0m"
|
#define CLR_STR "\x1B[0m"
|
||||||
#define BLD_STR "\x1B[1m"
|
#define BLD_STR "\x1B[1m"
|
||||||
|
#define WRN_STR "\x1B[1;33m"
|
||||||
#define HTTP_STR "\x1B[1;31m"
|
#define HTTP_STR "\x1B[1;31m"
|
||||||
#define HTTPS_STR "\x1B[1;32m"
|
#define HTTPS_STR "\x1B[1;32m"
|
||||||
|
|
||||||
@ -56,6 +57,7 @@
|
|||||||
#define NECRONDA_ZLIB_LEVEL 9
|
#define NECRONDA_ZLIB_LEVEL 9
|
||||||
|
|
||||||
#define MAGIC_FILE "/usr/share/file/misc/magic.mgc"
|
#define MAGIC_FILE "/usr/share/file/misc/magic.mgc"
|
||||||
|
#define PHP_FPM_SOCKET "/var/run/php-fpm/php-fpm.sock"
|
||||||
|
|
||||||
int sockets[NUM_SOCKETS];
|
int sockets[NUM_SOCKETS];
|
||||||
pid_t children[MAX_CHILDREN];
|
pid_t children[MAX_CHILDREN];
|
||||||
|
Reference in New Issue
Block a user