move repository from m6w6 to awesomized
[awesomized/libmemcached] / src / libmemcachedprotocol / binary_handler.c
index 51fa60be1fb671c512c449b769f57709ea6e6233..84151cfed4f23fa02f686ba483507fe8a66407c6 100644 (file)
@@ -9,11 +9,12 @@
     | the terms online at: https://opensource.org/licenses/BSD-3-Clause  |
     +--------------------------------------------------------------------+
     | Copyright (c) 2006-2014 Brian Aker   https://datadifferential.com/ |
-    | Copyright (c) 2020 Michael Wallner   <mike@php.net>                |
+    | Copyright (c) 2020-2021 Michael Wallner        https://awesome.co/ |
     +--------------------------------------------------------------------+
 */
 
 #include "libmemcachedprotocol/common.h"
+#include "p9y/socket.hpp"
 
 #include <stdlib.h>
 #include <sys/types.h>
@@ -43,7 +44,7 @@ binary_raw_response_handler(const void *cookie, protocol_binary_request_header *
                             protocol_binary_response_header *response) {
   memcached_protocol_client_st *client = (void *) cookie;
 
-  if (client->root->pedantic
+  if (response && client->root->pedantic
       && !memcached_binary_protocol_pedantic_check_response(request, response)) {
     return PROTOCOL_BINARY_RESPONSE_EINVAL;
   }
@@ -52,6 +53,10 @@ binary_raw_response_handler(const void *cookie, protocol_binary_request_header *
     return PROTOCOL_BINARY_RESPONSE_EINTERNAL;
   }
 
+  if (!response) {
+    return PROTOCOL_BINARY_RESPONSE_SUCCESS;
+  }
+
   size_t len = sizeof(protocol_binary_response_header) + htonl(response->response.bodylen);
   size_t offset = 0;
   char *ptr = (void *) response;
@@ -265,7 +270,8 @@ static void print_cmd(protocol_binary_command cmd) {
   case PROTOCOL_BINARY_CMD_SCRUB:
     fprintf(stderr, "%s:%d PROTOCOL_BINARY_CMD_SCRUB\n", __FILE__, __LINE__);
     return;
-  default: abort();
+  default:
+    abort();
   }
 }
 
@@ -404,7 +410,7 @@ add_command_handler(const void *cookie, protocol_binary_request_header *header,
   protocol_binary_response_status rval;
 
   memcached_protocol_client_st *client = (void *) cookie;
-  if (client->root->callback->interface.v1.add != NULL) {
+  if (client->root->callback->interface.v1.add) {
     uint16_t keylen = ntohs(header->request.keylen);
     uint32_t datalen = ntohl(header->request.bodylen) - keylen - 8;
     protocol_binary_request_add *request = (void *) header;
@@ -449,7 +455,7 @@ decrement_command_handler(const void *cookie, protocol_binary_request_header *he
   protocol_binary_response_status rval;
 
   memcached_protocol_client_st *client = (void *) cookie;
-  if (client->root->callback->interface.v1.decrement != NULL) {
+  if (client->root->callback->interface.v1.decrement) {
     uint16_t keylen = ntohs(header->request.keylen);
     protocol_binary_request_decr *request = (void *) header;
     uint64_t init = memcached_ntohll(request->message.body.initial);
@@ -496,7 +502,7 @@ delete_command_handler(const void *cookie, protocol_binary_request_header *heade
   protocol_binary_response_status rval;
 
   memcached_protocol_client_st *client = (void *) cookie;
-  if (client->root->callback->interface.v1.delete_object != NULL) {
+  if (client->root->callback->interface.v1.delete_object) {
     uint16_t keylen = ntohs(header->request.keylen);
     void *key = (header + 1);
     uint64_t cas = memcached_ntohll(header->request.cas);
@@ -535,7 +541,7 @@ flush_command_handler(const void *cookie, protocol_binary_request_header *header
   protocol_binary_response_status rval;
 
   memcached_protocol_client_st *client = (void *) cookie;
-  if (client->root->callback->interface.v1.flush_object != NULL) {
+  if (client->root->callback->interface.v1.flush_object) {
     protocol_binary_request_flush *flush_object = (void *) header;
     uint32_t timeout = 0;
     if (htonl(header->request.bodylen) == 4) {
@@ -576,7 +582,7 @@ get_command_handler(const void *cookie, protocol_binary_request_header *header,
   protocol_binary_response_status rval;
 
   memcached_protocol_client_st *client = (void *) cookie;
-  if (client->root->callback->interface.v1.get != NULL) {
+  if (client->root->callback->interface.v1.get) {
     uint16_t keylen = ntohs(header->request.keylen);
     void *key = (header + 1);
     rval = client->root->callback->interface.v1.get(cookie, key, keylen, get_response_handler);
@@ -609,7 +615,7 @@ increment_command_handler(const void *cookie, protocol_binary_request_header *he
   protocol_binary_response_status rval;
 
   memcached_protocol_client_st *client = (void *) cookie;
-  if (client->root->callback->interface.v1.increment != NULL) {
+  if (client->root->callback->interface.v1.increment) {
     uint16_t keylen = ntohs(header->request.keylen);
     protocol_binary_request_incr *request = (void *) header;
     uint64_t init = memcached_ntohll(request->message.body.initial);
@@ -656,7 +662,7 @@ static protocol_binary_response_status
 noop_command_handler(const void *cookie, protocol_binary_request_header *header,
                      memcached_binary_protocol_raw_response_handler response_handler) {
   memcached_protocol_client_st *client = (void *) cookie;
-  if (client->root->callback->interface.v1.noop != NULL) {
+  if (client->root->callback->interface.v1.noop) {
     client->root->callback->interface.v1.noop(cookie);
   }
 
@@ -685,7 +691,7 @@ append_command_handler(const void *cookie, protocol_binary_request_header *heade
   protocol_binary_response_status rval;
 
   memcached_protocol_client_st *client = (void *) cookie;
-  if (client->root->callback->interface.v1.append != NULL) {
+  if (client->root->callback->interface.v1.append) {
     uint16_t keylen = ntohs(header->request.keylen);
     uint32_t datalen = ntohl(header->request.bodylen) - keylen;
     char *key = (void *) (header + 1);
@@ -733,7 +739,7 @@ prepend_command_handler(const void *cookie, protocol_binary_request_header *head
   protocol_binary_response_status rval;
 
   memcached_protocol_client_st *client = (void *) cookie;
-  if (client->root->callback->interface.v1.prepend != NULL) {
+  if (client->root->callback->interface.v1.prepend) {
     uint16_t keylen = ntohs(header->request.keylen);
     uint32_t datalen = ntohl(header->request.bodylen) - keylen;
     char *key = (char *) (header + 1);
@@ -777,7 +783,7 @@ static protocol_binary_response_status
 quit_command_handler(const void *cookie, protocol_binary_request_header *header,
                      memcached_binary_protocol_raw_response_handler response_handler) {
   memcached_protocol_client_st *client = (void *) cookie;
-  if (client->root->callback->interface.v1.quit != NULL) {
+  if (client->root->callback->interface.v1.quit) {
     client->root->callback->interface.v1.quit(cookie);
   }
 
@@ -809,7 +815,7 @@ replace_command_handler(const void *cookie, protocol_binary_request_header *head
   protocol_binary_response_status rval;
 
   memcached_protocol_client_st *client = (void *) cookie;
-  if (client->root->callback->interface.v1.replace != NULL) {
+  if (client->root->callback->interface.v1.replace) {
     uint16_t keylen = ntohs(header->request.keylen);
     uint32_t datalen = ntohl(header->request.bodylen) - keylen - 8;
     protocol_binary_request_replace *request = (void *) header;
@@ -860,7 +866,7 @@ set_command_handler(const void *cookie, protocol_binary_request_header *header,
   protocol_binary_response_status rval;
 
   memcached_protocol_client_st *client = (void *) cookie;
-  if (client->root->callback->interface.v1.set != NULL) {
+  if (client->root->callback->interface.v1.set) {
     uint16_t keylen = ntohs(header->request.keylen);
     uint32_t datalen = ntohl(header->request.bodylen) - keylen - 8;
     protocol_binary_request_replace *request = (void *) header;
@@ -910,11 +916,25 @@ stat_command_handler(const void *cookie, protocol_binary_request_header *header,
   protocol_binary_response_status rval;
 
   memcached_protocol_client_st *client = (void *) cookie;
-  if (client->root->callback->interface.v1.stat != NULL) {
+  if (client->root->callback->interface.v1.stat) {
     uint16_t keylen = ntohs(header->request.keylen);
 
     rval = client->root->callback->interface.v1.stat(cookie, (void *) (header + 1), keylen,
                                                      stat_response_handler);
+    if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS) {
+      /* END message */
+      protocol_binary_response_no_extras response = {
+          .message = {
+              .header.response =
+                  {
+                      .magic = PROTOCOL_BINARY_RES,
+                      .opcode = PROTOCOL_BINARY_CMD_STAT,
+                      .status = htons(PROTOCOL_BINARY_RESPONSE_SUCCESS),
+                      .opaque = header->request.opaque,
+                  },
+          }};
+      rval = response_handler(cookie, header, &response);
+    }
   } else {
     rval = PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
   }
@@ -937,8 +957,11 @@ version_command_handler(const void *cookie, protocol_binary_request_header *head
   protocol_binary_response_status rval;
 
   memcached_protocol_client_st *client = (void *) cookie;
-  if (client->root->callback->interface.v1.version != NULL) {
+  if (client->root->callback->interface.v1.version) {
     rval = client->root->callback->interface.v1.version(cookie, version_response_handler);
+    if (rval == PROTOCOL_BINARY_RESPONSE_SUCCESS) {
+      rval = response_handler(cookie, header, NULL);
+    }
   } else {
     rval = PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
   }
@@ -995,7 +1018,7 @@ static protocol_binary_response_status execute_command(memcached_protocol_client
   }
 
   /* we got all data available, execute the callback! */
-  if (client->root->callback->pre_execute != NULL) {
+  if (client->root->callback->pre_execute) {
     client->root->callback->pre_execute(client, header);
   }
 
@@ -1008,14 +1031,14 @@ static protocol_binary_response_status execute_command(memcached_protocol_client
 
   switch (client->root->callback->interface_version) {
   case 0:
-    if (client->root->callback->interface.v0.comcode[cc] != NULL) {
+    if (client->root->callback->interface.v0.comcode[cc]) {
       rval = client->root->callback->interface.v0.comcode[cc](client, header,
                                                               binary_raw_response_handler);
     }
     break;
 
   case 1:
-    if (comcode_v0_v1_remap[cc] != NULL) {
+    if (comcode_v0_v1_remap[cc]) {
       rval = comcode_v0_v1_remap[cc](client, header, binary_raw_response_handler);
     }
     break;
@@ -1028,7 +1051,7 @@ static protocol_binary_response_status execute_command(memcached_protocol_client
     abort();
   }
 
-  if (rval == PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND && client->root->callback->unknown != NULL) {
+  if (rval == PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND && client->root->callback->unknown) {
     rval = client->root->callback->unknown(client, header, binary_raw_response_handler);
   }
 
@@ -1047,7 +1070,7 @@ static protocol_binary_response_status execute_command(memcached_protocol_client
     rval = binary_raw_response_handler(client, header, (void *) &response);
   }
 
-  if (client->root->callback->post_execute != NULL) {
+  if (client->root->callback->post_execute) {
     client->root->callback->post_execute(client, header);
   }