Skip to content

Commit

Permalink
http: Compress static responses
Browse files Browse the repository at this point in the history
Signed-off-by: Andrew Clayton <[email protected]>
  • Loading branch information
ac000 committed Nov 29, 2024
1 parent 5237c85 commit 84a19b0
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 0 deletions.
102 changes: 102 additions & 0 deletions src/nxt_http_compression.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,108 @@ nxt_http_comp_bound(size_t size)
}


nxt_int_t
nxt_http_comp_compress_static_response(nxt_task_t *task, nxt_file_t **f,
nxt_file_info_t *fi,
size_t static_buf_len,
size_t *out_total)
{
char tmp_path[NXT_MAX_PATH_LEN];
size_t in_size, out_size, rest;
u_char *p;
uint8_t *in, *out;
nxt_int_t ret;
nxt_file_t tfile;
nxt_runtime_t *rt = task->thread->runtime;

static const char *template = "unit-compr-XXXXXX";

*out_total = 0;

if (nxt_slow_path(strlen(rt->tmp) + 1 + strlen(template) + 1
> NXT_MAX_PATH_LEN))
{
return NXT_ERROR;
}

p = nxt_cpymem(tmp_path, rt->tmp, strlen(rt->tmp));
*p++ = '/';
p = nxt_cpymem(tmp_path, template, strlen(template));
*p = '\0';

tfile.fd = mkstemp(tmp_path);
if (nxt_slow_path(tfile.fd == -1)) {
nxt_alert(task, "mkstemp(%s) failed %E", tmp_path, nxt_errno);
return NXT_ERROR;
}

in_size = nxt_file_size(fi);
out_size = nxt_http_comp_bound(in_size);

ret = ftruncate(tfile.fd, out_size);
if (nxt_slow_path(ret == -1)) {
nxt_alert(task, "ftruncate(%d<%s>, %uz) failed %E",
tfile.fd, tmp_path, out_size, nxt_errno);
nxt_file_close(task, &tfile);
return NXT_ERROR;
}

in = nxt_mem_mmap(NULL, in_size, PROT_READ, MAP_SHARED, (*f)->fd, 0);
if (nxt_slow_path(in == MAP_FAILED)) {
nxt_file_close(task, &tfile);
return NXT_ERROR;
}

out = nxt_mem_mmap(NULL, out_size, PROT_READ|PROT_WRITE, MAP_SHARED,
tfile.fd, 0);
if (nxt_slow_path(out == MAP_FAILED)) {
nxt_mem_munmap(in, in_size);
nxt_file_close(task, &tfile);
return NXT_ERROR;
}

rest = in_size;

do {
bool last;
size_t n;
ssize_t cbytes;

n = nxt_min(rest, static_buf_len);

last = n == rest;

printf("%s: out_off [%ld] in_off [%ld] last [%s]\n",
__func__, *out_total, in_size - rest, last ? "true" : "false");

cbytes = nxt_http_comp_compress(out + *out_total, out_size - *out_total,
in + in_size - rest, n, last);
printf("%s: cbytes [%ld]\n", __func__, cbytes);

*out_total += cbytes;
rest -= n;
} while (rest > 0);

nxt_mem_munmap(in, in_size);
msync(out, out_size, MS_ASYNC);
nxt_mem_munmap(out, out_size);

ret = ftruncate(tfile.fd, *out_total);
if (nxt_slow_path(ret == -1)) {
nxt_alert(task, "ftruncate(%d<%s>, %uz) failed %E",
tfile.fd, tmp_path, *out_total, nxt_errno);
nxt_file_close(task, &tfile);
return NXT_ERROR;
}

nxt_file_close(task, *f);

**f = tfile;

return NXT_OK;
}


bool
nxt_http_comp_wants_compression(void)
{
Expand Down
3 changes: 3 additions & 0 deletions src/nxt_http_compression.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ extern const nxt_http_comp_operations_t nxt_comp_brotli_ops;
#endif


extern nxt_int_t nxt_http_comp_compress_static_response(nxt_task_t *task,
nxt_file_t **f, nxt_file_info_t *fi, size_t static_buf_len,
size_t *out_total);
extern bool nxt_http_comp_wants_compression(void);
extern bool nxt_http_comp_compressor_is_valid(const nxt_str_t *token);
extern nxt_int_t nxt_http_comp_check_compression(nxt_task_t *task,
Expand Down
34 changes: 34 additions & 0 deletions src/nxt_http_static.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include <nxt_router.h>
#include <nxt_http.h>
#include <nxt_http_compression.h>


typedef struct {
Expand Down Expand Up @@ -326,6 +327,8 @@ nxt_http_static_send(nxt_task_t *task, nxt_http_request_t *r,
nxt_work_handler_t body_handler;
nxt_http_static_conf_t *conf;

printf("%s: \n", __func__);

action = ctx->action;
conf = action->u.conf;
rtcf = r->conf->socket_conf->router_conf;
Expand Down Expand Up @@ -576,7 +579,34 @@ nxt_http_static_send(nxt_task_t *task, nxt_http_request_t *r,
field->value_length = mtype->length;
}

r->resp.mime_type = mtype;

if (ctx->need_body && nxt_file_size(&fi) > 0) {
ret = nxt_http_comp_check_compression(task, r);
if (ret != NXT_OK) {
goto fail;
}

if (nxt_http_comp_wants_compression()) {
size_t out_total;
nxt_int_t ret;

ret = nxt_http_comp_compress_static_response(
task, &f, &fi,
NXT_HTTP_STATIC_BUF_SIZE,
&out_total);
if (ret == NXT_ERROR) {
goto fail;
}

ret = nxt_file_info(f, &fi);
if (nxt_slow_path(ret != NXT_OK)) {
goto fail;
}

r->resp.content_length_n = out_total;
}

fb = nxt_mp_zget(r->mem_pool, NXT_BUF_FILE_SIZE);
if (nxt_slow_path(fb == NULL)) {
goto fail;
Expand Down Expand Up @@ -793,6 +823,8 @@ nxt_http_static_body_handler(nxt_task_t *task, void *obj, void *data)
nxt_work_queue_t *wq;
nxt_http_request_t *r;

printf("%s: \n", __func__);

r = obj;
fb = r->out;

Expand Down Expand Up @@ -853,6 +885,8 @@ nxt_http_static_buf_completion(nxt_task_t *task, void *obj, void *data)
nxt_off_t rest;
nxt_http_request_t *r;

printf("%s: \n", __func__);

b = obj;
r = data;

Expand Down

0 comments on commit 84a19b0

Please sign in to comment.