Exemple #1
0
static int
rest_test_check_err(mtev_http_rest_closure_t *restc,
                    int npats, char **pats) {
  mtev_http_response *res = mtev_http_session_response(restc->http_ctx);
  mtev_skiplist_remove(&in_progress, restc,
                       (mtev_freefunc_t)rest_test_check_result);
  if(mtev_http_response_complete(res) != mtev_true) {
    mtev_http_response_standard(restc->http_ctx, 500, "ERROR", "text/html");
    mtev_http_response_end(restc->http_ctx);
  }
  return 0;
}
Exemple #2
0
static int
rest_test_check(mtev_http_rest_closure_t *restc,
                int npats, char **pats) {
  noit_check_t *tcheck;
  mtev_http_session_ctx *ctx = restc->http_ctx;
  int mask, complete = 0;
  int error_code = 500;
  const char *error = "internal error";
  xmlDocPtr indoc, doc = NULL;
  xmlNodePtr attr, config, root;

  indoc = rest_get_xml_upload(restc, &mask, &complete);
  if(!complete) return mask;
  if(indoc == NULL) {
    error = "xml parse error";
    goto error;
  }
  if(!noit_validate_check_rest_post(indoc, &attr, &config, &error))
    goto error;

  tcheck = noit_fire_check(attr, config, &error);
  if(tcheck) {
    /* push the check and the context into a queue to complete on */
    struct check_test_closure *cl;
    cl = calloc(1, sizeof(*cl));
    if(npats == 1 && !strcmp(pats[0], ".json"))
      cl->output = WANTS_JSON;
    cl->check = tcheck;
    cl->restc = restc;
    mtev_skiplist_insert(&in_progress, cl);
    check_test_schedule_sweeper();
    if(restc->call_closure_free)
      restc->call_closure_free(restc->call_closure);
    restc->call_closure_free = NULL;
    restc->call_closure = NULL;
    restc->fastpath = rest_test_check_err;
    goto cleanup;
  }

 error:
  mtev_http_response_standard(ctx, error_code, "ERROR", "text/xml");
  doc = xmlNewDoc((xmlChar *)"1.0");
  root = xmlNewDocNode(doc, NULL, (xmlChar *)"error", NULL);
  xmlDocSetRootElement(doc, root);
  xmlNodeAddContent(root, (xmlChar *)error);
  mtev_http_response_xml(ctx, doc);
  mtev_http_response_end(ctx);
  goto cleanup;

 cleanup:
  if(doc) xmlFreeDoc(doc);
  return 0;
}
static int rest_delete_feed(mtev_http_rest_closure_t *restc,
                            int npats, char **pats) {
  mtev_http_session_ctx *ctx = restc->http_ctx;
  const char *err = "unknown error";
  const char *jpath_with_sub;
  char jlogpath[PATH_MAX], *cp;
  int rv;
  mtev_log_stream_t feed;
  jlog_ctx *jctx;

  feed = mtev_log_stream_find("feed");
  if(!feed) { err = "cannot find feed"; goto error; }

  jpath_with_sub = mtev_log_stream_get_path(feed);
  strlcpy(jlogpath, jpath_with_sub, sizeof(jlogpath));
  cp = strchr(jlogpath, '(');
  if(cp) *cp = '\0';

  jctx = jlog_new(jlogpath);
  rv = jlog_ctx_remove_subscriber(jctx, pats[0]);
  jlog_ctx_close(jctx);
  if(rv < 0) {
    err = jlog_ctx_err_string(jctx);
    goto error;
  }

  /* removed or note, we should do a sweeping cleanup */
  jlog_clean(jlogpath);

  if(rv == 0) {
    mtev_http_response_not_found(ctx, "text/plain");
    mtev_http_response_end(ctx);
    return 0;
  }

  mtev_http_response_standard(ctx, 204, "OK", "text/plain");
  mtev_http_response_end(ctx);
  return 0;

 error:
  mtev_http_response_server_error(ctx, "text/plain");
  mtev_http_response_append(ctx, err, strlen(err));
  mtev_http_response_end(ctx);
  return 0;
}
Exemple #4
0
static int
lua_web_restc_fastpath(mtev_http_rest_closure_t *restc,
                       int npats, char **pats) {
  mtev_lua_resume_info_t *ri = restc->call_closure;
  mtev_http_response *res = mtev_http_session_response(restc->http_ctx);
  mtev_lua_resume_rest_info_t *ctx = ri->context_data;

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

  mtev_http_rest_clean_request(restc);
  return 0;
}
static int
rest_show_filter(mtev_http_rest_closure_t *restc,
                 int npats, char **pats) {
  mtev_http_session_ctx *ctx = restc->http_ctx;
  xmlDocPtr doc = NULL;
  xmlNodePtr node, root;
  char xpath[1024];
  int error_code = 500;

  if(npats != 2) goto error;

  snprintf(xpath, sizeof(xpath), "//filtersets%sfilterset[@name=\"%s\"]",
           pats[0], pats[1]);

  node = mtev_conf_get_section(NULL, xpath);
  if(!node) goto not_found;

  doc = xmlNewDoc((xmlChar *)"1.0");
  root = xmlCopyNode(node, 1);
  xmlDocSetRootElement(doc, root);
  mtev_http_response_ok(ctx, "text/xml");
  mtev_http_response_xml(ctx, doc);
  mtev_http_response_end(ctx);
  goto cleanup;

 not_found:
  mtev_http_response_not_found(ctx, "text/html");
  mtev_http_response_end(ctx);
  goto cleanup;

 error:
  mtev_http_response_standard(ctx, error_code, "ERROR", "text/html");
  mtev_http_response_end(ctx);
  goto cleanup;

 cleanup:
  if(doc) xmlFreeDoc(doc);
  return 0;
}
static int
rest_delete_filter(mtev_http_rest_closure_t *restc,
                   int npats, char **pats) {
  mtev_http_session_ctx *ctx = restc->http_ctx;
  xmlNodePtr node;
  char xpath[1024];
  int error_code = 500;

  if(npats != 2) goto error;

  snprintf(xpath, sizeof(xpath), "//filtersets%sfilterset[@name=\"%s\"]",
           pats[0], pats[1]);
  node = mtev_conf_get_section(NULL, xpath);
  if(!node) goto not_found;
  if(noit_filter_remove(node) == 0) goto not_found;
  CONF_REMOVE(node);
  xmlUnlinkNode(node);
  xmlFreeNode(node);

  if(mtev_conf_write_file(NULL) != 0)
    mtevL(noit_error, "local config write failed\n");
  mtev_conf_mark_changed();
  mtev_http_response_ok(ctx, "text/html");
  mtev_http_response_end(ctx);
  goto cleanup;

 not_found:
  mtev_http_response_not_found(ctx, "text/html");
  mtev_http_response_end(ctx);
  goto cleanup;

 error:
  mtev_http_response_standard(ctx, error_code, "ERROR", "text/html");
  mtev_http_response_end(ctx);
  goto cleanup;

 cleanup:
  return 0;
}
Exemple #7
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;
}
static int
rest_set_filter(mtev_http_rest_closure_t *restc,
                int npats, char **pats) {
  mtev_http_session_ctx *ctx = restc->http_ctx;
  xmlDocPtr doc = NULL, indoc = NULL;
  xmlNodePtr node, parent, root, newfilter;
  char xpath[1024];
  int error_code = 500, complete = 0, mask = 0;
  const char *error = "internal error";

  if(npats != 2) goto error;

  indoc = rest_get_xml_upload(restc, &mask, &complete);
  if(!complete) return mask;
  if(indoc == NULL) FAIL("xml parse error");

  snprintf(xpath, sizeof(xpath), "//filtersets%sfilterset[@name=\"%s\"]",
           pats[0], pats[1]);
  node = mtev_conf_get_section(NULL, xpath);
  if(!node && noit_filter_exists(pats[1])) {
    /* It's someone else's */
    error_code = 403;
    goto error;
  }

  if((newfilter = validate_filter_post(indoc)) == NULL) goto error;
  xmlSetProp(newfilter, (xmlChar *)"name", (xmlChar *)pats[1]);

  parent = make_conf_path(pats[0]);
  if(!parent) FAIL("invalid path");
  if(node) {
    xmlUnlinkNode(node);
    xmlFreeNode(node);
  }
  xmlUnlinkNode(newfilter);
  xmlAddChild(parent, newfilter);
  CONF_DIRTY(newfilter);

  mtev_conf_mark_changed();
  if(mtev_conf_write_file(NULL) != 0)
    mtevL(noit_error, "local config write failed\n");
  noit_filter_compile_add(newfilter);
  if(restc->call_closure_free) restc->call_closure_free(restc->call_closure);
  restc->call_closure_free = NULL;
  restc->call_closure = NULL;
  restc->fastpath = rest_show_filter;
  return restc->fastpath(restc, restc->nparams, restc->params);

 error:
  mtev_http_response_standard(ctx, error_code, "ERROR", "text/html");
  doc = xmlNewDoc((xmlChar *)"1.0");
  root = xmlNewDocNode(doc, NULL, (xmlChar *)"error", NULL);
  xmlDocSetRootElement(doc, root);
  xmlNodeAddContent(root, (xmlChar *)error);
  mtev_http_response_xml(ctx, doc);
  mtev_http_response_end(ctx);
  goto cleanup;

 cleanup:
  if(doc) xmlFreeDoc(doc);
  return 0;
}
static int rest_add_feed(mtev_http_rest_closure_t *restc,
                         int npats, char **pats) {
  mtev_http_session_ctx *ctx = restc->http_ctx;
  xmlXPathObjectPtr pobj = NULL;
  xmlDocPtr doc = NULL, indoc = NULL;
  xmlNodePtr node, root;
  acceptor_closure_t *ac = restc->ac;
  int error_code = 500, complete = 0, mask = 0, rv;
  const char *error = "internal error", *logname;
  char *name, *copy_from;
  mtev_log_stream_t feed;
  const char *jpath_with_sub;
  char jlogpath[PATH_MAX], *cp;
  jlog_ctx *jctx = NULL;
  jlog_id chkpt;

  if(npats != 0) goto error;

  indoc = rest_get_xml_upload(restc, &mask, &complete);
  if(!complete) return mask;
  if(indoc == NULL) {
    error = "xml parse error";
    goto error;
  }
  if(!mtev_hash_retr_str(ac->config,
                         "log_transit_feed_name",
                         strlen("log_transit_feed_name"),
                         &logname)) {
    goto error;

  }
  feed = mtev_log_stream_find("feed");
  if(!feed) { 
    error = "couldn't find feed";
    goto error; 
  }

  jpath_with_sub = mtev_log_stream_get_path(feed);
  strlcpy(jlogpath, jpath_with_sub, sizeof(jlogpath));
  cp = strchr(jlogpath, '(');
  if(cp) *cp = '\0';

  node = xmlDocGetRootElement(indoc);
  name = (char*)xmlGetProp(node, (xmlChar*)"name");
  copy_from = (char*)xmlGetProp(node, (xmlChar*)"checkpoint_copy");

  jctx = jlog_new(jlogpath);
  if (!jctx) {
    error = "couldn't open logpath";
    goto error;
  }

  if (!jlog_get_checkpoint(jctx, name, &chkpt)) {
    error = "subscriber already exists, can't add";
    goto error;
  }

  if (copy_from) {
    rv = jlog_ctx_add_subscriber_copy_checkpoint(jctx, name, copy_from);
  }
  else {
    rv = jlog_ctx_add_subscriber(jctx, name, JLOG_END);
  }
  if (rv == -1) {
    error = "couldn't add subscriber";
    goto error;
  }

  mtev_http_response_ok(restc->http_ctx, "text/xml");
  mtev_http_response_end(restc->http_ctx);
  goto cleanup;

 error:
  mtev_http_response_standard(ctx, error_code, "ERROR", "text/xml");
  doc = xmlNewDoc((xmlChar *)"1.0");
  root = xmlNewDocNode(doc, NULL, (xmlChar *)"error", NULL);
  xmlDocSetRootElement(doc, root);
  xmlNodeAddContent(root, (xmlChar *)error);
  mtev_http_response_xml(ctx, doc);
  mtev_http_response_end(ctx);

 cleanup:
  if (jctx) {
    jlog_ctx_close(jctx);
  }
  if(pobj) xmlXPathFreeObject(pobj);
  if(doc) xmlFreeDoc(doc);
  return 0;
}