summaryrefslogtreecommitdiff
path: root/proto_text.c
diff options
context:
space:
mode:
authordormando <dormando@rydia.net>2020-11-12 14:39:32 -0800
committerdormando <dormando@rydia.net>2021-06-07 22:06:55 -0700
commitf4aee656741421a41bc5e128f10e15be703c8927 (patch)
tree9db38f4eca25898e26e037ec37ff340fa95dfafa /proto_text.c
parent17640549935019ca3367aaacaabc66550a6f2908 (diff)
downloadmemcached-f4aee656741421a41bc5e128f10e15be703c8927.tar.gz
meta: 'b' flag for ME to return base64 keys
Diffstat (limited to 'proto_text.c')
-rw-r--r--proto_text.c25
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++;