sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | 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