diff options
author | dormando <dormando@rydia.net> | 2020-11-12 14:39:32 -0800 |
---|---|---|
committer | dormando <dormando@rydia.net> | 2021-06-07 22:06:55 -0700 |
commit | f4aee656741421a41bc5e128f10e15be703c8927 (patch) | |
tree | 9db38f4eca25898e26e037ec37ff340fa95dfafa /proto_text.c | |
parent | 17640549935019ca3367aaacaabc66550a6f2908 (diff) | |
download | memcached-f4aee656741421a41bc5e128f10e15be703c8927.tar.gz |
meta: 'b' flag for ME to return base64 keys
Diffstat (limited to 'proto_text.c')
-rw-r--r-- | proto_text.c | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/proto_text.c b/proto_text.c index ce1b030..6e15799 100644 --- a/proto_text.c +++ b/proto_text.c @@ -745,12 +745,11 @@ static void process_stat(conn *c, token_t *tokens, const size_t ntokens) { } } -// TODO: if 'b' after "ME key" decode the key. // slow snprintf for debugging purposes. static void process_meta_command(conn *c, token_t *tokens, const size_t ntokens) { assert(c != NULL); - if (tokens[KEY_TOKEN].length > KEY_MAX_LENGTH) { + if (ntokens < 3 || tokens[KEY_TOKEN].length > KEY_MAX_LENGTH) { out_string(c, "CLIENT_ERROR bad command line format"); return; } @@ -758,6 +757,17 @@ static void process_meta_command(conn *c, token_t *tokens, const size_t ntokens) char *key = tokens[KEY_TOKEN].value; size_t nkey = tokens[KEY_TOKEN].length; + if (ntokens >= 4 && tokens[2].length == 1 && tokens[2].value[0] == 'b') { + size_t ret = base64_decode((unsigned char *)key, nkey, + (unsigned char *)key, nkey); + if (ret == 0) { + // failed to decode. + out_string(c, "CLIENT_ERROR bad command line format"); + return; + } + nkey = ret; + } + bool overflow; // not used here. item *it = limited_get(key, nkey, c, 0, false, DONT_UPDATE, &overflow); if (it) { @@ -767,8 +777,15 @@ static void process_meta_command(conn *c, token_t *tokens, const size_t ntokens) // similar to out_string(). memcpy(resp->wbuf, "ME ", 3); total += 3; - memcpy(resp->wbuf + total, ITEM_key(it), it->nkey); - total += it->nkey; + if (it->it_flags & ITEM_KEY_BINARY) { + // re-encode from memory rather than copy the original key; + // to help give confidence that what in memory is what we asked + // for. + total += base64_encode((unsigned char *) ITEM_key(it), it->nkey, (unsigned char *)resp->wbuf + total, WRITE_BUFFER_SIZE - total); + } else { + memcpy(resp->wbuf + total, ITEM_key(it), it->nkey); + total += it->nkey; + } resp->wbuf[total] = ' '; total++; |