4 Commits

4 changed files with 68 additions and 28 deletions

View File

@ -77,9 +77,7 @@ int cache_process() {
fprintf(stdout, "[cache] Hashing file %s\n", cache[i].filename); fprintf(stdout, "[cache] Hashing file %s\n", cache[i].filename);
SHA1_Init(&ctx); SHA1_Init(&ctx);
file = fopen(cache[i].filename, "rb"); file = fopen(cache[i].filename, "rb");
compress = strncmp(cache[i].meta.type, "text/", 5) == 0 || compress = mime_is_compressible(cache[i].meta.type);
(strncmp(cache[i].meta.type, "application/", 12) == 0 &&
strstr(cache[i].meta.type, "+xml") != NULL);
int level = NECRONDA_ZLIB_LEVEL; int level = NECRONDA_ZLIB_LEVEL;
z_stream strm; z_stream strm;

View File

@ -174,7 +174,27 @@ 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) {
res.status = http_get_status(200);
http_add_header_field(&res.hdr, "Content-Type", "message/http");
content_length = snprintf(msg_buf, sizeof(msg_buf) - content_length, "%s %s HTTP/%s\r\n",
req.method, req.uri, req.version);
for (int i = 0; i < req.hdr.field_num; i++) {
content_length += snprintf(msg_buf + content_length, sizeof(msg_buf) - content_length, "%s: %s\r\n",
req.hdr.fields[i][0], req.hdr.fields[i][1]);
}
goto respond;
}
if (strncmp(uri.req_path, "/.well-known/", 13) != 0 && strstr(uri.path, "/.") != NULL) { if (strncmp(uri.req_path, "/.well-known/", 13) != 0 && strstr(uri.path, "/.") != NULL) {
res.status = http_get_status(403); res.status = http_get_status(403);
sprintf(err_msg, "Parts of this URI are hidden."); sprintf(err_msg, "Parts of this URI are hidden.");
@ -198,13 +218,18 @@ int client_request_handler(sock *client, unsigned long client_num, unsigned int
if (uri.is_static) { if (uri.is_static) {
res.status = http_get_status(200); res.status = http_get_status(200);
http_add_header_field(&res.hdr, "Allow", "GET, HEAD");
http_add_header_field(&res.hdr, "Accept-Ranges", "bytes"); http_add_header_field(&res.hdr, "Accept-Ranges", "bytes");
if (strcmp(req.method, "GET") != 0 && strcmp(req.method, "HEAD") != 0) { if (strcmp(req.method, "GET") != 0 && strcmp(req.method, "HEAD") != 0) {
res.status = http_get_status(405); res.status = http_get_status(405);
goto respond; goto respond;
} }
if (http_get_header_field(&req.hdr, "Content-Length") != NULL) {
res.status = http_get_status(400);
sprintf(err_msg, "A GET request must not contain a payload");
goto respond;
}
ret = uri_cache_init(&uri); ret = uri_cache_init(&uri);
if (ret != 0) { if (ret != 0) {
res.status = http_get_status(500); res.status = http_get_status(500);
@ -306,13 +331,9 @@ int client_request_handler(sock *client, unsigned long client_num, unsigned int
goto respond; goto respond;
} }
if (strcmp(req.method, "POST") == 0 || strcmp(req.method, "PUT") == 0) {
char *client_content_length = http_get_header_field(&req.hdr, "Content-Length"); char *client_content_length = http_get_header_field(&req.hdr, "Content-Length");
unsigned long client_content_len; if (client_content_length != NULL) {
if (client_content_length == NULL) { unsigned long client_content_len = strtoul(client_content_length, NULL, 10);
goto fastcgi_end;
}
client_content_len = strtoul(client_content_length, NULL, 10);
ret = fastcgi_receive(&php_fpm, client, client_content_len); ret = fastcgi_receive(&php_fpm, client, client_content_len);
if (ret != 0) { if (ret != 0) {
if (ret < 0) { if (ret < 0) {
@ -324,7 +345,6 @@ int client_request_handler(sock *client, unsigned long client_num, unsigned int
goto respond; goto respond;
} }
} }
fastcgi_end:
fastcgi_close_stdin(&php_fpm); fastcgi_close_stdin(&php_fpm);
ret = fastcgi_header(&php_fpm, &res, err_msg); ret = fastcgi_header(&php_fpm, &res, err_msg);
@ -351,13 +371,18 @@ int client_request_handler(sock *client, unsigned long client_num, unsigned int
} }
} }
char *accept_encoding = http_get_header_field(&req.hdr, "Accept-Encoding");
if (accept_encoding != NULL && strstr(accept_encoding, "deflate") != NULL) {
http_add_header_field(&res.hdr, "Content-Encoding", "deflate");
}
content_length = -1; content_length = -1;
use_fastcgi = 1; use_fastcgi = 1;
char *accept_encoding = http_get_header_field(&req.hdr, "Accept-Encoding");
char *content_type = http_get_header_field(&res.hdr, "Content-Type");
char *content_encoding = http_get_header_field(&res.hdr, "Content-Encoding");
if (mime_is_compressible(content_type) && content_encoding == NULL &&
accept_encoding != NULL && strstr(accept_encoding, "deflate") != NULL) {
http_add_header_field(&res.hdr, "Content-Encoding", "deflate");
use_fastcgi = 2;
}
if (http_get_header_field(&res.hdr, "Content-Length") == NULL) { if (http_get_header_field(&res.hdr, "Content-Length") == NULL) {
http_add_header_field(&res.hdr, "Transfer-Encoding", "chunked"); http_add_header_field(&res.hdr, "Transfer-Encoding", "chunked");
} }
@ -375,6 +400,9 @@ int client_request_handler(sock *client, unsigned long client_num, unsigned int
respond: respond:
if (!use_rev_proxy) { if (!use_rev_proxy) {
if (conf->type == CONFIG_TYPE_LOCAL && uri.is_static && res.status->code == 405) {
http_add_header_field(&res.hdr, "Allow", "GET, HEAD, TRACE");
}
if (http_get_header_field(&res.hdr, "Accept-Ranges") == NULL) { if (http_get_header_field(&res.hdr, "Accept-Ranges") == NULL) {
http_add_header_field(&res.hdr, "Accept-Ranges", "none"); http_add_header_field(&res.hdr, "Accept-Ranges", "none");
} }
@ -450,9 +478,7 @@ int client_request_handler(sock *client, unsigned long client_num, unsigned int
} else if (use_fastcgi) { } else if (use_fastcgi) {
char *transfer_encoding = http_get_header_field(&res.hdr, "Transfer-Encoding"); 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 && strcmp(transfer_encoding, "chunked") == 0;
char *content_encoding = http_get_header_field(&res.hdr, "Content-Encoding"); int flags = (chunked ? FASTCGI_CHUNKED : 0) | ((use_fastcgi == 2) ? FASTCGI_COMPRESS : 0);
int comp = content_encoding != NULL && strcmp(content_encoding, "deflate") == 0;
int flags = (chunked ? FASTCGI_CHUNKED : 0) | (comp ? FASTCGI_COMPRESS : 0);
fastcgi_send(&php_fpm, client, flags); fastcgi_send(&php_fpm, client, flags);
} else if (use_rev_proxy) { } else if (use_rev_proxy) {
char *transfer_encoding = http_get_header_field(&res.hdr, "Transfer-Encoding"); char *transfer_encoding = http_get_header_field(&res.hdr, "Transfer-Encoding");

View File

@ -159,3 +159,17 @@ MMDB_entry_data_list_s *mmdb_json(MMDB_entry_data_list_s *list, char *str, long
} }
return next; return next;
} }
int mime_is_compressible(const char *type) {
return
strncmp(type, "text/", 5) == 0 ||
strncmp(type, "message/", 7) == 0 ||
strstr(type, "+xml") != NULL ||
strcmp(type, "application/javascript") == 0 ||
strcmp(type, "application/json") == 0 ||
strcmp(type, "application/xml") == 0 ||
strcmp(type, "application/x-www-form-urlencoded") == 0 ||
strcmp(type, "application/x-tex") == 0 ||
strcmp(type, "application/x-httpd-php") == 0 ||
strcmp(type, "application/x-latex") == 0;
}

View File

@ -28,4 +28,6 @@ int url_encode(const char *str, char *enc, ssize_t *size);
int url_decode(const char *str, char *dec, ssize_t *size); int url_decode(const char *str, char *dec, ssize_t *size);
int mime_is_text(const char *type);
#endif //NECRONDA_SERVER_UTILS_H #endif //NECRONDA_SERVER_UTILS_H