Пример #1
0
static int
noit_lua_module_config(noit_module_t *mod,
                       mtev_hash_table *options) {
  struct module_conf *mc;
  struct module_tls_conf *mtlsc;
  LMC_DECL(L, mod, object);

  mc = noit_module_get_userdata(mod);
  if(options) {
    mtevAssert(mc->options == NULL);
    mc->options = calloc(1, sizeof(*mc->options));
    mtev_hash_init(mc->options);
    mtev_hash_merge_as_dict(mc->options, options);
  }
  else options = mc->options;
  mtlsc = __get_module_tls_conf(&mod->hdr);
  if(mtlsc->configured) return mtlsc->configured_return;

  SETUP_CALL(L, object, "config", return 0);

  noit_lua_setup_module(L, mod);
  mtev_lua_hash_to_table(L, options);
  lua_pcall(L, 2, 1, 0);

  /* If rv == 0, the caller will free options. We've
   * already freed options, that would be bad. fudge -> 1 */
  RETURN_INT(L, object, "config",
             { mtlsc->configured = 1; mtlsc->configured_return = rv; });
Пример #2
0
static int
mtev_lua_http_request_querystring(lua_State *L) {
  mtev_hash_table *h;
  CCALL_DECL(L, mtev_http_request, req, 0);
  h = mtev_http_request_querystring_table(req);
  if(lua_gettop(L) == 1)
    mtev_lua_hash_to_table(L, h);
  else if(lua_gettop(L) == 2) {
    const char *key = lua_tostring(L,2), *value;
    if(key == NULL) lua_pushnil(L);
    else {
      if(mtev_hash_retr_str(h, key, strlen(key), &value))
        lua_pushstring(L, value);
      else
        lua_pushnil(L);
    }
  }
  else luaL_error(L, "invalid arguments to mtev_http_request:querystring()");
  return 1;
}
Пример #3
0
static int
mtev_lua_http_request_headers(lua_State *L) {
  mtev_hash_table *h;
  CCALL_DECL(L, mtev_http_request, req, 0);
  h = mtev_http_request_headers_table(req);
  if(lua_gettop(L) == 1)
    mtev_lua_hash_to_table(L, h);
  else if(lua_gettop(L) == 2) {
    const char *hdr = lua_tostring(L,2);
    if(hdr == NULL) lua_pushnil(L);
    else {
      char *cp, *lower = alloca(strlen(hdr) + 1);
      memcpy(lower, hdr, strlen(hdr)+1);
      for(cp=lower; *cp; cp++) *cp = tolower(*cp);
      if(mtev_hash_retr_str(h, lower, strlen(lower), &hdr))
        lua_pushstring(L, hdr);
      else
        lua_pushnil(L);
    }
  }
  else luaL_error(L, "invalid arguments to mtev_http_request:headers()");
  return 1;
}
Пример #4
0
static int
noit_check_index_func(lua_State *L) {
  int n;
  const char *k;
  noit_check_t **udata, *check;
  n = lua_gettop(L);    /* number of arguments */
  mtevAssert(n == 2);
  if(!luaL_checkudata(L, 1, "noit_check_t")) {
    luaL_error(L, "metatable error, arg1 not a noit_check_t!");
  }
  udata = lua_touserdata(L, 1);
  check = *udata;
  if(!lua_isstring(L, 2)) {
    luaL_error(L, "metatable error, arg2 not a string!");
  }
  k = lua_tostring(L, 2);
  switch(*k) {
    case 'a':
      if(!strcmp(k, "available")) {
        lua_pushlightuserdata(L, check);
        lua_pushinteger(L, NP_AVAILABLE);
        lua_pushcclosure(L, noit_lua_set_available, 2);
      }
      else if(!strcmp(k, "availability")) {
        lua_pushlightuserdata(L, check);
        lua_pushcclosure(L, noit_lua_get_available, 1);
      }
      else break;
      return 1;
    case 'b':
      if(!strcmp(k, "bad")) {
        lua_pushlightuserdata(L, check);
        lua_pushinteger(L, NP_BAD);
        lua_pushcclosure(L, noit_lua_set_state, 2);
      }
      else break;
      return 1;
    case 'c':
      if(!strcmp(k, "config")) mtev_lua_hash_to_table(L, check->config);
      else if(!strcmp(k, "checkid")) {
        char uuid_str[UUID_STR_LEN + 1];
        uuid_unparse_lower(check->checkid, uuid_str);
        lua_pushstring(L, uuid_str);
      }
      else break;
      return 1;
    case 'f':
      if(!strcmp(k, "flags")) {
        lua_pushlightuserdata(L, check);
        lua_pushcclosure(L, noit_lua_get_flags, 1);
      }
      else break;
      return 1;
    case 'g':
      if(!strcmp(k, "good")) {
        lua_pushlightuserdata(L, check);
        lua_pushinteger(L, NP_GOOD);
        lua_pushcclosure(L, noit_lua_set_state, 2);
      }
      else break;
      return 1;
    case 'i':
      if(!strcmp(k, "interpolate")) {
        lua_pushlightuserdata(L, check);
        lua_pushcclosure(L, noit_lua_interpolate, 1);
      }
      else if(!strcmp(k, "is_thread_local")) {
        if(check->fire_event &&
           pthread_equal(pthread_self(), check->fire_event->thr_owner)) {
          lua_pushboolean(L, 1);
        }
        else {
          lua_pushboolean(L, 0);
        }
        return 1;
      }

#define IF_METRIC_IMMEDIATE_BLOCK(name,type) \
      if(!strcmp(k, "immediate_" name)) { \
        lua_pushlightuserdata(L, check); \
        lua_pushinteger(L, type); \
        lua_pushcclosure(L, noit_lua_log_immediate_metric, 2); \
      }
      else IF_METRIC_IMMEDIATE_BLOCK("metric", METRIC_GUESS)
      else IF_METRIC_IMMEDIATE_BLOCK("metric_string", METRIC_STRING)
      else IF_METRIC_IMMEDIATE_BLOCK("metric_int32", METRIC_INT32)
      else IF_METRIC_IMMEDIATE_BLOCK("metric_uint32", METRIC_UINT32)
      else IF_METRIC_IMMEDIATE_BLOCK("metric_int64", METRIC_INT64)
      else IF_METRIC_IMMEDIATE_BLOCK("metric_uint64", METRIC_UINT64)
      else IF_METRIC_IMMEDIATE_BLOCK("metric_double", METRIC_DOUBLE)
      else if(!strcmp(k, "immediate_histogram")) {
        lua_pushlightuserdata(L, check);
        lua_pushcclosure(L, noit_lua_set_histo_metric, 1);
      }
      else break;

      return 1;
    case 'm':
      if(!strcmp(k, "module")) lua_pushstring(L, check->module);

#define IF_METRIC_BLOCK(name,type) \
      if(!strcmp(k, name)) { \
        lua_pushlightuserdata(L, check); \
        lua_pushinteger(L, type); \
        lua_pushcclosure(L, noit_lua_set_metric, 2); \
      }

      else IF_METRIC_BLOCK("metric", METRIC_GUESS)
      else IF_METRIC_BLOCK("metric_string", METRIC_STRING)
      else IF_METRIC_BLOCK("metric_int32", METRIC_INT32)
      else IF_METRIC_BLOCK("metric_uint32", METRIC_UINT32)
      else IF_METRIC_BLOCK("metric_int64", METRIC_INT64)
      else IF_METRIC_BLOCK("metric_uint64", METRIC_UINT64)
      else IF_METRIC_BLOCK("metric_double", METRIC_DOUBLE)
      else if(!strcmp(k, "metric_json")) {
        lua_pushlightuserdata(L, check);
        lua_pushcclosure(L, noit_lua_set_metric_json, 1);
      }

      else break;
      return 1;
    case 'n':
      if(!strcmp(k, "name")) lua_pushstring(L, check->name);
      else break;
      return 1;
    case 'p':
      if(!strcmp(k, "period")) lua_pushinteger(L, check->period);
      else break;
      return 1;
    case 's':
      if(!strcmp(k, "set_flags")) {
        lua_pushlightuserdata(L, check);
        lua_pushcclosure(L, noit_lua_set_flags, 1);
      }
      else if(!strcmp(k, "state")) {
        lua_pushlightuserdata(L, check);
        lua_pushcclosure(L, noit_lua_get_state, 1);
      }
      else if(!strcmp(k, "status")) {
        lua_pushlightuserdata(L, check);
        lua_pushcclosure(L, noit_lua_set_status, 1);
      }
      else break;
      return 1;
   case 't':
      if(!strcmp(k, "target")) lua_pushstring(L, check->target);
      else if(!strcmp(k, "target_ip")) {
        if(check->target_ip[0] == '\0') lua_pushnil(L);
        else lua_pushstring(L, check->target_ip);
      }
      else if(!strcmp(k, "timeout")) lua_pushinteger(L, check->timeout);
      else break;
      return 1;
    case 'u':
      if(!strcmp(k, "unavailable")) {
        lua_pushlightuserdata(L, check);
        lua_pushinteger(L, NP_UNAVAILABLE);
        lua_pushcclosure(L, noit_lua_set_available, 2);
      }
      else if(!strcmp(k, "unset_flags")) {
        lua_pushlightuserdata(L, check);
        lua_pushcclosure(L, noit_lua_unset_flags, 1);
      }
      else if(!strcmp(k, "uuid")) {
        char uuid_str[UUID_STR_LEN+1];
        uuid_unparse_lower(check->checkid, uuid_str);
        lua_pushstring(L, uuid_str);
        return 1;
      }
      else break;
      return 1;
    default:
      break;
  }
  luaL_error(L, "noit_check_t no such element: %s", k);
  return 0;
}
Пример #5
0
static int
lua_web_handler(mtev_http_rest_closure_t *restc,
                int npats, char **pats) {
  int status, base, rv, mask = 0;
  int complete = 0;
  lua_web_conf_t *conf = the_one_conf;
  lua_module_closure_t *lmc = &conf->lmc;
  mtev_lua_resume_info_t *ri;
  mtev_lua_resume_rest_info_t *ctx = NULL;
  lua_State *L;
  eventer_t conne;
  mtev_http_request *req = mtev_http_session_request(restc->http_ctx);
  mtev_http_response *res = mtev_http_session_response(restc->http_ctx);

  if(!lmc || !conf || !conf->dispatch) {
    goto boom;
  }

  if(mtev_http_request_get_upload(req, NULL) == NULL &&
     mtev_http_request_has_payload(req)) {
    const void *payload = NULL;
    int payload_len = 0;
    payload = rest_get_raw_upload(restc, &mask, &complete, &payload_len);
    if(!complete) return mask;
    mtev_http_request_set_upload(req, (char *)payload, (int64_t)payload_len,
                                 req_payload_free, NULL);
    restc->call_closure_free(restc->call_closure);
    restc->call_closure = NULL;
  }

  if(restc->call_closure == NULL) {
    ri = calloc(1, sizeof(*ri));
    ri->bound_thread = pthread_self();
    ri->context_magic = LUA_REST_INFO_MAGIC;
    ctx = ri->context_data = calloc(1, sizeof(mtev_lua_resume_rest_info_t));
    ctx->restc = restc;
    ri->lmc = lmc;
    lua_getglobal(lmc->lua_state, "mtev_coros");
    ri->coro_state = lua_newthread(lmc->lua_state);
    ri->coro_state_ref = luaL_ref(lmc->lua_state, -2);

    mtev_lua_set_resume_info(lmc->lua_state, ri);

    lua_pop(lmc->lua_state, 1); /* pops mtev_coros */

    restc->call_closure = ri;
    restc->call_closure_free = rest_lua_ctx_free;
  }
  ri = restc->call_closure;
  ctx = ri->context_data;
  ctx->httpcode = 404;

  L = ri->coro_state;

  lua_getglobal(L, "require");
  lua_pushstring(L, conf->dispatch);
  rv = lua_pcall(L, 1, 1, 0);
  if(rv) {
    int i;
    mtevL(mtev_error, "lua: require %s failed\n", conf->dispatch);
    i = lua_gettop(L);
    if(i>0) {
      if(lua_isstring(L, i)) {
        const char *err;
        size_t len;
        err = lua_tolstring(L, i, &len);
        mtevL(mtev_error, "lua: %s\n", err);
      }
    }
    lua_pop(L,i);
    goto boom;
  }
  lua_pop(L, lua_gettop(L));

  mtev_lua_pushmodule(L, conf->dispatch);
  if(lua_isnil(L, -1)) {
    lua_pop(L, 1);
    ctx->err = strdup("no such module");
    goto boom;
  }
  lua_getfield(L, -1, "handler");
  lua_remove(L, -2);
  if(!lua_isfunction(L, -1)) {
    lua_pop(L, 1);
    ctx->err = strdup("no 'handler' function in module");
    goto boom;
  }
  mtev_lua_setup_restc(L, restc);
  mtev_lua_hash_to_table(L, restc->ac->config);

  conne = mtev_http_connection_event(mtev_http_session_connection(restc->http_ctx));
  eventer_remove(conne);
  restc->fastpath = lua_web_restc_fastpath;

  status = lmc->resume(ri, 2);
  if(status == 0) return 0;

  if(mtev_http_response_complete(res) != mtev_true) {
 boom:
    mtev_http_response_standard(restc->http_ctx,
                                (ctx && ctx->httpcode) ? ctx->httpcode : 500,
                                "ERROR", "text/plain");
    if(ctx && ctx->err) mtev_http_response_append(restc->http_ctx, ctx->err, strlen(ctx->err));
    mtev_http_response_end(restc->http_ctx);
  }
  return 0;
}