Compare commits
5 Commits
63b1ca5d6a
...
1859c432c8
Author | SHA1 | Date | |
---|---|---|---|
1859c432c8
|
|||
33ec943e8b
|
|||
b30f9fa56d
|
|||
90e324cf87
|
|||
e7e1e7b18f
|
8
Makefile
8
Makefile
@@ -11,6 +11,8 @@ default: bin bin/lib bin/libsesimos.so bin/sesimos
|
|||||||
prod: CFLAGS += -O3
|
prod: CFLAGS += -O3
|
||||||
prod: default
|
prod: default
|
||||||
debug: default
|
debug: default
|
||||||
|
debian: CFLAGS += $(DEBIAN_OPTS)
|
||||||
|
debian: prod
|
||||||
|
|
||||||
|
|
||||||
bin:
|
bin:
|
||||||
@@ -29,10 +31,10 @@ bin/lib/%.o: src/lib/%.c
|
|||||||
bin/libsesimos.so: bin/lib/cache.o bin/lib/compress.o bin/lib/config.o bin/lib/fastcgi.o bin/lib/geoip.o \
|
bin/libsesimos.so: bin/lib/cache.o bin/lib/compress.o bin/lib/config.o bin/lib/fastcgi.o bin/lib/geoip.o \
|
||||||
bin/lib/http.o bin/lib/http_static.o bin/lib/rev_proxy.o bin/lib/sock.o bin/lib/uri.o \
|
bin/lib/http.o bin/lib/http_static.o bin/lib/rev_proxy.o bin/lib/sock.o bin/lib/uri.o \
|
||||||
bin/lib/utils.o bin/lib/websocket.o
|
bin/lib/utils.o bin/lib/websocket.o
|
||||||
$(CC) -o $@ --shared -fPIC $(CFLAGS) $(LIBS) $^
|
$(CC) -o $@ --shared -fPIC $(CFLAGS) $^ $(LIBS)
|
||||||
|
|
||||||
bin/sesimos: bin/server.o bin/client.o
|
bin/sesimos: bin/server.o bin/client.o
|
||||||
$(CC) -o $@ $^ $(LIBS) -Lbin -lsesimos -Wl,-rpath=$(shell pwd)/bin
|
$(CC) -o $@ $^ $(CFLAGS) -Lbin -lsesimos -Wl,-rpath=$(shell pwd)/bin $(LIBS)
|
||||||
|
|
||||||
|
|
||||||
bin/server.o: src/server.c src/server.h src/defs.h src/client.h src/lib/cache.h src/lib/config.h src/lib/sock.h \
|
bin/server.o: src/server.c src/server.h src/defs.h src/client.h src/lib/cache.h src/lib/config.h src/lib/sock.h \
|
||||||
@@ -70,4 +72,4 @@ permit:
|
|||||||
sudo setcap 'cap_net_bind_service=+ep' "$(shell pwd)/bin/sesimos"
|
sudo setcap 'cap_net_bind_service=+ep' "$(shell pwd)/bin/sesimos"
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf sesimos bin/*
|
rm -rf bin/*
|
||||||
|
37
src/client.c
37
src/client.c
@@ -201,12 +201,6 @@ int client_request_handler(sock *client, unsigned long client_num, unsigned int
|
|||||||
goto respond;
|
goto respond;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (http_get_header_field(&req.hdr, "Transfer-Encoding") != NULL) {
|
|
||||||
sprintf(err_msg, "This server is unable to process requests with the Transfer-Encoding header field.");
|
|
||||||
res.status = http_get_status(501);
|
|
||||||
goto respond;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (conf->type == CONFIG_TYPE_LOCAL) {
|
if (conf->type == CONFIG_TYPE_LOCAL) {
|
||||||
if (strcmp(req.method, "TRACE") == 0) {
|
if (strcmp(req.method, "TRACE") == 0) {
|
||||||
res.status = http_get_status(200);
|
res.status = http_get_status(200);
|
||||||
@@ -254,7 +248,7 @@ int client_request_handler(sock *client, unsigned long client_num, unsigned int
|
|||||||
goto respond;
|
goto respond;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (http_get_header_field(&req.hdr, "Content-Length") != NULL) {
|
if (http_get_header_field(&req.hdr, "Content-Length") != NULL || http_get_header_field(&req.hdr, "Transfer-Encoding") != NULL) {
|
||||||
res.status = http_get_status(400);
|
res.status = http_get_status(400);
|
||||||
sprintf(err_msg, "A GET request must not contain a payload");
|
sprintf(err_msg, "A GET request must not contain a payload");
|
||||||
goto respond;
|
goto respond;
|
||||||
@@ -397,18 +391,23 @@ int client_request_handler(sock *client, unsigned long client_num, unsigned int
|
|||||||
}
|
}
|
||||||
|
|
||||||
const char *client_content_length = http_get_header_field(&req.hdr, "Content-Length");
|
const char *client_content_length = http_get_header_field(&req.hdr, "Content-Length");
|
||||||
|
const char *client_transfer_encoding = http_get_header_field(&req.hdr, "Transfer-Encoding");
|
||||||
if (client_content_length != NULL) {
|
if (client_content_length != NULL) {
|
||||||
unsigned long client_content_len = strtoul(client_content_length, NULL, 10);
|
unsigned long client_content_len = strtoul(client_content_length, NULL, 10);
|
||||||
ret = fastcgi_receive(&fcgi_conn, client, client_content_len);
|
ret = fastcgi_receive(&fcgi_conn, client, client_content_len);
|
||||||
if (ret != 0) {
|
} else if (client_transfer_encoding != NULL && strstr(client_transfer_encoding, "chunked") != NULL) {
|
||||||
if (ret < 0) {
|
ret = fastcgi_receive_chunked(&fcgi_conn, client);
|
||||||
goto abort;
|
} else {
|
||||||
} else {
|
ret = 0;
|
||||||
sprintf(err_msg, "Unable to communicate with FastCGI socket.");
|
}
|
||||||
}
|
if (ret != 0) {
|
||||||
res.status = http_get_status(502);
|
if (ret < 0) {
|
||||||
goto respond;
|
goto abort;
|
||||||
|
} else {
|
||||||
|
sprintf(err_msg, "Unable to communicate with FastCGI socket.");
|
||||||
}
|
}
|
||||||
|
res.status = http_get_status(502);
|
||||||
|
goto respond;
|
||||||
}
|
}
|
||||||
fastcgi_close_stdin(&fcgi_conn);
|
fastcgi_close_stdin(&fcgi_conn);
|
||||||
|
|
||||||
@@ -679,7 +678,7 @@ int client_request_handler(sock *client, unsigned long client_num, unsigned int
|
|||||||
}
|
}
|
||||||
} else if (use_fastcgi) {
|
} else if (use_fastcgi) {
|
||||||
const char *transfer_encoding = http_get_header_field(&res.hdr, "Transfer-Encoding");
|
const char *transfer_encoding = http_get_header_field(&res.hdr, "Transfer-Encoding");
|
||||||
int chunked = (transfer_encoding != NULL && strcmp(transfer_encoding, "chunked") == 0);
|
int chunked = (transfer_encoding != NULL && strstr(transfer_encoding, "chunked") != NULL);
|
||||||
|
|
||||||
int flags = (chunked ? FASTCGI_CHUNKED : 0) | (use_fastcgi & (FASTCGI_COMPRESS | FASTCGI_COMPRESS_HOLD));
|
int flags = (chunked ? FASTCGI_CHUNKED : 0) | (use_fastcgi & (FASTCGI_COMPRESS | FASTCGI_COMPRESS_HOLD));
|
||||||
ret = fastcgi_send(&fcgi_conn, client, flags);
|
ret = fastcgi_send(&fcgi_conn, client, flags);
|
||||||
@@ -720,12 +719,6 @@ int client_request_handler(sock *client, unsigned long client_num, unsigned int
|
|||||||
}
|
}
|
||||||
http_free_req(&req);
|
http_free_req(&req);
|
||||||
http_free_res(&res);
|
http_free_res(&res);
|
||||||
if (client->buf != NULL) {
|
|
||||||
free(client->buf);
|
|
||||||
client->buf = NULL;
|
|
||||||
client->buf_off = 0;
|
|
||||||
client->buf_len = 0;
|
|
||||||
}
|
|
||||||
return !client_keep_alive;
|
return !client_keep_alive;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -600,12 +600,6 @@ int fastcgi_receive(fastcgi_conn *conn, sock *client, unsigned long len) {
|
|||||||
.reserved = 0
|
.reserved = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
if (client->buf != NULL && client->buf_len - client->buf_off > 0) {
|
|
||||||
ret = (int) (client->buf_len - client->buf_off);
|
|
||||||
memcpy(buf, client->buf + client->buf_off, ret);
|
|
||||||
goto send;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (rcv_len < len) {
|
while (rcv_len < len) {
|
||||||
ret = sock_recv(client, buf, sizeof(buf), 0);
|
ret = sock_recv(client, buf, sizeof(buf), 0);
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
@@ -613,7 +607,6 @@ int fastcgi_receive(fastcgi_conn *conn, sock *client, unsigned long len) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
send:
|
|
||||||
rcv_len += ret;
|
rcv_len += ret;
|
||||||
header.contentLengthB1 = (ret >> 8) & 0xFF;
|
header.contentLengthB1 = (ret >> 8) & 0xFF;
|
||||||
header.contentLengthB0 = ret & 0xFF;
|
header.contentLengthB0 = ret & 0xFF;
|
||||||
@@ -626,3 +619,25 @@ int fastcgi_receive(fastcgi_conn *conn, sock *client, unsigned long len) {
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int fastcgi_receive_chunked(fastcgi_conn *conn, sock *client) {
|
||||||
|
long ret;
|
||||||
|
unsigned long next_len;
|
||||||
|
char tmp[16];
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
ret = sock_recv(client, tmp, sizeof(tmp), MSG_PEEK);
|
||||||
|
if (ret < 0) return -2;
|
||||||
|
next_len = strtol(tmp, NULL, 16);
|
||||||
|
char *ptr = strstr(tmp, "\r\n");
|
||||||
|
ret = sock_recv(client, tmp, ptr - tmp + 2, 0);
|
||||||
|
if (ret < 0) return -2;
|
||||||
|
|
||||||
|
if (next_len <= 0) break;
|
||||||
|
|
||||||
|
ret = fastcgi_receive(conn, client, next_len);
|
||||||
|
if (ret < 0) return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -55,4 +55,6 @@ int fastcgi_dump(fastcgi_conn *conn, char *buf, long len);
|
|||||||
|
|
||||||
int fastcgi_receive(fastcgi_conn *conn, sock *client, unsigned long len);
|
int fastcgi_receive(fastcgi_conn *conn, sock *client, unsigned long len);
|
||||||
|
|
||||||
|
int fastcgi_receive_chunked(fastcgi_conn *conn, sock *client);
|
||||||
|
|
||||||
#endif //SESIMOS_FASTCGI_H
|
#endif //SESIMOS_FASTCGI_H
|
||||||
|
@@ -145,7 +145,7 @@ int http_receive_request(sock *client, http_req *req) {
|
|||||||
req->hdr.last_field_num = -1;
|
req->hdr.last_field_num = -1;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
rcv_len = sock_recv(client, buf, CLIENT_MAX_HEADER_SIZE, 0);
|
rcv_len = sock_recv(client, buf, CLIENT_MAX_HEADER_SIZE, MSG_PEEK);
|
||||||
if (rcv_len <= 0) {
|
if (rcv_len <= 0) {
|
||||||
print("Unable to receive http header: %s", sock_strerror(client));
|
print("Unable to receive http header: %s", sock_strerror(client));
|
||||||
return -1;
|
return -1;
|
||||||
@@ -155,6 +155,8 @@ int http_receive_request(sock *client, http_req *req) {
|
|||||||
if (header_len <= 0) {
|
if (header_len <= 0) {
|
||||||
print(ERR_STR "Unable to parse http header: End of header not found" CLR_STR);
|
print(ERR_STR "Unable to parse http header: End of header not found" CLR_STR);
|
||||||
return 5;
|
return 5;
|
||||||
|
} else {
|
||||||
|
rcv_len = sock_recv(client, buf, header_len, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < header_len; i++) {
|
for (int i = 0; i < header_len; i++) {
|
||||||
@@ -216,13 +218,6 @@ int http_receive_request(sock *client, http_req *req) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
client->buf_len = rcv_len - (pos0 - buf + 4);
|
|
||||||
if (client->buf_len > 0) {
|
|
||||||
client->buf = malloc(client->buf_len);
|
|
||||||
client->buf_off = 0;
|
|
||||||
memcpy(client->buf, pos0 + 4, client->buf_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -25,9 +25,6 @@ char *rev_proxy_host = NULL;
|
|||||||
struct timeval server_timeout = {.tv_sec = SERVER_TIMEOUT, .tv_usec = 0};
|
struct timeval server_timeout = {.tv_sec = SERVER_TIMEOUT, .tv_usec = 0};
|
||||||
|
|
||||||
int rev_proxy_preload(void) {
|
int rev_proxy_preload(void) {
|
||||||
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.ctx = SSL_CTX_new(TLS_client_method());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -324,46 +321,35 @@ int rev_proxy_init(http_req *req, http_res *res, http_status_ctx *ctx, host_conf
|
|||||||
}
|
}
|
||||||
|
|
||||||
const char *content_length = http_get_header_field(&req->hdr, "Content-Length");
|
const char *content_length = http_get_header_field(&req->hdr, "Content-Length");
|
||||||
if (content_length != NULL) {
|
unsigned long content_len = content_length != NULL ? strtoul(content_length, NULL, 10) : 0;
|
||||||
unsigned long content_len = strtoul(content_length, NULL, 10);
|
const char *transfer_encoding = http_get_header_field(&req->hdr, "Transfer-Encoding");
|
||||||
if (client->buf_len - client->buf_off > 0) {
|
|
||||||
unsigned long len = client->buf_len - client->buf_off;
|
ret = 0;
|
||||||
if (len > content_len) {
|
if (content_len > 0) {
|
||||||
len = content_len;
|
ret = sock_splice(&rev_proxy, client, buffer, sizeof(buffer), content_len);
|
||||||
}
|
} else if (transfer_encoding != NULL && strstr(transfer_encoding, "chunked") != NULL) {
|
||||||
ret = sock_send(&rev_proxy, client->buf, len, 0);
|
ret = sock_splice_chunked(&rev_proxy, client, buffer, sizeof(buffer));
|
||||||
if (ret <= 0) {
|
}
|
||||||
res->status = http_get_status(502);
|
|
||||||
ctx->origin = SERVER_REQ;
|
if (ret < 0 || (content_len != 0 && ret != content_len)) {
|
||||||
print(ERR_STR "Unable to send request to server (2): %s" CLR_STR, sock_strerror(&rev_proxy));
|
if (ret == -1) {
|
||||||
sprintf(err_msg, "Unable to send request to server: %s.", sock_strerror(&rev_proxy));
|
res->status = http_get_status(502);
|
||||||
retry = tries < 4;
|
ctx->origin = SERVER_REQ;
|
||||||
goto proxy_err;
|
print(ERR_STR "Unable to send request to server (2): %s" CLR_STR, sock_strerror(&rev_proxy));
|
||||||
}
|
sprintf(err_msg, "Unable to send request to server: %s.", sock_strerror(&rev_proxy));
|
||||||
content_len -= len;
|
retry = tries < 4;
|
||||||
}
|
goto proxy_err;
|
||||||
if (content_len > 0) {
|
} else if (ret == -2) {
|
||||||
ret = sock_splice(&rev_proxy, client, buffer, sizeof(buffer), content_len);
|
res->status = http_get_status(400);
|
||||||
if (ret <= 0) {
|
ctx->origin = CLIENT_REQ;
|
||||||
if (ret == -1) {
|
print(ERR_STR "Unable to receive request from client: %s" CLR_STR, sock_strerror(client));
|
||||||
res->status = http_get_status(502);
|
sprintf(err_msg, "Unable to receive request from client: %s.", sock_strerror(client));
|
||||||
ctx->origin = SERVER_REQ;
|
return -1;
|
||||||
print(ERR_STR "Unable to send request to server (3): %s" CLR_STR, sock_strerror(&rev_proxy));
|
|
||||||
sprintf(err_msg, "Unable to send request to server: %s.", sock_strerror(&rev_proxy));
|
|
||||||
goto proxy_err;
|
|
||||||
} else if (ret == -2) {
|
|
||||||
res->status = http_get_status(400);
|
|
||||||
ctx->origin = CLIENT_REQ;
|
|
||||||
print(ERR_STR "Unable to receive request from client: %s" CLR_STR, sock_strerror(client));
|
|
||||||
sprintf(err_msg, "Unable to receive request from client: %s.", sock_strerror(client));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
res->status = http_get_status(500);
|
|
||||||
ctx->origin = INTERNAL;
|
|
||||||
print(ERR_STR "Unknown Error" CLR_STR);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
res->status = http_get_status(500);
|
||||||
|
ctx->origin = INTERNAL;
|
||||||
|
print(ERR_STR "Unknown Error" CLR_STR);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = sock_recv(&rev_proxy, buffer, sizeof(buffer), MSG_PEEK);
|
ret = sock_recv(&rev_proxy, buffer, sizeof(buffer), MSG_PEEK);
|
||||||
|
@@ -103,6 +103,29 @@ long sock_splice(sock *dst, sock *src, void *buf, unsigned long buf_len, unsigne
|
|||||||
return (long) send_len;
|
return (long) send_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long sock_splice_chunked(sock *dst, sock *src, void *buf, unsigned long buf_len) {
|
||||||
|
long ret;
|
||||||
|
unsigned long send_len = 0;
|
||||||
|
unsigned long next_len;
|
||||||
|
char tmp[16];
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
ret = sock_recv(src, tmp, sizeof(tmp), MSG_PEEK);
|
||||||
|
if (ret < 0) return -2;
|
||||||
|
next_len = strtol(tmp, NULL, 16);
|
||||||
|
char *ptr = strstr(tmp, "\r\n");
|
||||||
|
ret = sock_recv(src, tmp, ptr - tmp + 2, 0);
|
||||||
|
if (ret < 0) return -2;
|
||||||
|
|
||||||
|
if (next_len <= 0) break;
|
||||||
|
|
||||||
|
ret = sock_splice(dst, src, buf, buf_len, next_len);
|
||||||
|
if (ret < 0) return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (long) send_len;
|
||||||
|
}
|
||||||
|
|
||||||
int sock_close(sock *s) {
|
int sock_close(sock *s) {
|
||||||
if ((int) s->enc && s->ssl != NULL) {
|
if ((int) s->enc && s->ssl != NULL) {
|
||||||
if (s->_last_ret >= 0) SSL_shutdown(s->ssl);
|
if (s->_last_ret >= 0) SSL_shutdown(s->ssl);
|
||||||
|
@@ -17,9 +17,6 @@ typedef struct {
|
|||||||
int socket;
|
int socket;
|
||||||
SSL_CTX *ctx;
|
SSL_CTX *ctx;
|
||||||
SSL *ssl;
|
SSL *ssl;
|
||||||
char *buf;
|
|
||||||
unsigned long buf_len;
|
|
||||||
unsigned long buf_off;
|
|
||||||
long _last_ret;
|
long _last_ret;
|
||||||
int _errno;
|
int _errno;
|
||||||
unsigned long _ssl_error;
|
unsigned long _ssl_error;
|
||||||
@@ -35,6 +32,8 @@ long sock_recv(sock *s, void *buf, unsigned long len, int flags);
|
|||||||
|
|
||||||
long sock_splice(sock *dst, sock *src, void *buf, unsigned long buf_len, unsigned long len);
|
long sock_splice(sock *dst, sock *src, void *buf, unsigned long buf_len, unsigned long len);
|
||||||
|
|
||||||
|
long sock_splice_chunked(sock *dst, sock *src, void *buf, unsigned long buf_len);
|
||||||
|
|
||||||
int sock_close(sock *s);
|
int sock_close(sock *s);
|
||||||
|
|
||||||
int sock_check(sock *s);
|
int sock_check(sock *s);
|
||||||
|
@@ -291,10 +291,6 @@ int main(int argc, const char *argv[]) {
|
|||||||
|
|
||||||
openssl_init();
|
openssl_init();
|
||||||
|
|
||||||
client.buf = NULL;
|
|
||||||
client.buf_len = 0;
|
|
||||||
client.buf_off = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < CONFIG_MAX_CERT_CONFIG; i++) {
|
for (int i = 0; i < CONFIG_MAX_CERT_CONFIG; i++) {
|
||||||
const cert_config *conf = &config->certs[i];
|
const cert_config *conf = &config->certs[i];
|
||||||
if (conf->name[0] == 0) break;
|
if (conf->name[0] == 0) break;
|
||||||
|
Reference in New Issue
Block a user