bunkum

an old and silly c99 web server with some fun features
Log | Files | Refs | README

commit d7d48e8ddff7914d7cc26366cc97643888a58d4e
parent eed5ba40afe65162c2af0a9a8e0e1612a447720e
Author: quantumish <freifeld.david@gmail.com>
Date:   Thu, 13 Apr 2023 09:37:36 -0700

Add Accept-Encoding handling

Diffstat:
M.gitignore | 7+++++--
Mhttp.c | 42++++++++++++++++++++++++++++--------------
Mhttp/request.c | 2+-
Autils/compress.h | 9+++++++++
Mutils/compression.c | 15++++++++-------
5 files changed, 51 insertions(+), 24 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -11,4 +11,7 @@ public/ # emacs-related *~ \#*\# -.\#* -\ No newline at end of file +.\#* + +# osx-related? +*.dSYM/ +\ No newline at end of file diff --git a/http.c b/http.c @@ -21,6 +21,7 @@ #include "utils/log.h" #include "utils/time.h" #include "utils/shitvec.h" +#include "utils/compress.h" #include "http/response.h" #include "http/request.h" @@ -68,25 +69,38 @@ response_t serve_file(request_t req) { } } } - if (!ok) return serve_error(NotAcceptable); - - /* char datebuf[64]; */ - /* time_to_str(st.st_mtim.tv_sec, datebuf); */ - /* resp_add_hdr(&r, "Last-Modified", datebuf); */ char* buf = fbuf; // buffer to be written size_t bufsize = st.st_size; - if (ext == NULL || strcmp(ext, ".png") != 0) { - resp_add_hdr(&r, "Content-Encoding", "deflate"); - size_t clen = compressBound(st.st_size); - char* cbuf = malloc(clen); - compress((Bytef*)cbuf, &clen, (Bytef*)buf, bufsize); - free(buf); - - buf = cbuf; - bufsize = clen; + if (ok && (hdr = hashmap_get(&req.headers, "Accept-Encoding"))) { + log_debug("Handling Accept-Encoding header"); + ok = false; + shitvec_t mtypes = hdr_parse_accept(hdr); // abuse of this func + for (int j = 0; j < mtypes.vec_sz; j++) { + struct req_mimetype* a_mtype = shitvec_get(&mtypes, j); + log_debug("%s", a_mtype->item); + if (strcmp(a_mtype->item, "gzip") == 0) { + resp_add_hdr(&r, "Content-Encoding", "gzip"); + buf = gzip_compress(buf, &bufsize); + ok = true; + break; + } else if (strcmp(a_mtype->item, "deflate") == 0) { + resp_add_hdr(&r, "Content-Encoding", "deflate"); + buf = zlib_compress(buf, &bufsize); + ok = true; + break; + } else if (strcmp(a_mtype->item, "identity") == 0) { + ok = true; + break; + } + } } + if (!ok) return serve_error(NotAcceptable); + + /* char datebuf[64]; */ + /* time_to_str(st.st_mtim.tv_sec, datebuf); */ + /* resp_add_hdr(&r, "Last-Modified", datebuf); */ resp_add_content(&r, buf, bufsize); free(buf); diff --git a/http/request.c b/http/request.c @@ -71,7 +71,7 @@ int req_parse(request_t* req) { if (matched == 0) return 0; // No more headers; else if (matched == 1) { if (name[0] == '\r') return 0; // TODO sketch - return -1; // Uhh... half a header. + return -1; // Uhh... half a header. NOTE doesn't even seem to work. fun. } log_debug("Inserting '%s' (len %d) -> '%s'", name, strlen(name), value); hashmap_set(&req->headers, name, value); diff --git a/utils/compress.h b/utils/compress.h @@ -0,0 +1,9 @@ +#ifndef COMPRESS_H +#define COMPRESS_H + +#include <stddef.h> + +char* zlib_compress(char* buf, size_t* bufsize); +char* gzip_compress(char* buf, size_t* bufsize); + +#endif diff --git a/utils/compression.c b/utils/compression.c @@ -2,25 +2,26 @@ #include "zlib.h" -char* zlib_compress(char* buf, size_t bufsize) { - size_t clen = compressBound(bufsize); +char* zlib_compress(char* buf, size_t* bufsize) { + size_t clen = compressBound(*bufsize); char* cbuf = malloc(clen); - compress((Bytef*)cbuf, &clen, (Bytef*)buf, bufsize); + compress((Bytef*)cbuf, &clen, (Bytef*)buf, *bufsize); + *bufsize = clen; return cbuf; } -char* gzip_compress(char* buf, size_t bufsize) { - size_t clen = compressBound(bufsize); +char* gzip_compress(char* buf, size_t* bufsize) { + size_t clen = compressBound(*bufsize); char* cbuf = malloc(clen); z_stream zs; zs.zalloc = Z_NULL; zs.zfree = Z_NULL; zs.opaque = Z_NULL; - zs.avail_in = (uInt)bufsize; + zs.avail_in = (uInt)*bufsize; zs.next_in = (Bytef *)buf; zs.avail_out = (uInt)clen; zs.next_out = (Bytef *)cbuf; - + *bufsize = clen; // "Add 16 to windowBits to write a simple gzip header and trailer around the compressed data instead of a zlib wrapper" deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 15 | 16, 8, Z_DEFAULT_STRATEGY); deflate(&zs, Z_FINISH);