commit d7d48e8ddff7914d7cc26366cc97643888a58d4e
parent eed5ba40afe65162c2af0a9a8e0e1612a447720e
Author: quantumish <freifeld.david@gmail.com>
Date: Thu, 13 Apr 2023 09:37:36 -0700
Add Accept-Encoding handling
Diffstat:
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);