Skip to content
This repository was archived by the owner on Oct 8, 2025. It is now read-only.

Commit 729adee

Browse files
committed
http: Compress static responses
Signed-off-by: Andrew Clayton <a.clayton@nginx.com>
1 parent f1fc256 commit 729adee

File tree

1 file changed

+121
-0
lines changed

1 file changed

+121
-0
lines changed

src/nxt_http_static.c

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include <nxt_router.h>
77
#include <nxt_http.h>
8+
#include <nxt_http_compression.h>
89

910

1011
typedef struct {
@@ -326,6 +327,8 @@ nxt_http_static_send(nxt_task_t *task, nxt_http_request_t *r,
326327
nxt_work_handler_t body_handler;
327328
nxt_http_static_conf_t *conf;
328329

330+
printf("%s: \n", __func__);
331+
329332
action = ctx->action;
330333
conf = action->u.conf;
331334
rtcf = r->conf->socket_conf->router_conf;
@@ -576,7 +579,121 @@ nxt_http_static_send(nxt_task_t *task, nxt_http_request_t *r,
576579
field->value_length = mtype->length;
577580
}
578581

582+
r->resp.mime_type = mtype;
583+
579584
if (ctx->need_body && nxt_file_size(&fi) > 0) {
585+
bool compress;
586+
587+
ret = nxt_http_comp_check_compression(task, r);
588+
if (ret != NXT_OK) {
589+
goto fail;
590+
}
591+
592+
compress = nxt_http_comp_wants_compression();
593+
if (compress) {
594+
char tmp_path[NXT_MAX_PATH_LEN];
595+
size_t in_size, out_size, out_total = 0, rest;
596+
u_char *p;
597+
uint8_t *in, *out;
598+
nxt_file_t tfile;
599+
nxt_runtime_t *rt = task->thread->runtime;
600+
601+
static const char *template = "unit-compr-XXXXXX";
602+
603+
if (nxt_slow_path(strlen(rt->tmp) + 1 + strlen(template) + 1
604+
> NXT_MAX_PATH_LEN))
605+
{
606+
goto fail;
607+
}
608+
609+
p = nxt_cpymem(tmp_path, rt->tmp, strlen(rt->tmp));
610+
*p++ = '/';
611+
p = nxt_cpymem(tmp_path, template, strlen(template));
612+
*p = '\0';
613+
614+
tfile.fd = mkstemp(tmp_path);
615+
if (nxt_slow_path(tfile.fd == -1)) {
616+
nxt_alert(task, "mkstemp(%s) failed %E", tmp_path,
617+
nxt_errno);
618+
goto fail;
619+
}
620+
621+
in_size = nxt_file_size(&fi);
622+
out_size = nxt_http_comp_bound(in_size);
623+
624+
ret = ftruncate(tfile.fd, out_size);
625+
if (nxt_slow_path(ret == -1)) {
626+
nxt_alert(task, "ftruncate(%d<%s>, %uz) failed %E",
627+
tfile.fd, tmp_path, out_size, nxt_errno);
628+
nxt_file_close(task, &tfile);
629+
goto fail;
630+
}
631+
632+
in = nxt_mem_mmap(NULL, in_size, PROT_READ, MAP_SHARED, f->fd,
633+
0);
634+
if (nxt_slow_path(in == MAP_FAILED)) {
635+
nxt_file_close(task, &tfile);
636+
goto fail;
637+
}
638+
639+
out = nxt_mem_mmap(NULL, out_size, PROT_READ|PROT_WRITE,
640+
MAP_SHARED, tfile.fd, 0);
641+
if (nxt_slow_path(out == MAP_FAILED)) {
642+
nxt_mem_munmap(in, in_size);
643+
nxt_file_close(task, &tfile);
644+
goto fail;
645+
}
646+
647+
rest = in_size;
648+
649+
do {
650+
bool last;
651+
size_t n;
652+
ssize_t cbytes;
653+
654+
n = rest > NXT_HTTP_STATIC_BUF_SIZE
655+
? NXT_HTTP_STATIC_BUF_SIZE : rest;
656+
657+
last = n == rest;
658+
659+
printf("%s: out_off [%ld] in_off [%ld] last [%s]\n",
660+
__func__, out_total, in_size - rest,
661+
last ? "true" : "false");
662+
663+
cbytes = nxt_http_comp_compress(out + out_total,
664+
out_size - out_total,
665+
in + in_size - rest, n,
666+
last);
667+
printf("%s: cbytes [%ld]\n", __func__, cbytes);
668+
669+
out_total += cbytes;
670+
rest -= n;
671+
} while (rest > 0);
672+
673+
nxt_mem_munmap(in, in_size);
674+
msync(out, out_size, MS_ASYNC);
675+
nxt_mem_munmap(out, out_size);
676+
677+
ret = ftruncate(tfile.fd, out_total);
678+
if (nxt_slow_path(ret == -1)) {
679+
nxt_alert(task, "ftruncate(%d<%s>, %uz) failed %E",
680+
tfile.fd, tmp_path, out_total, nxt_errno);
681+
nxt_file_close(task, &tfile);
682+
goto fail;
683+
}
684+
685+
nxt_file_close(task, f);
686+
687+
*f = tfile;
688+
689+
ret = nxt_file_info(f, &fi);
690+
if (nxt_slow_path(ret != NXT_OK)) {
691+
goto fail;
692+
}
693+
694+
r->resp.content_length_n = out_total;
695+
}
696+
580697
fb = nxt_mp_zget(r->mem_pool, NXT_BUF_FILE_SIZE);
581698
if (nxt_slow_path(fb == NULL)) {
582699
goto fail;
@@ -793,6 +910,8 @@ nxt_http_static_body_handler(nxt_task_t *task, void *obj, void *data)
793910
nxt_work_queue_t *wq;
794911
nxt_http_request_t *r;
795912

913+
printf("%s: \n", __func__);
914+
796915
r = obj;
797916
fb = r->out;
798917

@@ -853,6 +972,8 @@ nxt_http_static_buf_completion(nxt_task_t *task, void *obj, void *data)
853972
nxt_off_t rest;
854973
nxt_http_request_t *r;
855974

975+
printf("%s: \n", __func__);
976+
856977
b = obj;
857978
r = data;
858979

0 commit comments

Comments
 (0)