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

Commit b8452bc

Browse files
http: Compress application responses
Co-authored-by: Alejandro Colomar <alx@kernel.org> Signed-off-by: Alejandro Colomar <alx@kernel.org> Signed-off-by: Andrew Clayton <a.clayton@nginx.com>
1 parent ccca7c5 commit b8452bc

File tree

4 files changed

+96
-2
lines changed

4 files changed

+96
-2
lines changed

src/nxt_http_compression.c

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,6 @@ static void print_comp_config(size_t n)
151151
}
152152
}
153153

154-
155154
static ssize_t
156155
nxt_http_comp_compress(uint8_t *dst, size_t dst_size, const uint8_t *src,
157156
size_t src_size, bool last)
@@ -181,6 +180,57 @@ nxt_http_comp_bound(size_t size)
181180
}
182181

183182

183+
nxt_int_t
184+
nxt_http_comp_compress_app_response(nxt_http_request_t *r)
185+
{
186+
bool last;
187+
size_t buf_len, in_len;
188+
ssize_t cbytes;
189+
nxt_buf_t *buf, *b = r->out;
190+
nxt_http_comp_ctx_t *ctx = &compressor_ctx;
191+
192+
printf("%s: \n", __func__);
193+
194+
if (ctx->idx == NXT_HTTP_COMP_SCHEME_IDENTITY) {
195+
printf("%s: NXT_HTTP_COMP_SCHEME_IDENTITY [skipping/identity]\n",
196+
__func__);
197+
return NXT_OK;
198+
}
199+
200+
if (b->mem.pos == NULL) {
201+
return NXT_OK;
202+
}
203+
204+
in_len = b->mem.free - b->mem.pos;
205+
206+
last = !b->next || b->next->is_last == 1;
207+
208+
buf_len = nxt_http_comp_bound(in_len);
209+
210+
buf = nxt_buf_mem_alloc(r->mem_pool, buf_len, 0);
211+
if (nxt_slow_path(buf == NULL)) {
212+
return NXT_ERROR;
213+
}
214+
215+
nxt_memcpy(buf, b, offsetof(nxt_buf_t, mem));
216+
buf->data = r->mem_pool;
217+
218+
cbytes = nxt_http_comp_compress(b->mem.pos, in_len, buf->mem.start,
219+
buf->mem.end - buf->mem.start, last);
220+
printf("%s: cbytes = %ld\n", __func__, cbytes);
221+
if (cbytes == -1) {
222+
return NXT_ERROR;
223+
}
224+
225+
// if (cbytes != -1) {
226+
// b->mem.free = nxt_cpymem(b->mem.pos, tmp->mem.start, cbytes);
227+
// }
228+
b = buf;
229+
230+
return NXT_OK;
231+
}
232+
233+
184234
nxt_int_t
185235
nxt_http_comp_compress_static_response(nxt_task_t *task, nxt_file_t **f,
186236
nxt_file_info_t *fi,
@@ -400,6 +450,14 @@ nxt_http_comp_set_header(nxt_http_request_t *r, nxt_uint_t comp_idx)
400450
static const nxt_str_t content_encoding_str =
401451
nxt_string("Content-Encoding");
402452

453+
printf("%s: \n", __func__);
454+
455+
#if 0
456+
if (comp_idx == NXT_HTTP_COMP_SCHEME_IDENTITY) {
457+
return NXT_OK;
458+
}
459+
#endif
460+
403461
f = nxt_list_add(r->resp.fields);
404462
if (nxt_slow_path(f == NULL)) {
405463
return NXT_ERROR;
@@ -414,6 +472,28 @@ nxt_http_comp_set_header(nxt_http_request_t *r, nxt_uint_t comp_idx)
414472
f->value = token->start;
415473
f->value_length = token->length;
416474

475+
r->resp.content_length = NULL;
476+
r->resp.content_length_n = -1;
477+
478+
if (r->resp.mime_type == NULL) {
479+
nxt_http_field_t *f;
480+
481+
/*
482+
* As per RFC 2616 section 4.4 item 3, you should not send
483+
* Content-Length when a Transfer-Encoding header is present.
484+
*/
485+
nxt_list_each(f, r->resp.fields) {
486+
if (nxt_strcasecmp(f->name,
487+
(const u_char *)"Content-Length") == 0)
488+
{
489+
printf("%s: Found (%s: %s), marking as 'skip'\n", __func__,
490+
f->name, f->value);
491+
f->skip = true;
492+
break;
493+
}
494+
} nxt_list_loop;
495+
}
496+
417497
return NXT_OK;
418498
}
419499

src/nxt_http_compression.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ extern const nxt_http_comp_operations_t nxt_comp_brotli_ops;
9191
#endif
9292

9393

94+
extern nxt_int_t nxt_http_comp_compress_app_response(nxt_http_request_t *r);
9495
extern nxt_int_t nxt_http_comp_compress_static_response(nxt_task_t *task,
9596
nxt_file_t **f, nxt_file_info_t *fi, size_t static_buf_len,
9697
size_t *out_total);

src/nxt_port_queue.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ nxt_port_queue_recv(nxt_port_queue_t volatile *q, void *p)
8181
nxt_nncq_atomic_t i;
8282
nxt_port_queue_item_t *qi;
8383

84+
// printf("%s \n", __func__);
85+
8486
i = nxt_nncq_dequeue(&q->queue);
8587
if (i == nxt_nncq_empty(&q->queue)) {
8688
return -1;

src/nxt_router.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4136,6 +4136,8 @@ nxt_router_response_ready_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg,
41364136
nxt_unit_response_t *resp;
41374137
nxt_request_rpc_data_t *req_rpc_data;
41384138

4139+
printf("%s: \n", __func__);
4140+
41394141
req_rpc_data = data;
41404142

41414143
r = req_rpc_data->request;
@@ -4191,8 +4193,11 @@ nxt_router_response_ready_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg,
41914193

41924194
if (r->header_sent) {
41934195
nxt_buf_chain_add(&r->out, b);
4194-
nxt_http_request_send_body(task, r, NULL);
41954196

4197+
/* XXX Do compression here */
4198+
nxt_http_comp_compress_app_response(r);
4199+
4200+
nxt_http_request_send_body(task, r, NULL);
41964201
} else {
41974202
b_size = nxt_buf_is_mem(b) ? nxt_buf_mem_used_size(&b->mem) : 0;
41984203

@@ -4272,6 +4277,12 @@ nxt_router_response_ready_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg,
42724277
nxt_buf_chain_add(&r->out, b);
42734278
}
42744279

4280+
/* XXX Check compression / modify headers here */
4281+
ret = nxt_http_comp_check_compression(task, r);
4282+
if (ret != NXT_OK) {
4283+
goto fail;
4284+
}
4285+
42754286
nxt_http_request_header_send(task, r, nxt_http_request_send_body, NULL);
42764287

42774288
if (r->websocket_handshake

0 commit comments

Comments
 (0)