[Groonga-commit] groonga/groonga at 3392f71 [master] http: support "Except: 100-Continue"

Back to archive index

Kouhei Sutou null+****@clear*****
Sat Jun 7 14:42:26 JST 2014


Kouhei Sutou	2014-06-07 14:42:26 +0900 (Sat, 07 Jun 2014)

  New Revision: 3392f71215d5bc23e1e0e050302c21e53dc347a1
  https://github.com/groonga/groonga/commit/3392f71215d5bc23e1e0e050302c21e53dc347a1

  Message:
    http: support "Except: 100-Continue"

  Modified files:
    src/groonga.c

  Modified: src/groonga.c (+54 -42)
===================================================================
--- src/groonga.c    2014-06-06 10:29:06 +0900 (631824f)
+++ src/groonga.c    2014-06-07 14:42:26 +0900 (bca1473)
@@ -755,6 +755,14 @@ do_htreq_get(grn_ctx *ctx, grn_msg *msg)
   grn_ctx_send(ctx, path, pathe - path, 0);
 }
 
+typedef struct {
+  const char *path_start;
+  int path_length;
+  int content_length;
+  grn_bool have_100_continue;
+  const char *body_start;
+} h_post_header;
+
 #define STRING_EQUAL_CI(string, string_length, constant_string)\
   (string_length == strlen(constant_string) &&\
    strncasecmp(string, constant_string, string_length) == 0)
@@ -763,8 +771,7 @@ static const char *
 do_htreq_post_parse_header_request_line(grn_ctx *ctx,
                                         const char *start,
                                         const char *end,
-                                        const char **path_start,
-                                        int *path_length)
+                                        h_post_header *header)
 {
   const char *current;
 
@@ -791,19 +798,19 @@ do_htreq_post_parse_header_request_line(grn_ctx *ctx,
   }
 
   {
-    *path_start = current;
-    *path_length = -1;
+    header->path_start = current;
+    header->path_length = -1;
     for (; current < end; current++) {
       if (current[0] == '\n') {
         return NULL;
       }
       if (current[0] == ' ') {
-        *path_length = current - *path_start;
+        header->path_length = current - header->path_start;
         current++;
         break;
       }
     }
-    if (*path_length == -1) {
+    if (header->path_length == -1) {
       return NULL;
     }
   }
@@ -838,7 +845,7 @@ static const char *
 do_htreq_post_parse_header_values(grn_ctx *ctx,
                                   const char *start,
                                   const char *end,
-                                  int *content_length)
+                                  h_post_header *header)
 {
   const char *current;
   const char *name = start;
@@ -866,10 +873,14 @@ do_htreq_post_parse_header_values(grn_ctx *ctx,
         }
         if (STRING_EQUAL_CI(name, name_length, "Content-Length")) {
           const char *rest;
-          *content_length = grn_atoi(value, value + value_length, &rest);
+          header->content_length = grn_atoi(value, value + value_length, &rest);
           if (rest != value + value_length) {
             /* Invalid Content-Length value. TODO: report error. */
-            *content_length = -1;
+            header->content_length = -1;
+          }
+        } else if (STRING_EQUAL_CI(name, name_length, "Expect")) {
+          if (STRING_EQUAL_CI(value, value_length, "100-continue")) {
+            header->have_100_continue = GRN_TRUE;
           }
         }
       }
@@ -896,81 +907,82 @@ static grn_bool
 do_htreq_post_parse_header(grn_ctx *ctx,
                            const char *start,
                            const char *end,
-                           const char **path_start,
-                           int *path_length,
-                           int *content_length,
-                           const char **body_start)
+                           h_post_header *header)
 {
   const char *current;
 
-  current = do_htreq_post_parse_header_request_line(ctx,
-                                                    start,
-                                                    end,
-                                                    path_start,
-                                                    path_length);
+  current = do_htreq_post_parse_header_request_line(ctx, start, end, header);
   if (!current) {
     return GRN_FALSE;
   }
-  current = do_htreq_post_parse_header_values(ctx,
-                                              current,
-                                              end,
-                                              content_length);
+  current = do_htreq_post_parse_header_values(ctx, current, end, header);
   if (!current) {
     return GRN_FALSE;
   }
 
-  if (*content_length == -1) {
+  if (!header->have_100_continue && current == end) {
     return GRN_FALSE;
   }
 
-  if (current >= end) {
-    return GRN_FALSE;
+  if (current == end) {
+    header->body_start = NULL;
+  } else {
+    header->body_start = current;
   }
 
-  *body_start = current;
-
   return GRN_TRUE;
 }
 
 static void
 do_htreq_post(grn_ctx *ctx, grn_msg *msg)
 {
+  grn_sock fd = msg->u.fd;
   const char *end;
-  const char *path_start = NULL;
-  int path_length = -1;
-  int content_length = -1;
-  const char *body_start = NULL;
+  h_post_header header;
+
+  header.path_start = NULL;
+  header.path_length = -1;
+  header.content_length = -1;
+  header.body_start = NULL;
+  header.have_100_continue = GRN_FALSE;
 
   end = GRN_BULK_CURR((grn_obj *)msg);
   if (!do_htreq_post_parse_header(ctx,
                                   GRN_BULK_HEAD((grn_obj *)msg),
                                   end,
-                                  &path_start,
-                                  &path_length,
-                                  &content_length,
-                                  &body_start)) {
+                                  &header)) {
     return;
   }
 
-  grn_ctx_send(ctx, path_start, path_length, GRN_CTX_QUIET);
+  if (header.have_100_continue) {
+    const char *continue_message = "HTTP/1.1 100 Continue\r\n";
+    ssize_t send_size;
+    int send_flags = MSG_NOSIGNAL;
+    send_size = send(fd, continue_message, strlen(continue_message), send_flags);
+    if (send_size == -1) {
+      SERR("send");
+      return;
+    }
+  }
+
+  grn_ctx_send(ctx, header.path_start, header.path_length, GRN_CTX_QUIET);
 
   {
-    grn_sock fd = msg->u.fd;
     grn_obj line_buffer;
     int read_content_length = 0;
 
     GRN_TEXT_INIT(&line_buffer, 0);
-    while (read_content_length < content_length) {
+    while (read_content_length < header.content_length) {
 #define POST_BUFFER_SIZE 8192
       ssize_t read_length;
       grn_rc rc;
       char buffer[POST_BUFFER_SIZE];
       const char *buffer_start, *buffer_current, *buffer_end;
 
-      if (body_start) {
-        buffer_start = body_start;
+      if (header.body_start) {
+        buffer_start = header.body_start;
         buffer_end = end;
-        body_start = NULL;
+        header.body_start = NULL;
       } else {
         read_length = read(fd, buffer, POST_BUFFER_SIZE);
         if (read_length == 0) {
@@ -997,7 +1009,7 @@ do_htreq_post(grn_ctx *ctx, grn_msg *msg)
                      buffer_current - buffer_start);
         {
           int flags = 0;
-          if (!(read_content_length == content_length &&
+          if (!(read_content_length == header.content_length &&
                 buffer_current + 1 == buffer_end)) {
             flags |= GRN_CTX_QUIET;
           }
-------------- next part --------------
HTML����������������������������...
下载 



More information about the Groonga-commit mailing list
Back to archive index