Browse Source

Merge in fixes for http/code refactoring.

Brian Aker 13 years ago
parent
commit
6ac67fca69

+ 20 - 8
examples/reverse_worker.cc

@@ -55,11 +55,13 @@ struct reverse_worker_options_t
   bool chunk;
   bool status;
   bool unique;
+  bool verbose;
 
   reverse_worker_options_t():
     chunk(false),
     status(false),
-    unique(false)
+    unique(false),
+    verbose(true)
   { }
 };
 
@@ -71,10 +73,14 @@ static gearman_return_t reverse_worker(gearman_job_st *job, void *context)
 {
   reverse_worker_options_t options= *((reverse_worker_options_t *)context);
 
-
   const char *workload= (const char *)gearman_job_workload(job);
   const size_t workload_size= gearman_job_workload_size(job);
 
+  if (options.verbose)
+  {
+    std::cout << "Recieved " << workload_size << " bytes" << std::endl;
+  }
+
   char *result= (char *)malloc(workload_size);
   if (result == NULL)
   {
@@ -106,18 +112,23 @@ static gearman_return_t reverse_worker(gearman_job_st *job, void *context)
     }
   }
 
-  std::cout << "Job=" << gearman_job_handle(job);
+  if (options.verbose)
+  {
+    std::cout << "Job=" << gearman_job_handle(job);
+  }
 
-  if (options.unique)
+  if (options.unique and options.verbose)
   {
     std::cout << "Unique=" << gearman_job_unique(job);
   }
 
 
-  std::cout << "  Reversed=";
-  std::cout.write(workload, workload_size);
-
-  std::cout << std::endl;
+  if (options.verbose)
+  {
+    std::cout << "  Reversed=";
+    std::cout.write(workload, workload_size);
+    std::cout << std::endl;
+  }
 
   return GEARMAN_SUCCESS;
 }
@@ -142,6 +153,7 @@ int main(int args, char *argv[])
     ("chunk,d", boost::program_options::bool_switch(&options.chunk)->default_value(false), "Send result back in data chunks")
     ("status,s", boost::program_options::bool_switch(&options.status)->default_value(false), "Send status updates and sleep while running job")
     ("unique,u", boost::program_options::bool_switch(&options.unique)->default_value(false), "When grabbing jobs, grab the uniqie id")
+    ("verbose", boost::program_options::bool_switch(&options.verbose)->default_value(true), "Print to stdout information as job is processed.")
             ;
 
   boost::program_options::variables_map vm;

+ 2 - 1
libgearman-server/include.am

@@ -77,7 +77,8 @@ libgearman_server_libgearman_server_la_SOURCES+= \
 						 libgearman-server/timer.cc \
 						 libgearman-server/wakeup.cc \
 						 libgearman-server/worker.cc \
-						 libgearman/command.cc
+						 libgearman/command.cc \
+						 libgearman/strcommand.cc
 
 libgearman_server_libgearman_server_la_CFLAGS+= $(LIBEVENT_CPPFLAGS)
 libgearman_server_libgearman_server_la_CFLAGS+= $(PTHREAD_CFLAGS)

+ 5 - 3
libgearman-server/io.cc

@@ -450,7 +450,9 @@ gearmand_error_t gearman_io_send(gearman_server_con_st *con,
 
     /* Return here if we have no data to send. */
     if (packet->data_size == 0)
+    {
       break;
+    }
 
     /* If there is any room in the buffer, copy in data. */
     if (packet->data and (GEARMAN_SEND_BUFFER_SIZE - connection->send_buffer_size) > 0)
@@ -512,7 +514,7 @@ gearmand_error_t gearman_io_send(gearman_server_con_st *con,
     {
       _connection_close(connection);
       ret= GEARMAN_LOST_CONNECTION;
-      gearmand_gerror_warn("failure while flusing data, closing connection", ret);
+      gearmand_debug("closing connection after flush by request");
     }
     return ret;
   }
@@ -521,11 +523,11 @@ gearmand_error_t gearman_io_send(gearman_server_con_st *con,
   {
     connection->send_state= gearmand_io_st::GEARMAND_CON_SEND_UNIVERSAL_FLUSH;
     ret= _connection_flush(con);
-    if (ret == GEARMAN_SUCCESS && connection->options.close_after_flush)
+    if (ret == GEARMAN_SUCCESS and connection->options.close_after_flush)
     {
       _connection_close(connection);
       ret= GEARMAN_LOST_CONNECTION;
-      gearmand_gerror_warn("failure while flusing data, closing connection", ret);
+      gearmand_debug("closing connection after flush by request");
     }
     return ret;
   }

+ 0 - 1
libgearman-server/packet.cc

@@ -14,7 +14,6 @@
 #include <config.h>
 #include <libgearman-server/common.h>
 
-#define GEARMAN_CORE
 #include <libgearman/command.h>
 
 #include <libgearman-server/fifo.h>

+ 7 - 5
libgearman-server/plugins/protocol/http/include.am

@@ -1,6 +1,6 @@
 # vim:ft=automake
 # Gearman
-# Copyright (C) 2011 Data Differential, http://datadifferential.com/
+# Copyright (C) 2011-2012 Data Differential, http://datadifferential.com/
 # All rights reserved.
 #
 # Use and distribution licensed under the BSD license.  See
@@ -9,8 +9,10 @@
 # All paths should be given relative to the root
 #
 
-noinst_HEADERS+= \
-                 libgearman-server/plugins/protocol/http/protocol.h
+noinst_HEADERS+= libgearman-server/plugins/protocol/http/protocol.h
+noinst_HEADERS+= libgearman-server/plugins/protocol/http/method.h
+noinst_HEADERS+= libgearman-server/plugins/protocol/http/response_codes.h
 
-libgearman_server_libgearman_server_la_SOURCES+= \
-                                                 libgearman-server/plugins/protocol/http/protocol.cc
+libgearman_server_libgearman_server_la_SOURCES+= libgearman-server/plugins/protocol/http/protocol.cc
+libgearman_server_libgearman_server_la_SOURCES+= libgearman-server/plugins/protocol/http/response_codes.cc
+libgearman_server_libgearman_server_la_SOURCES+= libgearman-server/plugins/protocol/http/method.cc

+ 67 - 0
libgearman-server/plugins/protocol/http/method.cc

@@ -0,0 +1,67 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ *  Gearmand client and server library.
+ *
+ *  Copyright (C) 2012 Data Differential, http://datadifferential.com/
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <config.h>
+
+#include <libgearman-server/plugins/protocol/http/method.h>
+
+namespace gearmand {
+namespace protocol {
+namespace httpd {
+
+const char *str_method(method_t arg)
+{
+  switch (arg)
+  {
+  case HEAD: return "HEAD";
+  case GET: return "GET";
+  case PUT: return "PUT";
+  case POST: return "POST";
+  case TRACE: return "TRACE";
+
+  default:
+              break;
+  }
+
+  return "UNKNOWN";
+}
+
+} // namespace http
+} // namespace protocol
+} // namespace gearmand
+
+

+ 58 - 0
libgearman-server/plugins/protocol/http/method.h

@@ -0,0 +1,58 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ *  Gearmand client and server library.
+ *
+ *  Copyright (C) 2012 Data Differential, http://datadifferential.com/
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+namespace gearmand {
+namespace protocol {
+namespace httpd {
+
+enum method_t 
+{
+  HEAD,
+  GET,
+  PUT,
+  POST,
+  TRACE
+};
+
+const char *str_method(method_t);
+
+} // namespace http
+} // namespace protocol
+} // namespace gearmand
+

+ 95 - 46
libgearman-server/plugins/protocol/http/protocol.cc

@@ -44,6 +44,7 @@
 
 #include <config.h>
 #include <libgearman-server/common.h>
+#include <libgearman/strcommand.h>
 
 #include <cstdio>
 #include <cstdlib>
@@ -66,29 +67,31 @@
 /* Protocol callback functions. */
 
 static const char *_http_line(const void *data, size_t data_size,
-                              size_t *line_size, size_t *offset)
+                              size_t& line_size, size_t& offset)
 {
-  const char *start= (const char *)data + *offset;
-  const char *end;
+  const char *start= (const char *)data +offset;
 
-  end= (const char *)memchr(start, '\n', data_size - *offset);
+  const char *end= (const char *)memchr(start, '\n', data_size -offset);
   if (end == NULL)
+  {
     return NULL;
+  }
 
-  *offset+= (size_t)(end - start) + 1;
+  offset+= size_t(end - start) +1;
 
   if (end != start && *(end - 1) == '\r')
+  {
     end--;
+  }
 
-  *line_size= (size_t)(end - start);
+  line_size= size_t(end - start);
 
   return start;
 }
 
-static void _http_free(gearman_server_con_st *connection __attribute__ ((unused)),
-                       void *context)
+static void _http_free(gearman_server_con_st *, void *context)
 {
-  gearmand_info("HTTP connection disconnected");
+  gearmand_debug("HTTP connection disconnected");
   gearmand::protocol::HTTP *http= (gearmand::protocol::HTTP *)context;
   delete http;
 }
@@ -97,10 +100,6 @@ static size_t _http_pack(const gearmand_packet_st *packet, gearman_server_con_st
                          void *data, size_t data_size,
                          gearmand_error_t *ret_ptr)
 {
-  gearmand_info("Sending HTTP response");
-
-  size_t pack_size;
-
   gearmand::protocol::HTTP *http= (gearmand::protocol::HTTP *)gearmand_connection_protocol_context(connection);
 
   if (packet->command != GEARMAN_COMMAND_WORK_COMPLETE and
@@ -109,12 +108,28 @@ static size_t _http_pack(const gearmand_packet_st *packet, gearman_server_con_st
       (http->background() == false or
        packet->command != GEARMAN_COMMAND_JOB_CREATED))
   {
-    gearmand_info("Sending HTTP told to ignore packet");
+    gearmand_log_debug(GEARMAN_DEFAULT_LOG_PARAM,
+                       "Sending HTTP told to ignore packet: gearmand_command_t:%s", 
+                       gearman_strcommand(packet->command));
     *ret_ptr= GEARMAN_IGNORE_PACKET;
     return 0;
   }
 
-  if (http->method() == gearmand::protocol::HTTP::HEAD)
+  gearmand_log_debug(GEARMAN_DEFAULT_LOG_PARAM, "Sending HTTP response: Content-length:%"PRIu64" gearmand_command_t:%s response:%s", 
+                     uint64_t(packet->data_size), gearman_strcommand(packet->command),
+                     gearmand::protocol::httpd::response(http->response()));
+
+  size_t pack_size;
+  if (http->response() != gearmand::protocol::httpd::HTTP_OK)
+  {
+    pack_size= (size_t)snprintf((char *)data, data_size,
+                                "HTTP/1.0 %u %s\r\n"
+                                "Server: Gearman/" PACKAGE_VERSION "\r\n"
+                                "Content-Length: 0\r\n"
+                                "\r\n",
+                                int(http->response()), gearmand::protocol::httpd::response(http->response()));
+  }
+  else if (http->method() == gearmand::protocol::httpd::HEAD)
   {
     pack_size= (size_t)snprintf((char *)data, data_size,
                                 "HTTP/1.0 200 OK\r\n"
@@ -126,7 +141,7 @@ static size_t _http_pack(const gearmand_packet_st *packet, gearman_server_con_st
                                 (const char *)packet->arg[0],
                                 (uint64_t)packet->data_size);
   }
-  else if (http->method() == gearmand::protocol::HTTP::TRACE)
+  else if (http->method() == gearmand::protocol::httpd::TRACE)
   {
     pack_size= (size_t)snprintf((char *)data, data_size,
                                 "HTTP/1.0 200 OK\r\n"
@@ -140,34 +155,36 @@ static size_t _http_pack(const gearmand_packet_st *packet, gearman_server_con_st
     pack_size= (size_t)snprintf((char *)data, data_size,
                                 "HTTP/1.0 200 OK\r\n"
                                 "X-Gearman-Job-Handle: %.*s\r\n"
+                                "X-Gearman-Command: %s\r\n"
                                 "Content-Length: %"PRIu64"\r\n"
                                 "Server: Gearman/" PACKAGE_VERSION "\r\n"
                                 "\r\n",
-                                packet->command == GEARMAN_COMMAND_JOB_CREATED ?  (int)packet->arg_size[0] : (int)packet->arg_size[0] - 1,
-                                (const char *)packet->arg[0],
-                                (uint64_t)packet->data_size);
+                                packet->command == GEARMAN_COMMAND_JOB_CREATED ?  int(packet->arg_size[0]) : int(packet->arg_size[0] - 1), (const char *)packet->arg[0],
+                                gearman_strcommand(packet->command),
+                                uint64_t(packet->data_size));
   }
 
   if (pack_size > data_size)
   {
-    gearmand_info("Sending HTTP had to flush");
+    gearmand_debug("Sending HTTP had to flush");
     *ret_ptr= GEARMAN_FLUSH_DATA;
     return 0;
   }
 
-  if (! (http->keep_alive()))
+  if (http->keep_alive() == false)
   {
     gearman_io_set_option(&connection->con, GEARMAND_CON_CLOSE_AFTER_FLUSH, true);
   }
 
   *ret_ptr= GEARMAN_SUCCESS;
+
   return pack_size;
 }
+
 static size_t _http_unpack(gearmand_packet_st *packet, gearman_server_con_st *connection,
                            const void *data, size_t data_size,
                            gearmand_error_t *ret_ptr)
 {
-  gearmand::protocol::HTTP *http;
   const char *unique= "-";
   size_t unique_size= 2;
   gearmand_job_priority_t priority= GEARMAND_JOB_PRIORITY_NORMAL;
@@ -177,7 +194,7 @@ static size_t _http_unpack(gearmand_packet_st *packet, gearman_server_con_st *co
   /* Get the request line first. */
   size_t request_size;
   size_t offset= 0;
-  const char *request= _http_line(data, data_size, &request_size, &offset);
+  const char *request= _http_line(data, data_size, request_size, offset);
   if (request == NULL or request_size == 0)
   {
     gearmand_log_info(GEARMAN_DEFAULT_LOG_PARAM, "Zero length request made");
@@ -185,7 +202,7 @@ static size_t _http_unpack(gearmand_packet_st *packet, gearman_server_con_st *co
     return offset;
   }
 
-  http= (gearmand::protocol::HTTP *)gearmand_connection_protocol_context(connection);
+  gearmand::protocol::HTTP *http= (gearmand::protocol::HTTP *)gearmand_connection_protocol_context(connection);
   http->reset();
 
   /* Parse out the method, URI, and HTTP version from the request line. */
@@ -194,7 +211,8 @@ static size_t _http_unpack(gearmand_packet_st *packet, gearman_server_con_st *co
   if (uri == NULL)
   {
     gearmand_log_error(GEARMAN_DEFAULT_LOG_PARAM, "bad request line: %.*s", (uint32_t)request_size, request);
-    *ret_ptr= GEARMAN_INVALID_PACKET;
+    http->set_response(gearmand::protocol::httpd::HTTP_NOT_FOUND);
+    *ret_ptr= GEARMAN_SUCCESS;
     return 0;
   }
 
@@ -202,40 +220,47 @@ static size_t _http_unpack(gearmand_packet_st *packet, gearman_server_con_st *co
 
   if (method_size == 3 and strncmp(method, "GET", 3) == 0)
   {
-    http->set_method(gearmand::protocol::HTTP::GET);
+    http->set_method(gearmand::protocol::httpd::GET);
   }
   else if (method_size == 3 and strncmp(method, "PUT", 3) == 0)
   {
-    http->set_method(gearmand::protocol::HTTP::PUT);
+    http->set_method(gearmand::protocol::httpd::PUT);
   }
   else if (method_size == 4 and strncmp(method, "POST", 4) == 0)
   {
-    http->set_method(gearmand::protocol::HTTP::POST);
+    http->set_method(gearmand::protocol::httpd::POST);
   }
   else if (method_size == 4 and strncmp(method, "HEAD", 4) == 0)
   {
-    http->set_method(gearmand::protocol::HTTP::HEAD);
+    http->set_method(gearmand::protocol::httpd::HEAD);
   }
   else if (method_size == 5 and strncmp(method, "TRACE", 5) == 0)
   {
-    http->set_method(gearmand::protocol::HTTP::TRACE);
+    http->set_method(gearmand::protocol::httpd::TRACE);
   }
   else
   {
     gearmand_log_error(GEARMAN_DEFAULT_LOG_PARAM, "bad method: %.*s", (uint32_t)method_size, method);
-    *ret_ptr= GEARMAN_INVALID_PACKET;
+    http->set_response(gearmand::protocol::httpd::HTTP_METHOD_NOT_ALLOWED);
+    *ret_ptr= GEARMAN_SUCCESS;
     return 0;
   }
 
+  gearmand_log_debug(GEARMAN_DEFAULT_LOG_PARAM, "METHOD: %s", str_method(http->method()));
+
+  gearmand_log_debug(GEARMAN_DEFAULT_LOG_PARAM, "URI: %s", uri);
+
   while (*uri == ' ')
   {
     uri++;
   }
+  gearmand_log_debug(GEARMAN_DEFAULT_LOG_PARAM, "URI: %s", uri);
 
   while (*uri == '/')
   {
     uri++;
   }
+  gearmand_log_debug(GEARMAN_DEFAULT_LOG_PARAM, "URI: %s", uri);
 
   const char *version= (const char *)memchr(uri, ' ', request_size - (size_t)(uri - request));
   if (version == NULL)
@@ -249,18 +274,17 @@ static size_t _http_unpack(gearmand_packet_st *packet, gearman_server_con_st *co
   ptrdiff_t uri_size= version -uri;
   switch (http->method())
   {
-  case gearmand::protocol::HTTP::POST:
-  case gearmand::protocol::HTTP::PUT:
-  case gearmand::protocol::HTTP::GET:
+  case gearmand::protocol::httpd::POST:
+  case gearmand::protocol::httpd::PUT:
+  case gearmand::protocol::httpd::GET:
     if (uri_size == 0)
     {
       gearmand_error("must give function name in URI");
-      *ret_ptr= GEARMAN_INVALID_PACKET;
-      return 0;
+      http->set_response(gearmand::protocol::httpd::HTTP_NOT_FOUND);
     }
 
-  case gearmand::protocol::HTTP::TRACE:
-  case gearmand::protocol::HTTP::HEAD:
+  case gearmand::protocol::httpd::TRACE:
+  case gearmand::protocol::httpd::HEAD:
     break;
   }
 
@@ -270,11 +294,14 @@ static size_t _http_unpack(gearmand_packet_st *packet, gearman_server_con_st *co
   }
 
   size_t version_size= request_size - (size_t)(version - request);
-  if (version_size == 8 && !strncasecmp(version, "HTTP/1.1", 8))
+  if (false and version_size == 8 and strncasecmp(version, "HTTP/1.1", 8) == 0)
   {
     http->set_keep_alive(true);
   }
-  else if (version_size != 8 || strncasecmp(version, "HTTP/1.0", 8))
+  else if (version_size == 8 and strncasecmp(version, "HTTP/1.1", 8) == 0)
+  {
+  }
+  else
   {
     gearmand_log_error(GEARMAN_DEFAULT_LOG_PARAM, "bad version: %.*s", (uint32_t)version_size, version);
     *ret_ptr= GEARMAN_INVALID_PACKET;
@@ -284,7 +311,7 @@ static size_t _http_unpack(gearmand_packet_st *packet, gearman_server_con_st *co
   /* Loop through all the headers looking for ones of interest. */
   const char *header;
   size_t header_size;
-  while ((header= _http_line(data, data_size, &header_size, &offset)) != NULL)
+  while ((header= _http_line(data, data_size, header_size, offset)) != NULL)
   {
     if (header_size == 0)
     {
@@ -330,7 +357,7 @@ static size_t _http_unpack(gearmand_packet_st *packet, gearman_server_con_st *co
   }
 
   /* Make sure we received the end of headers. */
-  if (header == NULL)
+  if (header == NULL and http->response() == gearmand::protocol::httpd::HTTP_OK)
   {
     gearmand_log_info(GEARMAN_DEFAULT_LOG_PARAM, "No headers were found");
     *ret_ptr= GEARMAN_IO_WAIT;
@@ -340,7 +367,20 @@ static size_t _http_unpack(gearmand_packet_st *packet, gearman_server_con_st *co
   /* Request and all headers complete, build a packet based on HTTP request. */
   packet->magic= GEARMAN_MAGIC_REQUEST;
 
-  if (http->method() == gearmand::protocol::HTTP::TRACE)
+  if (http->response() != gearmand::protocol::httpd::HTTP_OK)
+  {
+    packet->command= GEARMAN_COMMAND_ECHO_REQ;
+
+    *ret_ptr= gearmand_packet_pack_header(packet);
+    if (*ret_ptr != GEARMAN_SUCCESS)
+    {
+      return 0;
+    }
+
+    packet->data_size= 0;
+    packet->data= NULL;
+  }
+  else if (http->method() == gearmand::protocol::httpd::TRACE)
   {
     packet->command= GEARMAN_COMMAND_ECHO_REQ;
 
@@ -353,7 +393,7 @@ static size_t _http_unpack(gearmand_packet_st *packet, gearman_server_con_st *co
     packet->data_size= data_size;
     packet->data= (const char*)data;
   }
-  else if (http->method() == gearmand::protocol::HTTP::HEAD and uri_size == 0)
+  else if (http->method() == gearmand::protocol::httpd::HEAD and uri_size == 0)
   {
     packet->command= GEARMAN_COMMAND_ECHO_REQ;
 
@@ -435,9 +475,10 @@ namespace protocol {
 
 HTTP::HTTP() :
   Plugin("HTTP"),
-  _method(gearmand::protocol::HTTP::TRACE),
+  _method(gearmand::protocol::httpd::TRACE),
   _background(false),
-  _keep_alive(false)
+  _keep_alive(false),
+  _http_response(gearmand::protocol::httpd::HTTP_OK)
 {
   command_line_options().add_options()
     ("http-port", boost::program_options::value(&global_port)->default_value(GEARMAN_PROTOCOL_HTTP_DEFAULT_PORT), "Port to listen on.");
@@ -453,6 +494,14 @@ gearmand_error_t HTTP::start(gearmand_st *gearmand)
   return gearmand_port_add(gearmand, global_port.c_str(), _http_con_add);
 }
 
+void HTTP::reset()
+{
+  _background= false;
+  _keep_alive= false;
+  _method= httpd::TRACE;
+  _http_response= gearmand::protocol::httpd::HTTP_OK;
+}
+
 } // namespace protocol
 } // namespace gearmand
 

+ 17 - 18
libgearman-server/plugins/protocol/http/protocol.h

@@ -14,6 +14,8 @@
 #pragma once
 
 #include <libgearman-server/plugins/base.h>
+#include <libgearman-server/plugins/protocol/http/method.h>
+#include <libgearman-server/plugins/protocol/http/response_codes.h>
 
 struct gearmand_st;
 
@@ -21,21 +23,13 @@ namespace gearmand {
 namespace protocol {
 
 class HTTP : public gearmand::Plugin {
-public:
-  enum method_t 
-  {
-    HEAD,
-    GET,
-    PUT,
-    POST,
-    TRACE,
-  };
 
 private:
-  HTTP::method_t _method;
+  httpd::method_t _method;
   bool _background;
   bool _keep_alive;
   std::string global_port;
+  httpd::response_t _http_response;
 
 public:
 
@@ -64,22 +58,27 @@ public:
     _keep_alive= arg;
   }
 
-  HTTP::method_t method()
+  void set_response(httpd::response_t arg)
   {
-    return _method;
+    _http_response= arg;
   }
 
-  void set_method(HTTP::method_t arg)
+  httpd::response_t response() const
   {
-    _method= arg;
+    return _http_response;
+  }
+
+  httpd::method_t method()
+  {
+    return _method;
   }
 
-  void reset()
+  void set_method(httpd::method_t arg)
   {
-    _background= false;
-    _keep_alive= false;
-    _method= HTTP::TRACE;
+    _method= arg;
   }
+
+  void reset();
 };
 
 } // namespace protocol

+ 109 - 0
libgearman-server/plugins/protocol/http/response_codes.cc

@@ -0,0 +1,109 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ *  Gearmand client and server library.
+ *
+ *  Copyright (C) 2012 Data Differential, http://datadifferential.com/
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <config.h>
+#include <libgearman-server/plugins/protocol/http/response_codes.h>
+
+namespace gearmand {
+namespace protocol {
+namespace httpd {
+
+const char *response(response_t arg)
+{
+  switch (arg)
+  {
+  case HTTP_CONTINUE: return "CONTINUE";
+  case HTTP_SWITCHING_PROTOCOLS: return "SWITCHING_PROTOCOLS";
+  case HTTP_PROCESSING: return "PROCESSING";
+  case HTTP_OK: return "OK";
+  case HTTP_CREATED: return "CREATED";
+  case HTTP_ACCEPTED: return "ACCEPTED";
+  case HTTP_NON_AUTHORITATIVE: return "NON_AUTHORITATIVE";
+  case HTTP_NO_CONTENT: return "NO_CONTENT";
+  case HTTP_RESET_CONTENT: return "RESET_CONTENT";
+  case HTTP_PARTIAL_CONTENT: return "PARTIAL_CONTENT";
+  case HTTP_MULTI_STATUS: return "MULTI_STATUS";
+  case HTTP_MULTIPLE_CHOICES: return "MULTIPLE_CHOICES";
+  case HTTP_MOVED_PERMANENTLY: return "MOVED_PERMANENTLY";
+  case HTTP_MOVED_TEMPORARILY: return "MOVED_TEMPORARILY";
+  case HTTP_SEE_OTHER: return "SEE_OTHER";
+  case HTTP_NOT_MODIFIED: return "NOT_MODIFIED";
+  case HTTP_USE_PROXY: return "USE_PROXY";
+  case HTTP_TEMPORARY_REDIRECT: return "TEMPORARY_REDIRECT";
+  case HTTP_BAD_REQUEST: return "BAD_REQUEST";
+  case HTTP_UNAUTHORIZED: return "UNAUTHORIZED";
+  case HTTP_PAYMENT_REQUIRED: return "PAYMENT_REQUIRED";
+  case HTTP_FORBIDDEN: return "FORBIDDEN";
+  case HTTP_NOT_FOUND: return "NOT_FOUND";
+  case HTTP_METHOD_NOT_ALLOWED: return "METHOD_NOT_ALLOWED";
+  case HTTP_NOT_ACCEPTABLE: return "NOT_ACCEPTABLE";
+  case HTTP_PROXY_AUTHENTICATION_REQUIRED: return "PROXY_AUTHENTICATION_REQUIRED";
+  case HTTP_REQUEST_TIME_OUT: return "REQUEST_TIME_OUT";
+  case HTTP_CONFLICT: return "CONFLICT";
+  case HTTP_GONE: return "GONE";
+  case HTTP_LENGTH_REQUIRED: return "LENGTH_REQUIRED";
+  case HTTP_PRECONDITION_FAILED: return "PRECONDITION_FAILED";
+  case HTTP_REQUEST_ENTITY_TOO_LARGE: return "REQUEST_ENTITY_TOO_LARGE";
+  case HTTP_REQUEST_URI_TOO_LARGE: return "REQUEST_URI_TOO_LARGE";
+  case HTTP_UNSUPPORTED_MEDIA_TYPE: return "UNSUPPORTED_MEDIA_TYPE";
+  case HTTP_RANGE_NOT_SATISFIABLE: return "RANGE_NOT_SATISFIABLE";
+  case HTTP_EXPECTATION_FAILED: return "EXPECTATION_FAILED";
+  case HTTP_UNPROCESSABLE_ENTITY: return "UNPROCESSABLE_ENTITY";
+  case HTTP_LOCKED: return "LOCKED";
+  case HTTP_FAILED_DEPENDENCY: return "FAILED_DEPENDENCY";
+  case HTTP_UPGRADE_REQUIRED: return "UPGRADE_REQUIRED";
+  case HTTP_NOT_IMPLEMENTED: return "NOT_IMPLEMENTED";
+  case HTTP_BAD_GATEWAY: return "BAD_GATEWAY";
+  case HTTP_SERVICE_UNAVAILABLE: return "SERVICE_UNAVAILABLE";
+  case HTTP_GATEWAY_TIME_OUT: return "GATEWAY_TIME_OUT";
+  case HTTP_VERSION_NOT_SUPPORTED: return "VERSION_NOT_SUPPORTED";
+  case HTTP_VARIANT_ALSO_VARIES: return "VARIANT_ALSO_VARIES";
+  case HTTP_INSUFFICIENT_STORAGE: return "INSUFFICIENT_STORAGE";
+  case HTTP_NOT_EXTENDED: return "NOT_EXTENDED";
+
+  case HTTP_INTERNAL_SERVER_ERROR:
+  default:
+                          break;
+  }
+
+  return "INTERNAL_SERVER_ERROR";
+}
+
+} // namespace http
+} // namespace protocol
+} // namespace gearmand
+

Some files were not shown because too many files changed in this diff