diff --git a/.gitignore b/.gitignore index 56cdd03..934d7e0 100644 --- a/.gitignore +++ b/.gitignore @@ -57,3 +57,4 @@ ssl/* .github/* !.github/workflows/ src/bin +docker-push.sh diff --git a/README.md b/README.md index f61fdc4..1c8b54a 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,7 @@ sudo apt-get install -y \ libssl-dev \ libmagic-dev \ libnghttp2-dev \ + zlib1g-dev \ pkg-config ``` @@ -111,7 +112,7 @@ cd Carbon # Install dependencies sudo apt-get update -sudo apt-get install -y build-essential libssl-dev libmagic-dev libnghttp2-dev +sudo apt-get install -y build-essential libssl-dev libmagic-dev libnghttp2-dev zlib1g-dev pkg-config # Build the server make diff --git a/src/performance.c b/src/performance.c index f9b32cc..46bf3e6 100644 --- a/src/performance.c +++ b/src/performance.c @@ -218,6 +218,10 @@ void cache_file_mmap(const char *path, size_t size, const char *mime_type) { munmap(mmap_cache[slot].mmap_data, mmap_cache[slot].size); } + if (mmap_cache[slot].compressed_data) + { + free(mmap_cache[slot].compressed_data); + } free(mmap_cache[slot].path); free(mmap_cache[slot].mime_type); } @@ -249,6 +253,8 @@ void cache_file_mmap(const char *path, size_t size, const char *mime_type) mmap_cache[slot].path = strdup(path); mmap_cache[slot].mmap_data = mapped; mmap_cache[slot].size = size; + mmap_cache[slot].compressed_data = NULL; + mmap_cache[slot].compressed_size = 0; mmap_cache[slot].last_access = time(NULL); mmap_cache[slot].mime_type = strdup(mime_type); mmap_cache[slot].ref_count = 0; diff --git a/src/performance.h b/src/performance.h index 5886dca..a3df270 100644 --- a/src/performance.h +++ b/src/performance.h @@ -34,6 +34,8 @@ typedef struct char *path; void *mmap_data; size_t size; + void *compressed_data; + size_t compressed_size; time_t last_access; char *mime_type; int ref_count; diff --git a/src/server.c b/src/server.c index dbf8daa..e1cecf2 100644 --- a/src/server.c +++ b/src/server.c @@ -716,27 +716,42 @@ void *handle_http_client(void *arg) unsigned char *compressed_data = NULL; size_t compressed_size = 0; int using_compression = 0; - - char debug_msg[256]; - snprintf(debug_msg, sizeof(debug_msg), "accepts_gzip=%d, should_compress=%d, size=%zu", - accepts_gzip, should_compress(cached->mime_type), cached->size); - log_event(debug_msg); + int needs_free = 0; if (accepts_gzip && should_compress(cached->mime_type) && cached->size > 1024) { - compressed_data = gzip_compress((unsigned char *)cached->mmap_data, cached->size, &compressed_size); - if (compressed_data && compressed_size < cached->size * 0.9) // Only use if 10%+ savings + // Check if we have cached compressed version + if (cached->compressed_data && cached->compressed_size > 0) { + // Use pre-compressed cached data + compressed_data = cached->compressed_data; + compressed_size = cached->compressed_size; using_compression = 1; - snprintf(debug_msg, sizeof(debug_msg), "Compression: %zu -> %zu bytes (%.1f%%)", - cached->size, compressed_size, (compressed_size * 100.0) / cached->size); - log_event(debug_msg); + needs_free = 0; } - else if (compressed_data) + else { - log_event("Compression not efficient enough, skipping"); - free(compressed_data); - compressed_data = NULL; + // Compress on-the-fly and cache it + compressed_data = gzip_compress((unsigned char *)cached->mmap_data, cached->size, &compressed_size); + if (compressed_data && compressed_size < cached->size * 0.9) + { + using_compression = 1; + needs_free = 1; + + // Cache the compressed version for future requests + cached->compressed_data = malloc(compressed_size); + if (cached->compressed_data) + { + memcpy(cached->compressed_data, compressed_data, compressed_size); + cached->compressed_size = compressed_size; + needs_free = 0; + } + } + else if (compressed_data) + { + free(compressed_data); + compressed_data = NULL; + } } } @@ -790,7 +805,7 @@ void *handle_http_client(void *arg) } } - if (compressed_data) + if (needs_free && compressed_data) free(compressed_data); release_cached_file(cached); free(mime_type); @@ -1098,18 +1113,40 @@ void *handle_https_client(void *arg) unsigned char *compressed_data = NULL; size_t compressed_size = 0; int using_compression = 0; + int needs_free = 0; if (accepts_gzip && should_compress(cached->mime_type) && cached->size > 1024) { - compressed_data = gzip_compress((unsigned char *)cached->mmap_data, cached->size, &compressed_size); - if (compressed_data && compressed_size < cached->size * 0.9) + // Check if we have cached compressed version + if (cached->compressed_data && cached->compressed_size > 0) { + compressed_data = cached->compressed_data; + compressed_size = cached->compressed_size; using_compression = 1; + needs_free = 0; } - else if (compressed_data) + else { - free(compressed_data); - compressed_data = NULL; + compressed_data = gzip_compress((unsigned char *)cached->mmap_data, cached->size, &compressed_size); + if (compressed_data && compressed_size < cached->size * 0.9) + { + using_compression = 1; + needs_free = 1; + + // Cache the compressed version + cached->compressed_data = malloc(compressed_size); + if (cached->compressed_data) + { + memcpy(cached->compressed_data, compressed_data, compressed_size); + cached->compressed_size = compressed_size; + needs_free = 0; + } + } + else if (compressed_data) + { + free(compressed_data); + compressed_data = NULL; + } } } @@ -1150,7 +1187,7 @@ void *handle_https_client(void *arg) total_sent += sent; } - if (compressed_data) + if (needs_free && compressed_data) free(compressed_data); release_cached_file(cached); free(mime_type);