[Groonga-commit] groonga/groonga [master] Stop calling grn_expr_exec() from groonga.c

Zurück zum Archiv-Index

null+****@clear***** null+****@clear*****
2010年 6月 13日 (日) 16:47:55 JST


Daijiro MORI	2010-06-13 07:47:55 +0000 (Sun, 13 Jun 2010)

  New Revision: a8716090193b77ecd15922bd8379e7bfca6b20c1

  Log:
    Stop calling grn_expr_exec() from groonga.c

  Modified files:
    lib/ctx.c
    lib/ql.h
    src/groonga.c

  Modified: lib/ctx.c (+175 -140)
===================================================================
--- lib/ctx.c    2010-06-11 06:39:34 +0000 (b38b28a)
+++ lib/ctx.c    2010-06-13 07:47:55 +0000 (b368296)
@@ -761,175 +761,190 @@ grn_get_ctype(grn_obj *var)
   return ct;
 }
 
-static const char *
-get_content_type(grn_ctx *ctx, const char *p, const char *pe,
-                 grn_content_type *ct)
-{
-  const char *pd = NULL;
-  for (; p < pe && *p != '?'; p++) {
-    if (*p == '.') {
-      pd = p;
-    }
-  }
-  if (pd && pd < p) {
-    switch (*++pd) {
+static void
+get_content_mime_type(grn_ctx *ctx, const char *p, const char *pe)
+{
+  if (p + 2 <= pe) {
+    switch (*p) {
+    case 'c' :
+      if (p + 3 == pe && !memcmp(p, "css", 3)) {
+        ctx->impl->output_type = GRN_CONTENT_NONE;
+        ctx->impl->mime_type = "text/css";
+      }
+      break;
+    case 'g' :
+      if (p + 3 == pe && !memcmp(p, "gif", 3)) {
+        ctx->impl->output_type = GRN_CONTENT_NONE;
+        ctx->impl->mime_type = "image/gif";
+      }
+      break;
+    case 'h' :
+      if (p + 4 == pe && !memcmp(p, "html", 4)) {
+        ctx->impl->output_type = GRN_CONTENT_NONE;
+        ctx->impl->mime_type = "text/html";
+      }
+      break;
     case 'j' :
-      if (!memcmp(pd, "js", 2)) {
-        if (pd + 2 == p) {
-          *ct = GRN_CONTENT_NONE;
-        } else if (pd + 4 == p && !memcmp(pd + 2, "on", 2)) {
-          *ct = GRN_CONTENT_JSON;
+      if (!memcmp(p, "js", 2)) {
+        if (p + 2 == pe) {
+          ctx->impl->output_type = GRN_CONTENT_NONE;
+          ctx->impl->mime_type = "text/javascript";
+        } else if (p + 4 == pe && !memcmp(p + 2, "on", 2)) {
+          ctx->impl->output_type = GRN_CONTENT_JSON;
+          ctx->impl->mime_type = "application/json";
         }
-      } else if (pd + 3 == p && !memcmp(pd, "jpg", 3)) {
-        *ct = GRN_CONTENT_NONE;
+      } else if (p + 3 == pe && !memcmp(p, "jpg", 3)) {
+        ctx->impl->output_type = GRN_CONTENT_NONE;
+        ctx->impl->mime_type = "image/jpeg";
+      }
+      break;
+    case 'p' :
+      if (p + 3 == pe && !memcmp(p, "png", 3)) {
+        ctx->impl->output_type = GRN_CONTENT_NONE;
+        ctx->impl->mime_type = "image/png";
+      }
+      break;
+    case 't' :
+      if (p + 3 == pe && !memcmp(p, "txt", 3)) {
+        ctx->impl->output_type = GRN_CONTENT_NONE;
+        ctx->impl->mime_type = "text/plain";
+      } else if (p + 3 == pe && !memcmp(p, "tsv", 3)) {
+        ctx->impl->output_type = GRN_CONTENT_TSV;
+        ctx->impl->mime_type = "text/plain";
       }
       break;
     case 'x':
-      if (pd + 3 == p && !memcmp(pd, "xml", 3)) {
-        *ct = GRN_CONTENT_XML;
+      if (p + 3 == pe && !memcmp(p, "xml", 3)) {
+        ctx->impl->output_type = GRN_CONTENT_XML;
+        ctx->impl->mime_type = "text/xml";
       }
       break;
     }
-    return pd - 1;
+  }
+}
+
+static void
+grn_str_get_mime_type(grn_ctx *ctx, const char *p, const char *pe,
+                     const char **key_end, const char **filename_end)
+{
+  const char *pd = NULL;
+  for (; p < pe && *p != '?' && *p != '#'; p++) {
+    if (*p == '.') { pd = p; }
+  }
+  *filename_end = p;
+  if (pd && pd < p) {
+    get_content_mime_type(ctx, pd + 1, p);
+    *key_end = pd;
   } else {
-    *ct = GRN_CONTENT_JSON;
-    return pe;
+    *key_end = pe;
   }
 }
 
+#define INDEX_HTML "index.html"
 #define OUTPUT_TYPE "output_type"
+#define EXPR_MISSING "expr_missing"
 #define OUTPUT_TYPE_LEN (sizeof(OUTPUT_TYPE) - 1)
 
 grn_obj *
 grn_ctx_qe_exec_uri(grn_ctx *ctx, const char *path, uint32_t path_len)
 {
-  const char *p, *e;
-  grn_obj *expr, *val = NULL;
-  if (ctx->impl->qe_next) {
-    expr = ctx->impl->qe_next;
-    ctx->impl->qe_next = NULL;
-    if ((val = grn_expr_get_var_by_offset(ctx, expr, 0))) {
-      grn_obj_reinit(ctx, val, GRN_DB_TEXT, 0);
-      GRN_TEXT_PUT(ctx, val, path, path_len);
-    }
-    val = grn_expr_exec(ctx, expr, 0);
-    grn_expr_clear_vars(ctx, expr);
-  } else {
-    grn_obj key;
-    const char *g, *pe;
-    grn_content_type ot = GRN_CONTENT_NONE;
-    grn_timeval_now(ctx, &ctx->impl->tv);
-    GRN_LOG(ctx, GRN_LOG_NONE, "%08x|>%.*s", (intptr_t)ctx, path_len, path);
-    GRN_TEXT_INIT(&key, 0);
-    p = path;
-    e = p + path_len;
-    g = grn_text_urldec(ctx, &key, p, e, '?');
-    pe = get_content_type(ctx, GRN_TEXT_VALUE(&key), GRN_BULK_CURR(&key), &ot);
-    if ((GRN_TEXT_LEN(&key) >= 2 &&
-         GRN_TEXT_VALUE(&key)[0] == 'd' && GRN_TEXT_VALUE(&key)[1] == '/') &&
-        (expr = grn_ctx_get(ctx, GRN_TEXT_VALUE(&key) + 2, pe - GRN_TEXT_VALUE(&key) - 2))) {
-      while (g < e) {
-        GRN_BULK_REWIND(&key);
-        g = grn_text_cgidec(ctx, &key, g, e, '=');
-        if (!(val = grn_expr_get_var(ctx, expr, GRN_TEXT_VALUE(&key), GRN_TEXT_LEN(&key)))) {
-          val = &key;
+  grn_obj buf, *expr, *val;
+  const char *p = path, *e = path + path_len, *v, *key_end, *filename_end;
+  GRN_TEXT_INIT(&buf, 0);
+  p = grn_text_urldec(ctx, &buf, p, e, '?');
+  if (!GRN_TEXT_LEN(&buf)) { GRN_TEXT_SETS(ctx, &buf, INDEX_HTML); }
+  v = GRN_TEXT_VALUE(&buf);
+  grn_str_get_mime_type(ctx, v, GRN_BULK_CURR(&buf), &key_end, &filename_end);
+  if ((GRN_TEXT_LEN(&buf) >= 2 && v[0] == 'd' && v[1] == '/') &&
+      (expr = grn_ctx_get(ctx, v + 2, key_end - (v + 2)))) {
+    while (p < e) {
+      int l;
+      GRN_BULK_REWIND(&buf);
+      p = grn_text_cgidec(ctx, &buf, p, e, '=');
+      v = GRN_TEXT_VALUE(&buf);
+      l = GRN_TEXT_LEN(&buf);
+      if (l == OUTPUT_TYPE_LEN && !memcmp(v, OUTPUT_TYPE, OUTPUT_TYPE_LEN)) {
+        GRN_BULK_REWIND(&buf);
+        p = grn_text_cgidec(ctx, &buf, p, e, '&');
+        v = GRN_TEXT_VALUE(&buf);
+        get_content_mime_type(ctx, v, GRN_BULK_CURR(&buf));
+      } else {
+        if (!(val = grn_expr_get_var(ctx, expr, v, l)) &&
+            !(val = grn_expr_add_var(ctx, expr, v, l))) {
+          val = &buf;
         }
         grn_obj_reinit(ctx, val, GRN_DB_TEXT, 0);
-        g = grn_text_cgidec(ctx, val, g, e, '&');
+        p = grn_text_cgidec(ctx, val, p, e, '&');
       }
-      if ((val = grn_expr_get_var(ctx, expr, OUTPUT_TYPE, OUTPUT_TYPE_LEN))) {
-        grn_obj_reinit(ctx, val, GRN_DB_INT32, 0);
-        GRN_INT32_SET(ctx, val, (int32_t)ot);
-      }
-
-      val = grn_expr_exec(ctx, expr, 0);
-      grn_expr_clear_vars(ctx, expr);
     }
-    GRN_OBJ_FIN(ctx, &key);
-  }
-  if (!ctx->impl->qe_next) {
-    uint64_t et;
-    grn_timeval tv;
-    grn_timeval_now(ctx, &tv);
-    et = (tv.tv_sec - ctx->impl->tv.tv_sec) * GRN_TIME_USEC_PER_SEC
-      + (tv.tv_usec - ctx->impl->tv.tv_usec);
-    GRN_LOG(ctx, GRN_LOG_NONE, "%08x|<%012zu rc=%d", (intptr_t)ctx, et, ctx->rc);
+    ctx->impl->curr_expr = expr;
+    grn_expr_exec(ctx, expr, 0);
+  } else if ((expr = grn_ctx_get(ctx, GRN_EXPR_MISSING_NAME,
+                                 strlen(GRN_EXPR_MISSING_NAME)))) {
+    if ((val = grn_expr_get_var_by_offset(ctx, expr, 0))) {
+      grn_obj_reinit(ctx, val, GRN_DB_TEXT, 0);
+      GRN_TEXT_SET(ctx, val, v, filename_end - v);
+    }
+    ctx->impl->curr_expr = expr;
+    grn_expr_exec(ctx, expr, 0);
   }
-  return val;
+  GRN_OBJ_FIN(ctx, &buf);
+  return expr;
 }
 
 grn_obj *
 grn_ctx_qe_exec(grn_ctx *ctx, const char *str, uint32_t str_len)
 {
-  grn_obj *expr = NULL, *val = NULL;
-  if (ctx->impl->qe_next) {
-    expr = ctx->impl->qe_next;
-    ctx->impl->qe_next = NULL;
-    if ((val = grn_expr_get_var_by_offset(ctx, expr, 0))) {
-      grn_obj_reinit(ctx, val, GRN_DB_TEXT, 0);
-      GRN_TEXT_PUT(ctx, val, str, str_len);
-    }
-  } else {
-    grn_obj buf;
-    char tok_type;
-    int offset = 0;
-    const char *v, *p = str, *e = str + str_len;
-    grn_timeval_now(ctx, &ctx->impl->tv);
-    GRN_LOG(ctx, GRN_LOG_NONE, "%08x|>%.*s", (intptr_t)ctx, str_len, str);
-    GRN_TEXT_INIT(&buf, 0);
-    p = grn_text_unesc_tok(ctx, &buf, p, e, &tok_type);
-    if ((expr = grn_ctx_get(ctx, GRN_TEXT_VALUE(&buf), GRN_TEXT_LEN(&buf)))) {
-      while (p < e) {
-        GRN_BULK_REWIND(&buf);
-        p = grn_text_unesc_tok(ctx, &buf, p, e, &tok_type);
-        switch (tok_type) {
-        case GRN_TOK_VOID :
-          p = e;
-          break;
-        case GRN_TOK_SYMBOL :
-          v = GRN_TEXT_VALUE(&buf);
-          if (GRN_TEXT_LEN(&buf) > 2 && v[0] == '-' && v[1] == '-') {
-            if ((val = grn_expr_get_var(ctx, expr, v + 2, GRN_TEXT_LEN(&buf) - 2))) {
-              grn_obj_reinit(ctx, val, GRN_DB_TEXT, 0);
-              p = grn_text_unesc_tok(ctx, val, p, e, &tok_type);
-            } else {
-              p = e;
-            }
-            break;
-          }
-          // fallthru
-        case GRN_TOK_STRING :
-        case GRN_TOK_QUOTE :
-          if ((val = grn_expr_get_var_by_offset(ctx, expr, offset++))) {
+  char tok_type;
+  int offset = 0;
+  grn_obj buf, *expr = NULL, *val = NULL;
+  const char *p = str, *e = str + str_len, *v;
+  GRN_TEXT_INIT(&buf, 0);
+  p = grn_text_unesc_tok(ctx, &buf, p, e, &tok_type);
+  if ((expr = grn_ctx_get(ctx, GRN_TEXT_VALUE(&buf), GRN_TEXT_LEN(&buf)))) {
+    while (p < e) {
+      GRN_BULK_REWIND(&buf);
+      p = grn_text_unesc_tok(ctx, &buf, p, e, &tok_type);
+      v = GRN_TEXT_VALUE(&buf);
+      switch (tok_type) {
+      case GRN_TOK_VOID :
+        p = e;
+        break;
+      case GRN_TOK_SYMBOL :
+        if (GRN_TEXT_LEN(&buf) > 2 && v[0] == '-' && v[1] == '-') {
+          int l = GRN_TEXT_LEN(&buf) - 2;
+          v += 2;
+          if (l == OUTPUT_TYPE_LEN && !memcmp(v, OUTPUT_TYPE, OUTPUT_TYPE_LEN)) {
+            GRN_BULK_REWIND(&buf);
+            p = grn_text_unesc_tok(ctx, &buf, p, e, &tok_type);
+            v = GRN_TEXT_VALUE(&buf);
+            get_content_mime_type(ctx, v, GRN_BULK_CURR(&buf));
+          } else if ((val = grn_expr_get_var(ctx, expr, v, l)) ||
+                     (val = grn_expr_add_var(ctx, expr, v, l))) {
             grn_obj_reinit(ctx, val, GRN_DB_TEXT, 0);
-            GRN_TEXT_PUT(ctx, val, GRN_TEXT_VALUE(&buf), GRN_TEXT_LEN(&buf));
+            p = grn_text_unesc_tok(ctx, val, p, e, &tok_type);
           } else {
             p = e;
           }
           break;
         }
+        // fallthru
+      case GRN_TOK_STRING :
+      case GRN_TOK_QUOTE :
+        if ((val = grn_expr_get_var_by_offset(ctx, expr, offset++))) {
+          grn_obj_reinit(ctx, val, GRN_DB_TEXT, 0);
+          GRN_TEXT_PUT(ctx, val, GRN_TEXT_VALUE(&buf), GRN_TEXT_LEN(&buf));
+        } else {
+          p = e;
+        }
+        break;
       }
     }
-    GRN_OBJ_FIN(ctx, &buf);
+    ctx->impl->curr_expr = expr;
+    grn_expr_exec(ctx, expr, 0);
   }
-  if (expr) {
-    if ((val = grn_expr_get_var(ctx, expr, OUTPUT_TYPE, OUTPUT_TYPE_LEN))) {
-      grn_content_type ot = grn_get_ctype(val);
-      grn_obj_reinit(ctx, val, GRN_DB_INT32, 0);
-      GRN_INT32_SET(ctx, val, (int32_t)ot);
-    }
-    val = grn_expr_exec(ctx, expr, 0);
-    grn_expr_clear_vars(ctx, expr);
-  }
-  if (!ctx->impl->qe_next) {
-    uint64_t et;
-    grn_timeval tv;
-    grn_timeval_now(ctx, &tv);
-    et = (tv.tv_sec - ctx->impl->tv.tv_sec) * GRN_TIME_USEC_PER_SEC
-      + (tv.tv_usec - ctx->impl->tv.tv_usec);
-    GRN_LOG(ctx, GRN_LOG_NONE, "%08x|<%012zu rc=%d", (intptr_t)ctx, et, ctx->rc);
-  }
-  return val;
+  GRN_OBJ_FIN(ctx, &buf);
+  return expr;
 }
 
 grn_rc
@@ -972,15 +987,26 @@ grn_ctx_send(grn_ctx *ctx, const char *str, unsigned int str_len, int flags)
       }
       goto exit;
     } else {
-      /*
-      GRN_BULK_REWIND(ctx->impl->outbuf);
-      GRN_BULK_REWIND(&ctx->impl->subbuf);
-      ctx->impl->bufcur = 0;
-      */
-      if (str_len && *str == '/') {
-        grn_ctx_qe_exec_uri(ctx, str + 1, str_len - 1);
+      grn_obj *expr;
+      if (ctx->impl->qe_next) {
+        grn_obj *val;
+        expr = ctx->impl->qe_next;
+        ctx->impl->qe_next = NULL;
+        if ((val = grn_expr_get_var_by_offset(ctx, expr, 0))) {
+          grn_obj_reinit(ctx, val, GRN_DB_TEXT, 0);
+          GRN_TEXT_PUT(ctx, val, str, str_len);
+        }
+        grn_expr_exec(ctx, expr, 0);
       } else {
-        grn_ctx_qe_exec(ctx, str, str_len);
+        ctx->impl->mime_type = "application/json";
+        ctx->impl->output_type = GRN_CONTENT_JSON;
+        grn_timeval_now(ctx, &ctx->impl->tv);
+        GRN_LOG(ctx, GRN_LOG_NONE, "%08x|>%.*s", (intptr_t)ctx, str_len, str);
+        if (str_len && *str == '/') {
+          expr = grn_ctx_qe_exec_uri(ctx, str + 1, str_len - 1);
+        } else {
+          expr = grn_ctx_qe_exec(ctx, str, str_len);
+        }
       }
       if (ctx->stat == GRN_CTX_QUITTING) { ctx->stat = GRN_CTX_QUIT; }
       if (!ERRP(ctx, GRN_CRIT)) {
@@ -988,6 +1014,15 @@ grn_ctx_send(grn_ctx *ctx, const char *str, unsigned int str_len, int flags)
           ctx->impl->output(ctx, 0, ctx->impl->data.ptr);
         }
       }
+      if (expr) { grn_expr_clear_vars(ctx, expr); }
+      if (!ctx->impl->qe_next) {
+        uint64_t et;
+        grn_timeval tv;
+        grn_timeval_now(ctx, &tv);
+        et = (tv.tv_sec - ctx->impl->tv.tv_sec) * GRN_TIME_USEC_PER_SEC
+          + (tv.tv_usec - ctx->impl->tv.tv_usec);
+        GRN_LOG(ctx, GRN_LOG_NONE, "%08x|<%012zu rc=%d", (intptr_t)ctx, et, ctx->rc);
+      }
       goto exit;
     }
   }

  Modified: lib/ql.h (+2 -0)
===================================================================
--- lib/ql.h    2010-06-11 06:39:34 +0000 (a0fa680)
+++ lib/ql.h    2010-06-13 07:47:55 +0000 (2f052db)
@@ -186,6 +186,7 @@ struct _grn_ctx_impl {
   grn_obj *stack[GRN_STACK_SIZE];
   uint32_t stack_curr;
   grn_hash *expr_vars;
+  grn_obj *curr_expr;
   grn_obj *qe_next;
   void *parser;
   grn_timeval tv;
@@ -199,6 +200,7 @@ struct _grn_ctx_impl {
 
   /* output portion */
   grn_content_type output_type;
+  const char *mime_type;
 
   /* ql portion */
   uint32_t ncells;

  Modified: src/groonga.c (+25 -171)
===================================================================
--- src/groonga.c    2010-06-11 06:39:34 +0000 (c6d191c)
+++ src/groonga.c    2010-06-13 07:47:55 +0000 (9411988)
@@ -269,95 +269,6 @@ typedef enum {
   grn_http_request_type_post
 } grn_http_request_type;
 
-void
-get_content_mime_type(const char *p, const char *pe,
-                      grn_content_type *ct, const char **mime_type)
-{
-  switch (*p) {
-  case 'c' :
-    if (p + 3 == pe && !memcmp(p, "css", 3)) {
-      *ct = GRN_CONTENT_NONE;
-      *mime_type = "text/css";
-    }
-    break;
-  case 'g' :
-    if (p + 3 == pe && !memcmp(p, "gif", 3)) {
-      *ct = GRN_CONTENT_NONE;
-      *mime_type = "image/gif";
-    }
-    break;
-  case 'h' :
-    if (p + 4 == pe && !memcmp(p, "html", 4)) {
-      *ct = GRN_CONTENT_NONE;
-      *mime_type = "text/html";
-    }
-    break;
-  case 'j' :
-    if (!memcmp(p, "js", 2)) {
-      if (p + 2 == pe) {
-        *ct = GRN_CONTENT_NONE;
-        *mime_type = "text/javascript";
-      } else if (p + 4 == pe && !memcmp(p + 2, "on", 2)) {
-        *ct = GRN_CONTENT_JSON;
-        *mime_type = "application/json";
-      }
-    } else if (p + 3 == pe && !memcmp(p, "jpg", 3)) {
-      *ct = GRN_CONTENT_NONE;
-      *mime_type = "image/jpeg";
-    }
-    break;
-  case 'p' :
-    if (p + 3 == pe && !memcmp(p, "png", 3)) {
-      *ct = GRN_CONTENT_NONE;
-      *mime_type = "image/png";
-    }
-    break;
-  case 't' :
-    if (p + 3 == pe && !memcmp(p, "txt", 3)) {
-      *ct = GRN_CONTENT_NONE;
-      *mime_type = "text/plain";
-    }
-    break;
-  case 'x':
-    if (p + 3 == pe && !memcmp(p, "xml", 3)) {
-      *ct = GRN_CONTENT_XML;
-      *mime_type = "text/xml";
-    }
-    break;
-  }
-}
-
-static void
-parse_htpath(const char *p, const char *pe,
-             const char **key_end, const char **filename_end,
-             grn_content_type *ct, const char **mime_type)
-{
-  const char *pd = NULL;
-  for (; p < pe && *p != '?' && *p != '#'; p++) {
-    if (*p == '.') {
-      pd = p;
-    }
-  }
-  *filename_end = p;
-  *ct = GRN_CONTENT_JSON;
-  *mime_type = "application/json";
-  if (pd && pd < p) {
-    get_content_mime_type(pd + 1, p, ct, mime_type);
-    *key_end = pd;
-  } else {
-    *key_end = pe;
-  }
-}
-
-#define INDEX_HTML "index.html"
-#define OUTPUT_TYPE "output_type"
-#define EXPR_MISSING "expr_missing"
-#define JSON_CALLBACK_PARAM "callback"
-#define OUTPUT_TYPE_LEN (sizeof(OUTPUT_TYPE) - 1)
-
-#define GRN_TEXT_CMPS(obj,str) \
-  (GRN_TEXT_LEN((obj)) == strlen((str)) && !memcmp(GRN_TEXT_VALUE((obj)), (str), strlen((str))))
-
 static void
 print_return_code(grn_ctx *ctx, grn_rc rc, grn_obj *head, grn_obj *body, grn_obj *foot)
 {
@@ -403,15 +314,29 @@ print_return_code(grn_ctx *ctx, grn_rc rc, grn_obj *head, grn_obj *body, grn_obj
   }
 }
 
+#define JSON_CALLBACK_PARAM "callback"
+
+typedef struct {
+  grn_obj body;
+  grn_msg *msg;
+} ht_context;
+
 static void
-h_output(grn_ctx *ctx, grn_rc expr_rc, grn_sock fd,
-         grn_obj *jsonp_func, grn_obj *body, const char *mime_type)
+h_output(grn_ctx *ctx, int flags, void *arg)
 {
+  grn_rc expr_rc = ctx->rc;
+  ht_context *hc = (ht_context *)arg;
+  grn_sock fd = hc->msg->u.fd;
+  grn_obj *expr = ctx->impl->curr_expr;
+  grn_obj *jsonp_func = grn_expr_get_var(ctx, expr, JSON_CALLBACK_PARAM,
+                                         strlen(JSON_CALLBACK_PARAM));
+  grn_obj *body = &hc->body;
+  const char *mime_type = ctx->impl->mime_type;
   grn_obj head, foot, *outbuf = ctx->impl->outbuf;
   GRN_TEXT_INIT(&head, 0);
   GRN_TEXT_INIT(&foot, 0);
   if (!expr_rc) {
-    if (GRN_TEXT_LEN(jsonp_func)) {
+    if (jsonp_func && GRN_TEXT_LEN(jsonp_func)) {
       GRN_TEXT_PUT(ctx, &head, GRN_TEXT_VALUE(jsonp_func), GRN_TEXT_LEN(jsonp_func));
       GRN_TEXT_PUTC(ctx, &head, '(');
       print_return_code(ctx, expr_rc, &head, outbuf, &foot);
@@ -479,18 +404,10 @@ h_output(grn_ctx *ctx, grn_rc expr_rc, grn_sock fd,
   GRN_BULK_REWIND(outbuf);
   GRN_OBJ_FIN(ctx, &foot);
   GRN_OBJ_FIN(ctx, &head);
-  {
-    uint64_t et;
-    grn_timeval tv;
-    grn_timeval_now(ctx, &tv);
-    et = (tv.tv_sec - ctx->impl->tv.tv_sec) * GRN_TIME_USEC_PER_SEC
-      + (tv.tv_usec - ctx->impl->tv.tv_usec);
-    GRN_LOG(ctx, GRN_LOG_NONE, "%08x|<%012zu rc=%d", (intptr_t)ctx, et, ctx->rc);
-  }
 }
 
 static void
-do_htreq(grn_ctx *ctx, grn_msg *msg, grn_obj *body)
+do_htreq(grn_ctx *ctx, grn_msg *msg)
 {
   grn_sock fd = msg->u.fd;
   grn_http_request_type t = grn_http_request_type_none;
@@ -522,73 +439,7 @@ do_htreq(grn_ctx *ctx, grn_msg *msg, grn_obj *body)
         }
       }
     }
-    /* TODO: handle post body */
-    {
-      const char *mime_type = NULL;
-      grn_rc expr_rc = GRN_SUCCESS;
-      grn_obj jsonp_func;
-      GRN_TEXT_INIT(&jsonp_func, 0);
-      if (*path != '/') {
-        expr_rc = GRN_INVALID_ARGUMENT;
-      } else {
-        grn_obj key;
-        grn_content_type ot;
-        grn_obj *expr, *val = NULL;
-        const char *g, *key_end, *filename_end;
-
-        grn_timeval_now(ctx, &ctx->impl->tv); /* should be initialized in grn_ctx_qe_exec() */
-        GRN_LOG(ctx, GRN_LOG_NONE, "%08x|>%.*s", (intptr_t)ctx, pathe - path, path);
-        GRN_TEXT_INIT(&key, 0);
-
-        g = grn_text_urldec(ctx, &key, path + 1, pathe, '?');
-        if (!GRN_TEXT_LEN(&key)) { GRN_TEXT_SETS(ctx, &key, INDEX_HTML); }
-        parse_htpath(GRN_TEXT_VALUE(&key), GRN_BULK_CURR(&key),
-                     &key_end, &filename_end, &ot, &mime_type);
-        if ((GRN_TEXT_LEN(&key) >= 2 &&
-             GRN_TEXT_VALUE(&key)[0] == 'd' && GRN_TEXT_VALUE(&key)[1] == '/') &&
-            (expr = grn_ctx_get(ctx, GRN_TEXT_VALUE(&key) + 2,
-                                key_end - GRN_TEXT_VALUE(&key) - 2))) {
-          while (g < pathe) {
-            GRN_BULK_REWIND(&key);
-            g = grn_text_cgidec(ctx, &key, g, pathe, '=');
-            if (GRN_TEXT_CMPS(&key, JSON_CALLBACK_PARAM)) {
-              val = &jsonp_func;
-            } else if (!(val = grn_expr_get_var(ctx, expr, GRN_TEXT_VALUE(&key), GRN_TEXT_LEN(&key)))) {
-              val = &key;
-            }
-            grn_obj_reinit(ctx, val, GRN_DB_TEXT, 0);
-            g = grn_text_cgidec(ctx, val, g, pathe, '&');
-            if (GRN_TEXT_CMPS(&key, OUTPUT_TYPE)) {
-              get_content_mime_type(GRN_TEXT_VALUE(val),
-                                    GRN_TEXT_VALUE(val) + GRN_TEXT_LEN(val),
-                                    &ot, &mime_type);
-            }
-          }
-          if ((val = grn_expr_get_var(ctx, expr, OUTPUT_TYPE, OUTPUT_TYPE_LEN))) {
-            grn_obj_reinit(ctx, val, GRN_DB_INT32, 0);
-            GRN_INT32_SET(ctx, val, (int32_t)ot);
-          }
-          ctx->impl->output_type = ot;
-          val = grn_expr_exec(ctx, expr, 0);
-          expr_rc = ctx->rc;
-          grn_expr_clear_vars(ctx, expr);
-        } else if ((expr = grn_ctx_get(ctx, GRN_EXPR_MISSING_NAME,
-                                       strlen(GRN_EXPR_MISSING_NAME)))) {
-          if ((val = grn_expr_get_var_by_offset(ctx, expr, 0))) {
-            grn_obj_reinit(ctx, val, GRN_DB_TEXT, 0);
-            GRN_TEXT_SET(ctx, val,
-                         GRN_TEXT_VALUE(&key), filename_end - GRN_TEXT_VALUE(&key));
-          }
-          ctx->impl->output_type = ot;
-          val = grn_expr_exec(ctx, expr, 0);
-          expr_rc = ctx->rc;
-          grn_expr_clear_vars(ctx, expr);
-        }
-        GRN_OBJ_FIN(ctx, &key);
-      }
-      h_output(ctx, expr_rc, fd, &jsonp_func, body, mime_type);
-      GRN_OBJ_FIN(ctx, &jsonp_func);
-    }
+    grn_ctx_send(ctx, path, pathe - path, 0);
   }
 exit :
   // todo : support "Connection: keep-alive"
@@ -1171,11 +1022,12 @@ static uint32_t nthreads = 0, nfthreads = 0, max_nfthreads;
 static void * CALLBACK
 h_worker(void *arg)
 {
-  grn_obj body;
+  ht_context hc;
   grn_ctx ctx_, *ctx = &ctx_;
   grn_ctx_init(ctx, 0);
-  GRN_TEXT_INIT(&body, 0);
+  GRN_TEXT_INIT(&hc.body, 0);
   grn_ctx_use(ctx, (grn_obj *)arg);
+  grn_ctx_recv_handler_set(ctx, h_output, &hc);
   GRN_LOG(&grn_gctx, GRN_LOG_NOTICE, "thread start (%d/%d)", nfthreads, nthreads + 1);
   MUTEX_LOCK(q_mutex);
   do {
@@ -1187,13 +1039,15 @@ h_worker(void *arg)
     }
     nfthreads--;
     MUTEX_UNLOCK(q_mutex);
-    do_htreq(ctx, (grn_msg *)msg, &body);
+    hc.msg = (grn_msg *)msg;
+    do_htreq(ctx, (grn_msg *)msg);
     MUTEX_LOCK(q_mutex);
   } while (nfthreads < max_nfthreads && grn_gctx.stat != GRN_CTX_QUIT);
 exit :
   nthreads--;
   MUTEX_UNLOCK(q_mutex);
   GRN_LOG(&grn_gctx, GRN_LOG_NOTICE, "thread end (%d/%d)", nfthreads, nthreads);
+  GRN_OBJ_FIN(ctx, &hc.body);
   grn_ctx_fin(ctx);
   return NULL;
 }




Groonga-commit メーリングリストの案内
Zurück zum Archiv-Index