Skip to content

Commit

Permalink
added cache check for max item size
Browse files Browse the repository at this point in the history
  • Loading branch information
unbit committed Mar 8, 2013
1 parent cd29b03 commit e418a35
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 47 deletions.
111 changes: 75 additions & 36 deletions core/cache.c
Expand Up @@ -546,7 +546,7 @@ int uwsgi_cache_set2(struct uwsgi_cache *uc, char *key, uint16_t keylen, char *v
if (keylen > uc->keysize)
return -1;

if (!uc->blocks_bitmap && vallen > uc->blocksize) return -1;
if (vallen > uc->max_item_size) return -1;

//uwsgi_log("putting cache data in key %.*s %d\n", keylen, key, vallen);
index = uwsgi_cache_get_index(uc, key, keylen);
Expand Down Expand Up @@ -946,6 +946,7 @@ struct uwsgi_cache *uwsgi_cache_create(char *arg) {
uc->name = "default";
uc->name_len = strlen(uc->name);
uc->blocksize = uwsgi.cache_blocksize;
uc->max_item_size = uc->blocksize;
if (!uc->blocksize) uc->blocksize = UMAX16;
uc->max_items = uwsgi.cache_max_items;
uc->blocks = uwsgi.cache_max_items;
Expand Down Expand Up @@ -1024,6 +1025,7 @@ struct uwsgi_cache *uwsgi_cache_create(char *arg) {
// defaults
uc->blocks = uc->max_items;
uc->blocksize = UMAX16;
uc->max_item_size = uc->blocksize;
uc->keysize = 2048;
uc->hashsize = UMAX16;
uc->hash = uwsgi_hash_algo_get("djb33x");
Expand All @@ -1039,7 +1041,10 @@ struct uwsgi_cache *uwsgi_cache_create(char *arg) {
if (!uc->hashsize) { uwsgi_log("invalid cache hashsize for \"%s\"\n", uc->name); exit(1); }
if (c_keysize) uc->keysize = uwsgi_n64(c_keysize);
if (!uc->keysize || uc->keysize >= UMAX16) { uwsgi_log("invalid cache keysize for \"%s\"\n", uc->name); exit(1); }
if (c_bitmap) uc->use_blocks_bitmap = 1;
if (c_bitmap) {
uc->use_blocks_bitmap = 1;
uc->max_item_size = uc->blocksize * uc->blocks;
}

uc->store_sync = uwsgi.cache_store_sync;
if (c_store_sync) { uc->store_sync = uwsgi_n64(c_store_sync); }
Expand Down Expand Up @@ -1268,6 +1273,28 @@ struct uwsgi_buffer *uwsgi_cache_prepare_magic_update(char *cache_name, uint16_t
return NULL;
}

static int cache_magic_send_and_manage(int fd, struct uwsgi_buffer *ub, char *stream, uint64_t stream_len, int timeout, struct uwsgi_cache_magic_context *ucmc) {
if (uwsgi_buffer_set_uh(ub, 111, 17)) return -1;

if (stream) {
if (uwsgi_buffer_append(ub, stream, stream_len)) return -1;
}

if (uwsgi_write_true_nb(fd, ub->buf, ub->pos, timeout)) return -1;

// ok now wait for the response, using the same buffer of the request
// NOTE: after using a uwsgi_buffer in that way we basically destroy (even if we can safely free it)
size_t rlen = ub->pos;
if (uwsgi_read_with_realloc(fd, &ub->buf, &rlen, timeout)) return -1;
// try to fix the buffer to maintain size info
ub->pos = rlen;

// now we have a uwsgi dictionary with all of the options needed, let's parse it
memset(ucmc, 0, sizeof(struct uwsgi_cache_magic_context));
if (uwsgi_hooked_parse(ub->buf, rlen, uwsgi_cache_magic_context_hook, ucmc)) return -1;
return 0;
}

char *uwsgi_cache_magic_get(char *key, uint16_t keylen, uint64_t *vallen, char *cache) {
struct uwsgi_cache_magic_context ucmc;
struct uwsgi_cache *uc = NULL;
Expand Down Expand Up @@ -1309,7 +1336,6 @@ char *uwsgi_cache_magic_get(char *key, uint16_t keylen, uint64_t *vallen, char *
int fd = uwsgi_connect(cache_server, 0, 1);
if (fd < 0) return NULL;

// wait for connection;
int ret = uwsgi.wait_write_hook(fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
if (ret <= 0) {
close(fd);
Expand All @@ -1322,33 +1348,10 @@ char *uwsgi_cache_magic_get(char *key, uint16_t keylen, uint64_t *vallen, char *
return NULL;
}

if (uwsgi_buffer_set_uh(ub, 111, 17)) {
if (cache_magic_send_and_manage(fd, ub, NULL, 0, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], &ucmc)) {
close(fd);
uwsgi_buffer_destroy(ub);
return NULL;
}

if (uwsgi_write_true_nb(fd, ub->buf, ub->pos, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT])) {
close(fd);
uwsgi_buffer_destroy(ub);
return NULL;
}

// ok now wait for the response, using the same buffer of the request
// NOTE: after using a uwsgi_buffer in that way we basically destroy (even if we can safely free it)
size_t rlen = ub->pos;
if (uwsgi_read_with_realloc(fd, &ub->buf, &rlen, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT])) {
close(fd);
uwsgi_buffer_destroy(ub);
return NULL;
}

// now we have a uwsgi dictionary with all of the options needed, let's parse it
memset(&ucmc, 0, sizeof(struct uwsgi_cache_magic_context));
if (uwsgi_hooked_parse(ub->buf, rlen, uwsgi_cache_magic_context_hook, &ucmc)) {
close(fd);
uwsgi_buffer_destroy(ub);
return NULL;
uwsgi_buffer_destroy(ub);
return NULL;
}

if (uwsgi_strncmp(ucmc.status, ucmc.status_len, "ok", 2)) {
Expand All @@ -1364,7 +1367,7 @@ char *uwsgi_cache_magic_get(char *key, uint16_t keylen, uint64_t *vallen, char *
}

// ok we now need to fix our buffer (if needed)
if (ucmc.size > rlen) {
if (ucmc.size > ub->pos) {
char *tmp_buf = realloc(ub->buf, ucmc.size);
if (!tmp_buf) {
uwsgi_error("uwsgi_cache_magic_get()/realloc()");
Expand All @@ -1375,6 +1378,7 @@ char *uwsgi_cache_magic_get(char *key, uint16_t keylen, uint64_t *vallen, char *
ub->buf = tmp_buf;
}

// read the raw value from the socket
if (uwsgi_read_whole_true_nb(fd, ub->buf, ucmc.size, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT])) {
close(fd);
uwsgi_buffer_destroy(ub);
Expand All @@ -1394,16 +1398,21 @@ char *uwsgi_cache_magic_get(char *key, uint16_t keylen, uint64_t *vallen, char *
}


int uwsgi_cache_magic_set(char *key, uint16_t keylen, char *value, uint64_t vallen, uint64_t expires, uint64_t flags, char *cachename) {

struct uwsgi_cache *uc = NULL;
int uwsgi_cache_magic_set(char *key, uint16_t keylen, char *value, uint64_t vallen, uint64_t expires, uint64_t flags, char *cache) {
struct uwsgi_cache_magic_context ucmc;
struct uwsgi_cache *uc = NULL;
char *cache_server = NULL;
if (cachename) {
char *at = strchr(cachename, '@');
char *cache_name = NULL;
uint16_t cache_name_len = 0;
if (cache) {
char *at = strchr(cache, '@');
if (!at) {
uc = uwsgi_cache_by_name(cachename);
uc = uwsgi_cache_by_name(cache);
}
else {
cache_server = at + 1;
cache_name = cache;
cache_name_len = at - cache;
}
}
// use default (local) cache
Expand All @@ -1421,6 +1430,36 @@ int uwsgi_cache_magic_set(char *key, uint16_t keylen, char *value, uint64_t vall

// we have a remote one
if (cache_server) {
int fd = uwsgi_connect(cache_server, 0, 1);
if (fd < 0) return -1;

int ret = uwsgi.wait_write_hook(fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
if (ret <= 0) {
close(fd);
return -1;
}

struct uwsgi_buffer *ub = uwsgi_cache_prepare_magic_set(cache_name, cache_name_len, key, keylen, vallen, expires);
if (!ub) {
close(fd);
return -1;
}

if (cache_magic_send_and_manage(fd, ub, value, vallen, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], &ucmc)) {
close(fd);
uwsgi_buffer_destroy(ub);
return -1;
}

if (uwsgi_strncmp(ucmc.status, ucmc.status_len, "ok", 2)) {
close(fd);
uwsgi_buffer_destroy(ub);
return -1;
}

uwsgi_buffer_destroy(ub);
return 0;

}

return -1;
Expand Down
6 changes: 6 additions & 0 deletions plugins/cache/cache.c
Expand Up @@ -97,6 +97,12 @@ static void manage_magic_context(struct wsgi_request *wsgi_req, struct uwsgi_cac
return;
}

// cache set
if (!uwsgi_strncmp(ucmc->cmd, ucmc->cmd_len, "set", 3)) {
// allocate memory for the item
}

return;
error:
uwsgi_rwunlock(uc->lock);
uwsgi_buffer_destroy(ub);
Expand Down
18 changes: 7 additions & 11 deletions plugins/python/uwsgi_pymodule.c
Expand Up @@ -2581,25 +2581,21 @@ PyObject *py_uwsgi_cache_set(PyObject * self, PyObject * args) {
char *value;
Py_ssize_t vallen = 0;
Py_ssize_t keylen = 0;
char *remote = NULL;

uint64_t expires = 0;

if (!PyArg_ParseTuple(args, "s#s#|i:cache_set", &key, &keylen, &value, &vallen, &expires)) {
if (!PyArg_ParseTuple(args, "s#s#|is:cache_set", &key, &keylen, &value, &vallen, &expires, &remote)) {
return NULL;
}

if (uwsgi.caches) {
UWSGI_RELEASE_GIL
uwsgi_wlock(uwsgi.caches->lock);
if (uwsgi_cache_set(key, keylen, value, vallen, expires, 0)) {
uwsgi_rwunlock(uwsgi.caches->lock);
UWSGI_GET_GIL
Py_INCREF(Py_None);
return Py_None;
}
uwsgi_rwunlock(uwsgi.caches->lock);
UWSGI_RELEASE_GIL
if (uwsgi_cache_magic_set(key, keylen, value, vallen, expires, 0, remote)) {
UWSGI_GET_GIL
Py_INCREF(Py_None);
return Py_None;
}
UWSGI_GET_GIL

Py_INCREF(Py_True);
return Py_True;
Expand Down
1 change: 1 addition & 0 deletions uwsgi.h
Expand Up @@ -690,6 +690,7 @@ struct uwsgi_cache {
uint64_t blocks_bitmap_size;

uint64_t max_items;
uint64_t max_item_size;
uint64_t n_items;
struct uwsgi_cache_item *items;

Expand Down

0 comments on commit e418a35

Please sign in to comment.