- rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
- }
-
- return rval;
-}
-
-/**
- * Callback for FLUSH and FLUSHQ
- * @param cookie the calling client
- * @param header the command
- * @param response_handler not used
- * @return the result of the operation
- */
-static protocol_binary_response_status
-flush_command_handler(const void *cookie,
- protocol_binary_request_header *header,
- memcached_binary_protocol_raw_response_handler response_handler)
-{
- (void)response_handler;
- protocol_binary_response_status rval;
-
- struct memcached_binary_protocol_client_st *client= (void*)cookie;
- if (client->root->callback->interface.v1.flush != NULL)
- {
- protocol_binary_request_flush *flush= (void*)header;
- uint32_t timeout= 0;
- if (htonl(header->request.bodylen) == 4)
- {
- timeout= ntohl(flush->message.body.expiration);
- }
-
- rval= client->root->callback->interface.v1.flush(cookie, timeout);
- if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS &&
- header->request.opcode == PROTOCOL_BINARY_CMD_FLUSH)
- {
- /* Send a positive request */
- protocol_binary_response_no_extras response= {
- .message= {
- .header.response= {
- .magic= PROTOCOL_BINARY_RES,
- .opcode= PROTOCOL_BINARY_CMD_FLUSH,
- .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
- .opaque= header->request.opaque,
- }
- }
- };
- rval= response_handler(cookie, header, (void*)&response);
- }
- }
- else
- {
- rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
- }
-
- return rval;
-}
-
-/**
- * Callback for GET, GETK, GETQ, GETKQ
- * @param cookie the calling client
- * @param header the command
- * @param response_handler not used
- * @return the result of the operation
- */
-static protocol_binary_response_status
-get_command_handler(const void *cookie,
- protocol_binary_request_header *header,
- memcached_binary_protocol_raw_response_handler response_handler)
-{
- (void)response_handler;
- protocol_binary_response_status rval;
-
- struct memcached_binary_protocol_client_st *client= (void*)cookie;
- if (client->root->callback->interface.v1.get != NULL)
- {
- uint16_t keylen= ntohs(header->request.keylen);
- void *key= (header + 1);
- rval= client->root->callback->interface.v1.get(cookie, key, keylen,
- get_response_handler);
-
- if (rval == PROTOCOL_BINARY_RESPONSE_KEY_ENOENT &&
- (header->request.opcode == PROTOCOL_BINARY_CMD_GETQ ||
- header->request.opcode == PROTOCOL_BINARY_CMD_GETKQ))
- {
- /* Quiet commands shouldn't respond on cache misses */
- rval= PROTOCOL_BINARY_RESPONSE_SUCCESS;
- }
- }
- else
- {
- rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
- }
-
- return rval;
-}
-
-/**
- * Callback for INCREMENT and INCREMENTQ
- * @param cookie the calling client
- * @param header the command
- * @param response_handler not used
- * @return the result of the operation
- */
-static protocol_binary_response_status
-increment_command_handler(const void *cookie,
- protocol_binary_request_header *header,
- memcached_binary_protocol_raw_response_handler response_handler)
-{
- (void)response_handler;
- protocol_binary_response_status rval;
-
- struct memcached_binary_protocol_client_st *client= (void*)cookie;
- if (client->root->callback->interface.v1.increment != NULL)
- {
- uint16_t keylen= ntohs(header->request.keylen);
- protocol_binary_request_incr *request= (void*)header;
- uint64_t init= ntohll(request->message.body.initial);
- uint64_t delta= ntohll(request->message.body.delta);
- uint32_t timeout= ntohl(request->message.body.expiration);
- void *key= request->bytes + sizeof(request->bytes);
- uint64_t cas;
- uint64_t result;
-
- rval= client->root->callback->interface.v1.increment(cookie, key, keylen,
- delta, init, timeout,
- &result, &cas);
- if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS &&
- header->request.opcode == PROTOCOL_BINARY_CMD_INCREMENT)
- {
- /* Send a positive request */
- protocol_binary_response_incr response= {
- .message= {
- .header.response= {
- .magic= PROTOCOL_BINARY_RES,
- .opcode= PROTOCOL_BINARY_CMD_INCREMENT,
- .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
- .opaque= header->request.opaque,
- .cas= ntohll(cas),
- .bodylen= htonl(8)
- },
- .body.value = htonll(result)
- }
- };
-
- rval= response_handler(cookie, header, (void*)&response);
- }
- }
- else
- {
- rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
- }
-
- return rval;
-}
-
-/**
- * Callback for noop. Inform the v1 interface about the noop packet, and
- * create and send a packet back to the client
- *
- * @param cookie the calling client
- * @param header the command
- * @param response_handler the response handler
- * @return the result of the operation
- */
-static protocol_binary_response_status
-noop_command_handler(const void *cookie,
- protocol_binary_request_header *header,
- memcached_binary_protocol_raw_response_handler response_handler)
-{
- struct memcached_binary_protocol_client_st *client= (void*)cookie;
- if (client->root->callback->interface.v1.noop != NULL)
- {
- client->root->callback->interface.v1.noop(cookie);
- }
-
- protocol_binary_response_no_extras response= {
- .message = {
- .header.response = {
- .magic = PROTOCOL_BINARY_RES,
- .opcode= PROTOCOL_BINARY_CMD_NOOP,
- .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
- .opaque= header->request.opaque,
- }
- }
- };
-
- return response_handler(cookie, header, (void*)&response);
-}
-
-/**
- * Callback for APPEND and APPENDQ
- * @param cookie the calling client
- * @param header the command
- * @param response_handler not used
- * @return the result of the operation
- */
-static protocol_binary_response_status
-append_command_handler(const void *cookie,
- protocol_binary_request_header *header,
- memcached_binary_protocol_raw_response_handler response_handler)
-{
- (void)response_handler;
- protocol_binary_response_status rval;
-
- struct memcached_binary_protocol_client_st *client= (void*)cookie;
- if (client->root->callback->interface.v1.append != NULL)
- {
- uint16_t keylen= ntohs(header->request.keylen);
- uint32_t datalen= ntohl(header->request.bodylen) - keylen;
- char *key= (void*)(header + 1);
- char *data= key + keylen;
- uint64_t cas= ntohll(header->request.cas);
- uint64_t result_cas;
-
- rval= client->root->callback->interface.v1.append(cookie, key, keylen,
- data, datalen, cas,
- &result_cas);
- if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS &&
- header->request.opcode == PROTOCOL_BINARY_CMD_APPEND)
- {
- /* Send a positive request */
- protocol_binary_response_no_extras response= {
- .message= {
- .header.response= {
- .magic= PROTOCOL_BINARY_RES,
- .opcode= PROTOCOL_BINARY_CMD_APPEND,
- .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
- .opaque= header->request.opaque,
- .cas= ntohll(result_cas),
- },
- }
- };
- rval= response_handler(cookie, header, (void*)&response);
- }
- }
- else
- {
- rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
- }
-
- return rval;
-}
-
-/**
- * Callback for PREPEND and PREPENDQ
- * @param cookie the calling client
- * @param header the command
- * @param response_handler not used
- * @return the result of the operation
- */
-static protocol_binary_response_status
-prepend_command_handler(const void *cookie,
- protocol_binary_request_header *header,
- memcached_binary_protocol_raw_response_handler response_handler)
-{
- (void)response_handler;
- protocol_binary_response_status rval;
-
- struct memcached_binary_protocol_client_st *client= (void*)cookie;
- if (client->root->callback->interface.v1.prepend != NULL)
- {
- uint16_t keylen= ntohs(header->request.keylen);
- uint32_t datalen= ntohl(header->request.bodylen) - keylen;
- char *key= (char*)(header + 1);
- char *data= key + keylen;
- uint64_t cas= ntohll(header->request.cas);
- uint64_t result_cas;
- rval= client->root->callback->interface.v1.prepend(cookie, key, keylen,
- data, datalen, cas,
- &result_cas);
- if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS &&
- header->request.opcode == PROTOCOL_BINARY_CMD_PREPEND)
- {
- /* Send a positive request */
- protocol_binary_response_no_extras response= {
- .message= {
- .header.response= {
- .magic= PROTOCOL_BINARY_RES,
- .opcode= PROTOCOL_BINARY_CMD_PREPEND,
- .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
- .opaque= header->request.opaque,
- .cas= ntohll(result_cas),
- },
- }
- };
- rval= response_handler(cookie, header, (void*)&response);
- }
- }
- else
- {
- rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
- }
-
- return rval;
-}
-
-/**
- * Callback for QUIT and QUITQ. Notify the client and shut down the connection
- * @param cookie the calling client
- * @param header the command
- * @param response_handler not used
- * @return the result of the operation
- */
-static protocol_binary_response_status
-quit_command_handler(const void *cookie,
- protocol_binary_request_header *header,
- memcached_binary_protocol_raw_response_handler response_handler)
-{
- struct memcached_binary_protocol_client_st *client= (void*)cookie;
- if (client->root->callback->interface.v1.quit != NULL)
- {
- client->root->callback->interface.v1.quit(cookie);
- }
-
- protocol_binary_response_no_extras response= {
- .message = {
- .header.response = {
- .magic= PROTOCOL_BINARY_RES,
- .opcode= PROTOCOL_BINARY_CMD_QUIT,
- .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
- .opaque= header->request.opaque
- }
- }
- };
-
- if (header->request.opcode == PROTOCOL_BINARY_CMD_QUIT)
- {
- response_handler(cookie, header, (void*)&response);
- }
-
- /* I need a better way to signal to close the connection */
- return PROTOCOL_BINARY_RESPONSE_EIO;
-}
-
-/**
- * Callback for REPLACE and REPLACEQ
- * @param cookie the calling client
- * @param header the command
- * @param response_handler not used
- * @return the result of the operation
- */
-static protocol_binary_response_status
-replace_command_handler(const void *cookie,
- protocol_binary_request_header *header,
- memcached_binary_protocol_raw_response_handler response_handler)
-{
- (void)response_handler;
- protocol_binary_response_status rval;
-
- struct memcached_binary_protocol_client_st *client= (void*)cookie;
- if (client->root->callback->interface.v1.replace != NULL)
- {
- uint16_t keylen= ntohs(header->request.keylen);
- uint32_t datalen= ntohl(header->request.bodylen) - keylen - 8;
- protocol_binary_request_replace *request= (void*)header;
- uint32_t flags= ntohl(request->message.body.flags);
- uint32_t timeout= ntohl(request->message.body.expiration);
- char *key= ((char*)header) + sizeof(*header) + 8;
- char *data= key + keylen;
- uint64_t cas= ntohll(header->request.cas);
- uint64_t result_cas;
-
- rval= client->root->callback->interface.v1.replace(cookie, key, keylen,
- data, datalen, flags,
- timeout, cas,
- &result_cas);
- if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS &&
- header->request.opcode == PROTOCOL_BINARY_CMD_REPLACE)
- {
- /* Send a positive request */
- protocol_binary_response_no_extras response= {
- .message= {
- .header.response= {
- .magic= PROTOCOL_BINARY_RES,
- .opcode= PROTOCOL_BINARY_CMD_REPLACE,
- .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
- .opaque= header->request.opaque,
- .cas= ntohll(result_cas),
- },
- }
- };
- rval= response_handler(cookie, header, (void*)&response);
- }
- }
- else
- {
- rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
- }
-
- return rval;
-}
-
-/**
- * Callback for SET and SETQ
- * @param cookie the calling client
- * @param header the command
- * @param response_handler not used
- * @return the result of the operation
- */
-static protocol_binary_response_status
-set_command_handler(const void *cookie,
- protocol_binary_request_header *header,
- memcached_binary_protocol_raw_response_handler response_handler)
-{
- (void)response_handler;
- protocol_binary_response_status rval;
-
- struct memcached_binary_protocol_client_st *client= (void*)cookie;
- if (client->root->callback->interface.v1.set != NULL)
- {
- uint16_t keylen= ntohs(header->request.keylen);
- uint32_t datalen= ntohl(header->request.bodylen) - keylen - 8;
- protocol_binary_request_replace *request= (void*)header;
- uint32_t flags= ntohl(request->message.body.flags);
- uint32_t timeout= ntohl(request->message.body.expiration);
- char *key= ((char*)header) + sizeof(*header) + 8;
- char *data= key + keylen;
- uint64_t cas= ntohll(header->request.cas);
- uint64_t result_cas;
-
-
- rval= client->root->callback->interface.v1.set(cookie, key, keylen,
- data, datalen, flags,
- timeout, cas, &result_cas);
- if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS &&
- header->request.opcode == PROTOCOL_BINARY_CMD_SET)
- {
- /* Send a positive request */
- protocol_binary_response_no_extras response= {
- .message= {
- .header.response= {
- .magic= PROTOCOL_BINARY_RES,
- .opcode= PROTOCOL_BINARY_CMD_SET,
- .status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
- .opaque= header->request.opaque,
- .cas= ntohll(result_cas),
- },
- }
- };
- rval= response_handler(cookie, header, (void*)&response);
- }
- }
- else
- {
- rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
- }
-
- return rval;
-}
-
-/**
- * Callback for STAT
- * @param cookie the calling client
- * @param header the command
- * @param response_handler not used
- * @return the result of the operation
- */
-static protocol_binary_response_status
-stat_command_handler(const void *cookie,
- protocol_binary_request_header *header,
- memcached_binary_protocol_raw_response_handler response_handler)
-{
- (void)response_handler;
- protocol_binary_response_status rval;
-
- struct memcached_binary_protocol_client_st *client= (void*)cookie;
- if (client->root->callback->interface.v1.stat != NULL)
- {
- uint16_t keylen= ntohs(header->request.keylen);
-
- rval= client->root->callback->interface.v1.stat(cookie,
- (void*)(header + 1),
- keylen,
- stat_response_handler);
- }
- else
- {
- rval= PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
- }
-
- return rval;
-}
-
-/**
- * Callback for VERSION
- * @param cookie the calling client
- * @param header the command
- * @param response_handler not used
- * @return the result of the operation
- */
-static protocol_binary_response_status
-version_command_handler(const void *cookie,
- protocol_binary_request_header *header,
- memcached_binary_protocol_raw_response_handler response_handler)
-{
- (void)response_handler;
- (void)header;
- protocol_binary_response_status rval;
-
- struct memcached_binary_protocol_client_st *client= (void*)cookie;
- if (client->root->callback->interface.v1.version != NULL)
- {
- rval= client->root->callback->interface.v1.version(cookie,
- version_response_handler);