memcache/command.c
author Tero Marttila <terom@fixme.fi>
Fri, 29 Aug 2008 23:31:17 +0300
changeset 48 1c67f512779b
parent 46 8a832c0e01ee
permissions -rw-r--r--
fix doc tpyos, rename some enums, fix printf format len for non-zero terminated strings (hg status), pass args to memcache_cmd_format_header via memcache_req_*, handle zero-length STORE requests, memcache_req is_buf_ours + free, other function name typos (keymemcache_req_key), fix req state behaviour re *_DATA_* for STORE requests and FETCH/END, better memcache_server connpool events/management, modular memcache_test with a working benchmark. This is a long commit message.
42
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
     1
#include <string.h>
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
     2
#include <stdlib.h>
41
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     3
#include <assert.h>
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     4
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     5
#include "command.h"
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     6
#include "../common.h"
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     7
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     8
static char *memcache_cmd_names[MEMCACHE_CMD_MAX] = {
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     9
    NULL,       // MEMCACHE_CMD_INVALID
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    10
    "get",      // MEMCACHE_CMD_FETCH_GET
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    11
    "set",      // MEMCACHE_CMD_STORE_SET
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    12
    "add",      // MEMCACHE_CMD_STORE_ADD
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    13
    "replace",  // MEMCACHE_CMD_STORE_REPLACE
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    14
    "append",   // MEMCACHE_CMD_STORE_APPEND
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    15
    "prepend"   // MEMCACHE_CMD_STORE_PREPEND
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    16
};
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    17
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    18
static struct memcache_reply_info {
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    19
    enum memcache_reply type;
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    20
    char *name;
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    21
42
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
    22
} memcache_cmd_replies[MEMCACHE_RPL_MAX] = {
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
    23
    {   MEMCACHE_RPL_INVALID,       NULL            },
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
    24
    {   MEMCACHE_RPL_ERROR,         "ERROR"         },
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
    25
    {   MEMCACHE_RPL_CLIENT_ERROR,  "CLIENT_ERROR"  },
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
    26
    {   MEMCACHE_RPL_SERVER_ERROR,  "SERVER_ERROR"  },
41
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    27
    
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    28
    // MEMCACHE_CMD_FETCH_*
42
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
    29
    {   MEMCACHE_RPL_VALUE,         "VALUE"         },
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
    30
    {   MEMCACHE_RPL_END,           "END"           },
41
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    31
    
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    32
    // MEMCACHE_CMD_STORE_*
42
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
    33
    {   MEMCACHE_RPL_STORED,        "STORED"        },
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
    34
    {   MEMCACHE_RPL_NOT_STORED,    "NOT_STORED"    },
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
    35
    {   MEMCACHE_RPL_EXISTS,        "EXISTS"        },
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
    36
    {   MEMCACHE_RPL_NOT_FOUND,     "NOT_FOUND"     }
41
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    37
};
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    38
42
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
    39
41
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    40
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    41
int memcache_cmd_init (struct memcache_cmd *cmd, enum memcache_command cmd_type, struct memcache_key *key, struct memcache_obj *obj) {
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    42
    // shouldn't already have a request header yet?
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    43
    assert(cmd->req_header == NULL);
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    44
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    45
    // allocate the request header
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    46
    if ((cmd->req_header = evbuffer_new()) == NULL)
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    47
        ERROR("evbuffer_new");
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    48
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    49
    // format the command
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    50
    if (memcache_cmd_format_header(cmd->req_header, cmd_type, key, obj))
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    51
        goto error;
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    52
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    53
    // XXX: prepare the rest
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    54
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    55
    // success
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    56
    return 0;
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    57
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    58
error:    
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    59
    if (cmd->req_header)
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    60
        evbuffer_free(cmd->req_header);
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    61
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    62
    return -1;
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    63
}
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    64
48
1c67f512779b fix doc tpyos, rename some enums, fix printf format len for non-zero terminated strings (hg status), pass args to memcache_cmd_format_header via memcache_req_*, handle zero-length STORE requests, memcache_req is_buf_ours + free, other function name typos (keymemcache_req_key), fix req state behaviour re *_DATA_* for STORE requests and FETCH/END, better memcache_server connpool events/management, modular memcache_test with a working benchmark. This is a long commit message.
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
    65
int memcache_cmd_format_header (struct evbuffer *buf, enum memcache_command cmd_type, const struct memcache_key *key, const struct memcache_obj *obj) {
41
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    66
    char *cmd_name;
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    67
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    68
    // valid command
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    69
    assert(cmd_type < MEMCACHE_CMD_MAX);
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    70
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    71
    if (cmd_type == MEMCACHE_CMD_INVALID)
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    72
        ERROR("invalid command");
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    73
    
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    74
    // map the command to a string
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    75
    cmd_name = memcache_cmd_names[cmd_type];
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    76
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    77
    // format the request header
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    78
    switch (cmd_type) {
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    79
        case MEMCACHE_CMD_FETCH_GET:
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    80
            assert(key != NULL && obj == NULL);
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    81
            assert(key->len > 0 && key->buf != NULL);
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    82
48
1c67f512779b fix doc tpyos, rename some enums, fix printf format len for non-zero terminated strings (hg status), pass args to memcache_cmd_format_header via memcache_req_*, handle zero-length STORE requests, memcache_req is_buf_ours + free, other function name typos (keymemcache_req_key), fix req state behaviour re *_DATA_* for STORE requests and FETCH/END, better memcache_server connpool events/management, modular memcache_test with a working benchmark. This is a long commit message.
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
    83
            if (evbuffer_add_printf(buf, "%s %.*s\r\n", cmd_name, (int) key->len, key->buf) == -1)
41
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    84
                ERROR("evbuffer_add_printf");
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    85
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    86
            break;
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    87
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    88
        case MEMCACHE_CMD_STORE_SET:
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    89
        case MEMCACHE_CMD_STORE_ADD:
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    90
        case MEMCACHE_CMD_STORE_REPLACE:
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    91
        case MEMCACHE_CMD_STORE_APPEND:
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    92
        case MEMCACHE_CMD_STORE_PREPEND:
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    93
            assert(key != NULL && obj != NULL);
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    94
            assert(key->len > 0 && key->buf != NULL);
43
e5b714190dee the request/reply code should be complete now, but still needs testing
Tero Marttila <terom@fixme.fi>
parents: 42
diff changeset
    95
            // XXX: ensure that we have a valid buf
41
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    96
48
1c67f512779b fix doc tpyos, rename some enums, fix printf format len for non-zero terminated strings (hg status), pass args to memcache_cmd_format_header via memcache_req_*, handle zero-length STORE requests, memcache_req is_buf_ours + free, other function name typos (keymemcache_req_key), fix req state behaviour re *_DATA_* for STORE requests and FETCH/END, better memcache_server connpool events/management, modular memcache_test with a working benchmark. This is a long commit message.
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
    97
            if (evbuffer_add_printf(buf, "%s %.*s %u %lu %zu\r\n", cmd_name, (int) key->len, key->buf, obj->flags, obj->exptime, obj->bytes) == -1)
41
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    98
                ERROR("evbuffer_add_printf");
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    99
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   100
            break;
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   101
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   102
        case MEMCACHE_CMD_STORE_CAS:
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   103
        default:
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   104
            // XXX: not supported yet/invalid
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   105
            assert(0);
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   106
    };
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   107
    
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   108
    // success
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   109
    return 0;
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   110
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   111
error:
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   112
    return -1;
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   113
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   114
}
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   115
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   116
int memcache_cmd_parse_header (struct evbuffer *buf, char **header_data, enum memcache_reply *reply_type, struct memcache_key *key, struct memcache_obj *obj, int *has_data) {
42
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   117
    size_t line_length, buf_size;
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   118
    char *line = NULL, *token_cursor, *token, *invalid;
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   119
    int i;
43
e5b714190dee the request/reply code should be complete now, but still needs testing
Tero Marttila <terom@fixme.fi>
parents: 42
diff changeset
   120
   
e5b714190dee the request/reply code should be complete now, but still needs testing
Tero Marttila <terom@fixme.fi>
parents: 42
diff changeset
   121
    // read lines until we find one that isn't empty
e5b714190dee the request/reply code should be complete now, but still needs testing
Tero Marttila <terom@fixme.fi>
parents: 42
diff changeset
   122
    do {
e5b714190dee the request/reply code should be complete now, but still needs testing
Tero Marttila <terom@fixme.fi>
parents: 42
diff changeset
   123
        // take note of how long the buffer is
e5b714190dee the request/reply code should be complete now, but still needs testing
Tero Marttila <terom@fixme.fi>
parents: 42
diff changeset
   124
        buf_size = evbuffer_get_length(buf);
42
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   125
43
e5b714190dee the request/reply code should be complete now, but still needs testing
Tero Marttila <terom@fixme.fi>
parents: 42
diff changeset
   126
        // free the prvious line in case it was empty
e5b714190dee the request/reply code should be complete now, but still needs testing
Tero Marttila <terom@fixme.fi>
parents: 42
diff changeset
   127
        free(line);
42
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   128
43
e5b714190dee the request/reply code should be complete now, but still needs testing
Tero Marttila <terom@fixme.fi>
parents: 42
diff changeset
   129
        // try and read a line
e5b714190dee the request/reply code should be complete now, but still needs testing
Tero Marttila <terom@fixme.fi>
parents: 42
diff changeset
   130
        if ((line = evbuffer_readln(buf, &line_length, EVBUFFER_EOL_CRLF_STRICT)) == NULL) {
e5b714190dee the request/reply code should be complete now, but still needs testing
Tero Marttila <terom@fixme.fi>
parents: 42
diff changeset
   131
            // check if any data was consumed
e5b714190dee the request/reply code should be complete now, but still needs testing
Tero Marttila <terom@fixme.fi>
parents: 42
diff changeset
   132
            if (evbuffer_get_length(buf) != buf_size) {
e5b714190dee the request/reply code should be complete now, but still needs testing
Tero Marttila <terom@fixme.fi>
parents: 42
diff changeset
   133
                // faaaail!
e5b714190dee the request/reply code should be complete now, but still needs testing
Tero Marttila <terom@fixme.fi>
parents: 42
diff changeset
   134
                return -1;
e5b714190dee the request/reply code should be complete now, but still needs testing
Tero Marttila <terom@fixme.fi>
parents: 42
diff changeset
   135
e5b714190dee the request/reply code should be complete now, but still needs testing
Tero Marttila <terom@fixme.fi>
parents: 42
diff changeset
   136
            } else {
e5b714190dee the request/reply code should be complete now, but still needs testing
Tero Marttila <terom@fixme.fi>
parents: 42
diff changeset
   137
                // no complete line found
e5b714190dee the request/reply code should be complete now, but still needs testing
Tero Marttila <terom@fixme.fi>
parents: 42
diff changeset
   138
                return 0;
e5b714190dee the request/reply code should be complete now, but still needs testing
Tero Marttila <terom@fixme.fi>
parents: 42
diff changeset
   139
            }
42
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   140
        }
43
e5b714190dee the request/reply code should be complete now, but still needs testing
Tero Marttila <terom@fixme.fi>
parents: 42
diff changeset
   141
e5b714190dee the request/reply code should be complete now, but still needs testing
Tero Marttila <terom@fixme.fi>
parents: 42
diff changeset
   142
    } while (line_length == 0);
42
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   143
    
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   144
    // just check to make sure that it really is null-delimited
46
8a832c0e01ee bugfixed, enum->string mappings, test does requests
Tero Marttila <terom@fixme.fi>
parents: 43
diff changeset
   145
    assert(line[line_length] == '\0');
42
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   146
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   147
    // use strsep
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   148
    token_cursor = line;
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   149
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   150
    // the first token should be the reply name
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   151
    if ((token = strsep(&token_cursor, " ")) == NULL)
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   152
        ERROR("no reply name in response line: %s", line);
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   153
    
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   154
    // figure out the reply type
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   155
    for (i = MEMCACHE_RPL_INVALID + 1; i < MEMCACHE_RPL_MAX; i++) {
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   156
        if (strcmp(token, memcache_cmd_replies[i].name) == 0)
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   157
            break;
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   158
    }
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   159
    
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   160
    // did we figure out what this reply means?
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   161
    if (i == MEMCACHE_RPL_MAX)
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   162
        ERROR("unrecognized reply: %s", line);
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   163
    
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   164
    // we found the type
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   165
    *reply_type = memcache_cmd_replies[i].type;
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   166
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   167
    // default to no data
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   168
    *has_data = 0;
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   169
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   170
    switch (*reply_type) {
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   171
        case MEMCACHE_RPL_ERROR:
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   172
            // no additional data
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   173
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   174
            break;
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   175
        
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   176
        case MEMCACHE_RPL_CLIENT_ERROR:
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   177
        case MEMCACHE_RPL_SERVER_ERROR:
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   178
            // the rest of the line is a human-readable error message
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   179
            WARNING("received a %s reply: %s", token, token_cursor);
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   180
            
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   181
            break;
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   182
        
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   183
        case MEMCACHE_RPL_VALUE:
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   184
            // <key> <flags> <bytes> [<cas unique>]
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   185
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   186
            // the key field
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   187
            if ((key->buf = strsep(&token_cursor, " ")) == NULL)
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   188
                ERROR("missing key in VALUE reply");
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   189
            
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   190
            if ((key->len = strlen(key->buf)) == 0)
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   191
                ERROR("zero-length key in VALUE reply");
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   192
            
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   193
            // the flags field
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   194
            if ((token = strsep(&token_cursor, " ")) == NULL)
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   195
                ERROR("missing flags in VALUE reply");
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   196
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   197
            obj->flags = (u_int32_t) strtol(token, &invalid, 10);
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   198
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   199
            if (*invalid != '\0')
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   200
                ERROR("invalid flags in VALUE reply: %s (%s)", token, invalid);
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   201
            
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   202
            // the bytes field
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   203
            if ((token = strsep(&token_cursor, " ")) == NULL)
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   204
                ERROR("missing bytes in VALUE reply");
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   205
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   206
            obj->bytes = (u_int32_t) strtol(token, &invalid, 10);
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   207
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   208
            if (*invalid != '\0')
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   209
                ERROR("invalid bytes in VALUE reply: %s (%s)", token, invalid);
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   210
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   211
            // the optional cas field
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   212
            if ((token = strsep(&token_cursor, " ")) != NULL) {
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   213
                // there is a cas value present
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   214
                obj->cas = (u_int64_t) strtoll(token, &invalid, 10);
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   215
                
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   216
                if (*invalid != '\0')
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   217
                    ERROR("invalid cas value in VALUE reply: %s (%s)", token, invalid);
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   218
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   219
            } else {
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   220
                obj->cas = 0;
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   221
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   222
            }
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   223
            
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   224
            // and we do have data following this
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   225
            *has_data = 1;
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   226
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   227
            break;
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   228
        
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   229
        case MEMCACHE_RPL_END:
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   230
            // no additional data
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   231
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   232
            break;
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   233
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   234
        case MEMCACHE_RPL_STORED:
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   235
        case MEMCACHE_RPL_NOT_STORED:
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   236
        case MEMCACHE_RPL_EXISTS:
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   237
        case MEMCACHE_RPL_NOT_FOUND:
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   238
            // no additional data
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   239
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   240
            break;
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   241
        
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   242
        default:
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   243
            assert(0);
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   244
    };
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   245
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   246
    // success
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   247
    *header_data = line;
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   248
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   249
    return 0;
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   250
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   251
error:
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   252
    free(line);
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   253
0e503189af2f more reply-receiving code, but still incomplete
Tero Marttila <terom@fixme.fi>
parents: 41
diff changeset
   254
    return -1;
41
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   255
}
540737bf6bac sending requests, and partial support for receiving -- incomplete, not tested
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   256