quark-precompression-20200308-3c7049e.diff - sites - public wiki contents of suckless.org
(HTM) git clone git://git.suckless.org/sites
(DIR) Log
(DIR) Files
(DIR) Refs
---
quark-precompression-20200308-3c7049e.diff (3325B)
---
1 From 668df28967b8abd2893383e4d20b16cfe99dfdeb Mon Sep 17 00:00:00 2001
2 From: guysv <sviryguy@gmail.com>
3 Date: Sun, 8 Mar 2020 18:40:07 +0200
4 Subject: [PATCH] Add support for precomputed compression
5
6 If a client indicates that it supports gzip, then look for a `.gz`
7 variation of requested file. If such gzipped file exists, send it
8 instead and set the appropriate headers.
9
10 Range requests and dirlist requests are not supported.
11 ---
12 http.c | 24 ++++++++++++++++++++++--
13 http.h | 1 +
14 resp.c | 5 +++--
15 resp.h | 2 +-
16 4 files changed, 27 insertions(+), 5 deletions(-)
17
18 diff --git a/http.c b/http.c
19 index efc4136..a654514 100644
20 --- a/http.c
21 +++ b/http.c
22 @@ -25,6 +25,7 @@ const char *req_field_str[] = {
23 [REQ_HOST] = "Host",
24 [REQ_RANGE] = "Range",
25 [REQ_MOD] = "If-Modified-Since",
26 + [REQ_ENCODE] = "Accept-Encoding",
27 };
28
29 const char *req_method_str[] = {
30 @@ -349,7 +350,7 @@ enum status
31 http_send_response(int fd, struct request *r)
32 {
33 struct in6_addr res;
34 - struct stat st;
35 + struct stat st, gzst;
36 struct tm tm;
37 size_t len, i;
38 off_t lower, upper;
39 @@ -604,5 +605,24 @@ http_send_response(int fd, struct request *r)
40 }
41 }
42
43 - return resp_file(fd, RELPATH(realtarget), r, &st, mime, lower, upper);
44 + /* encoding-compression */
45 + if (r->field[REQ_ENCODE][0] && !r->field[REQ_RANGE][0]) {
46 + for (p = r->field[REQ_ENCODE]; p; p = strchr(p, ','), p ? p++ : p) {
47 + /* skip whitespace */
48 + for (; *p == ' ' || *p == '\t'; p++)
49 + ;
50 + if (!strncasecmp(p, "gzip", sizeof("gzip")-1) &&
51 + !esnprintf(tmptarget, sizeof(tmptarget), "%s%s", realtarget,
52 + ".gz") &&
53 + !stat(RELPATH(tmptarget), &gzst) &&
54 + S_ISREG(gzst.st_mode)) {
55 + lower = 0;
56 + upper = gzst.st_size-1;
57 + return resp_file(fd, RELPATH(tmptarget), r, &gzst, mime,
58 + "Content-Encoding: gzip\r\n", lower, upper);
59 + }
60 + }
61 + }
62 +
63 + return resp_file(fd, RELPATH(realtarget), r, &st, mime, "", lower, upper);
64 }
65 diff --git a/http.h b/http.h
66 index cd1ba22..26ced90 100644
67 --- a/http.h
68 +++ b/http.h
69 @@ -11,6 +11,7 @@ enum req_field {
70 REQ_HOST,
71 REQ_RANGE,
72 REQ_MOD,
73 + REQ_ENCODE,
74 NUM_REQ_FIELDS,
75 };
76
77 diff --git a/resp.c b/resp.c
78 index 3075c28..bf35ac8 100644
79 --- a/resp.c
80 +++ b/resp.c
81 @@ -111,7 +111,7 @@ cleanup:
82
83 enum status
84 resp_file(int fd, char *name, struct request *r, struct stat *st, char *mime,
85 - off_t lower, off_t upper)
86 + char *encoding, off_t lower, off_t upper)
87 {
88 FILE *fp;
89 enum status s;
90 @@ -142,10 +142,11 @@ resp_file(int fd, char *name, struct request *r, struct stat *st, char *mime,
91 "Connection: close\r\n"
92 "Last-Modified: %s\r\n"
93 "Content-Type: %s\r\n"
94 + "%s"
95 "Content-Length: %zu\r\n",
96 s, status_str[s], timestamp(time(NULL), t1),
97 timestamp(st->st_mtim.tv_sec, t2), mime,
98 - upper - lower + 1) < 0) {
99 + encoding, upper - lower + 1) < 0) {
100 s = S_REQUEST_TIMEOUT;
101 goto cleanup;
102 }
103 diff --git a/resp.h b/resp.h
104 index d5928ef..ccfaaad 100644
105 --- a/resp.h
106 +++ b/resp.h
107 @@ -9,6 +9,6 @@
108
109 enum status resp_dir(int, char *, struct request *);
110 enum status resp_file(int, char *, struct request *, struct stat *, char *,
111 - off_t, off_t);
112 + char *, off_t, off_t);
113
114 #endif /* RESP_H */
115 --
116 2.25.1
117