added the ability to store cache items in gzip

This commit is contained in:
Unbit
2013-04-15 12:36:27 +02:00
parent 2d6200231a
commit bf1f90a96a
4 changed files with 69 additions and 1 deletions
+8 -1
View File
@@ -628,9 +628,16 @@ void uwsgi_close_request(struct wsgi_request *wsgi_req) {
if (wsgi_req->cached_response && wsgi_req->status == 200 && wsgi_req->response_size > 0) {
uwsgi_cache_magic_set(wsgi_req->cache_it->buf, wsgi_req->cache_it->pos,
wsgi_req->cached_response->buf, wsgi_req->cached_response->pos, wsgi_req->cache_it_expires, UWSGI_CACHE_FLAG_UPDATE, wsgi_req->cache_it_to ? wsgi_req->cache_it_to->buf : NULL);
if (wsgi_req->cache_it_gzip) {
struct uwsgi_buffer *gzipped = uwsgi_gzip(wsgi_req->cached_response->buf, wsgi_req->cached_response->pos);
if (gzipped) {
uwsgi_cache_magic_set(wsgi_req->cache_it_gzip->buf, wsgi_req->cache_it_gzip->pos,
gzipped->buf, gzipped->pos, wsgi_req->cache_it_expires, UWSGI_CACHE_FLAG_UPDATE, wsgi_req->cache_it_to ? wsgi_req->cache_it_to->buf : NULL);
uwsgi_buffer_destroy(gzipped);
}
}
}
uwsgi_buffer_destroy(wsgi_req->cache_it);
}
if (wsgi_req->cache_it_to) {
+32
View File
@@ -1,5 +1,37 @@
#include <uwsgi.h>
static char gzheader[10] = { 0x1f, 0x8b, Z_DEFLATED, 0, 0, 0, 0, 0, 0, 3 };
struct uwsgi_buffer *uwsgi_gzip(char *buf, size_t len) {
z_stream z;
struct uwsgi_buffer *ub = NULL;
uint32_t gzip_crc32 = 0;
char *gzipped = NULL;
char *gzipped0 = NULL;
size_t dlen = 0;
size_t dlen0 = 0;
uwsgi_crc32(&gzip_crc32, NULL, 0);
if (uwsgi_deflate_init(&z, NULL, 0)) return NULL;
uwsgi_crc32(&gzip_crc32, buf, len);
gzipped = uwsgi_deflate(&z, buf, len, &dlen);
if (!gzipped) goto end;
gzipped0 = uwsgi_deflate(&z, NULL, 0, &dlen0);
if (!gzipped0) goto end;
ub = uwsgi_buffer_new(10 + dlen + dlen0 + 8);
if (uwsgi_buffer_append(ub, gzheader, 10)) goto end;
if (uwsgi_buffer_append(ub, gzipped, dlen)) goto end;
if (uwsgi_buffer_append(ub, gzipped0, dlen0)) goto end;
if (uwsgi_buffer_u32le(ub, gzip_crc32)) goto end;
if (uwsgi_buffer_u32le(ub, len)) goto end;
end:
if (gzipped) free(gzipped);
if (gzipped0) free(gzipped0);
deflateEnd(&z);
return ub;
}
int uwsgi_deflate_init(z_stream *z, char *dict, size_t dict_len) {
z->zalloc = Z_NULL;
+27
View File
@@ -23,6 +23,9 @@ struct uwsgi_router_cache_conf {
char *key;
size_t key_len;
char *gzip;
size_t gzip_len;
char *content_type;
size_t content_type_len;
@@ -46,6 +49,11 @@ static int uwsgi_routing_func_cache_store(struct wsgi_request *wsgi_req, struct
wsgi_req->cache_it = NULL;
}
if (wsgi_req->cache_it_gzip) {
uwsgi_buffer_destroy(wsgi_req->cache_it_gzip);
wsgi_req->cache_it_gzip = NULL;
}
if (wsgi_req->cache_it_to) {
uwsgi_buffer_destroy(wsgi_req->cache_it_to);
wsgi_req->cache_it_to = NULL;
@@ -63,6 +71,20 @@ static int uwsgi_routing_func_cache_store(struct wsgi_request *wsgi_req, struct
if (!wsgi_req->cache_it_to) {
uwsgi_buffer_destroy(wsgi_req->cache_it);
wsgi_req->cache_it = NULL;
return UWSGI_ROUTE_NEXT;
}
}
if (urcc->gzip) {
wsgi_req->cache_it_gzip = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, urcc->gzip, urcc->gzip_len);
if (!wsgi_req->cache_it_gzip) {
uwsgi_buffer_destroy(wsgi_req->cache_it);
wsgi_req->cache_it = NULL;
if (wsgi_req->cache_it_to) {
uwsgi_buffer_destroy(wsgi_req->cache_it_to);
wsgi_req->cache_it_to = NULL;
}
return UWSGI_ROUTE_NEXT;
}
}
@@ -111,6 +133,7 @@ static int uwsgi_router_cache_store(struct uwsgi_route *ur, char *args) {
struct uwsgi_router_cache_conf *urcc = uwsgi_calloc(sizeof(struct uwsgi_router_cache_conf));
if (uwsgi_kvlist_parse(ur->data, ur->data_len, ',', '=',
"key", &urcc->key,
"gzip", &urcc->gzip,
"name", &urcc->name,
"expires", &urcc->expires_str, NULL)) {
uwsgi_log("invalid cachestore route syntax: %s\n", args);
@@ -121,6 +144,10 @@ static int uwsgi_router_cache_store(struct uwsgi_route *ur, char *args) {
urcc->key_len = strlen(urcc->key);
}
if (urcc->gzip) {
urcc->gzip_len = strlen(urcc->gzip);
}
if (urcc->name) {
urcc->name_len = strlen(urcc->name);
}
+2
View File
@@ -1396,6 +1396,7 @@ struct wsgi_request {
uint32_t route_goto;
struct uwsgi_buffer *cache_it;
struct uwsgi_buffer *cache_it_gzip;
struct uwsgi_buffer *cache_it_to;
uint64_t cache_it_expires;
struct uwsgi_buffer *cached_response;
@@ -3897,6 +3898,7 @@ int uwsgi_emperor_vassal_start(struct uwsgi_instance *);
int uwsgi_deflate_init(z_stream *, char *, size_t);
char *uwsgi_deflate(z_stream *, char *, size_t, size_t *);
void uwsgi_crc32(uint32_t *, char *, size_t);
struct uwsgi_buffer *uwsgi_gzip(char *, size_t);
#endif
char *uwsgi_get_cookie(struct wsgi_request *, char *, uint16_t, uint16_t *);