static int noit_http_rest_permission_denied(noit_http_rest_closure_t *restc, int npats, char **pats) { noit_http_session_ctx *ctx = restc->http_ctx; noit_http_response_standard(ctx, 403, "DENIED", "text/xml"); noit_http_response_end(ctx); return 0; }
static int rest_test_check_err(noit_http_rest_closure_t *restc, int npats, char **pats) { noit_http_response *res = noit_http_session_response(restc->http_ctx); noit_skiplist_remove(&in_progress, restc, (noit_freefunc_t)rest_test_check_result); if(noit_http_response_complete(res) != noit_true) { noit_http_response_standard(restc->http_ctx, 500, "ERROR", "text/html"); noit_http_response_end(restc->http_ctx); } return 0; }
static int rest_test_check(noit_http_rest_closure_t *restc, int npats, char **pats) { noit_check_t *tcheck; noit_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)); cl->check = tcheck; cl->restc = restc; noit_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: noit_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); noit_http_response_xml(ctx, doc); noit_http_response_end(ctx); goto cleanup; cleanup: if(doc) xmlFreeDoc(doc); return 0; }
static int rest_delete_feed(noit_http_rest_closure_t *restc, int npats, char **pats) { noit_http_session_ctx *ctx = restc->http_ctx; const char *err = "unknown error"; const char *jpath_with_sub; char jlogpath[PATH_MAX], *cp; int rv; noit_log_stream_t feed; jlog_ctx *jctx; feed = noit_log_stream_find("feed"); if(!feed) { err = "cannot find feed"; goto error; } jpath_with_sub = noit_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) { noit_http_response_not_found(ctx, "text/plain"); noit_http_response_end(ctx); return 0; } noit_http_response_standard(ctx, 204, "OK", "text/plain"); noit_http_response_end(ctx); return 0; error: noit_http_response_server_error(ctx, "text/plain"); noit_http_response_append(ctx, err, strlen(err)); noit_http_response_end(ctx); return 0; }
static int rest_show_filter(noit_http_rest_closure_t *restc, int npats, char **pats) { noit_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 = noit_conf_get_section(NULL, xpath); if(!node) goto not_found; doc = xmlNewDoc((xmlChar *)"1.0"); root = xmlCopyNode(node, 1); xmlDocSetRootElement(doc, root); noit_http_response_ok(ctx, "text/xml"); noit_http_response_xml(ctx, doc); noit_http_response_end(ctx); goto cleanup; not_found: noit_http_response_not_found(ctx, "text/html"); noit_http_response_end(ctx); goto cleanup; error: noit_http_response_standard(ctx, error_code, "ERROR", "text/html"); noit_http_response_end(ctx); goto cleanup; cleanup: if(doc) xmlFreeDoc(doc); return 0; }
static int rest_delete_filter(noit_http_rest_closure_t *restc, int npats, char **pats) { noit_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 = noit_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(noit_conf_write_file(NULL) != 0) noitL(noit_error, "local config write failed\n"); noit_conf_mark_changed(); noit_http_response_ok(ctx, "text/html"); noit_http_response_end(ctx); goto cleanup; not_found: noit_http_response_not_found(ctx, "text/html"); noit_http_response_end(ctx); goto cleanup; error: noit_http_response_standard(ctx, error_code, "ERROR", "text/html"); noit_http_response_end(ctx); goto cleanup; cleanup: return 0; }
static int rest_set_filter(noit_http_rest_closure_t *restc, int npats, char **pats) { noit_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 = noit_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); noit_conf_mark_changed(); if(noit_conf_write_file(NULL) != 0) noitL(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: noit_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); noit_http_response_xml(ctx, doc); noit_http_response_end(ctx); goto cleanup; cleanup: if(doc) xmlFreeDoc(doc); return 0; }
static int rest_show_check(noit_http_rest_closure_t *restc, int npats, char **pats) { noit_http_session_ctx *ctx = restc->http_ctx; xmlXPathObjectPtr pobj = NULL; xmlXPathContextPtr xpath_ctxt = NULL; xmlDocPtr doc = NULL; xmlNodePtr node, root, attr, config, state, tmp, anode; uuid_t checkid; noit_check_t *check; char xpath[1024], *uuid_conf, *module, *value; int rv, cnt, error_code = 500; noit_hash_iter iter = NOIT_HASH_ITER_ZERO; const char *k; int klen; void *data; noit_hash_table *configh; if(npats != 2) goto error; rv = noit_check_xpath(xpath, sizeof(xpath), pats[0], pats[1]); if(rv == 0) goto not_found; if(rv < 0) goto error; noit_conf_xml_xpath(NULL, &xpath_ctxt); pobj = xmlXPathEval((xmlChar *)xpath, xpath_ctxt); if(!pobj || pobj->type != XPATH_NODESET || xmlXPathNodeSetIsEmpty(pobj->nodesetval)) goto not_found; cnt = xmlXPathNodeSetGetLength(pobj->nodesetval); if(cnt != 1) goto error; node = (noit_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, 0); uuid_conf = (char *)xmlGetProp(node, (xmlChar *)"uuid"); if(!uuid_conf || uuid_parse(uuid_conf, checkid)) goto error; doc = xmlNewDoc((xmlChar *)"1.0"); root = xmlNewDocNode(doc, NULL, (xmlChar *)"check", NULL); xmlDocSetRootElement(doc, root); #define MYATTR(node,a,n,b) _noit_conf_get_string(node, &(n), "@" #a, &(b)) #define INHERIT(node,a,n,b) \ _noit_conf_get_string(node, &(n), "ancestor-or-self::node()/@" #a, &(b)) #define SHOW_ATTR(parent, node, a) do { \ xmlNodePtr anode = NULL; \ char *value = NULL; \ INHERIT(node, a, anode, value); \ if(value != NULL) { \ int clen, plen;\ const char *cpath, *apath; \ xmlNodePtr child; \ cpath = node ? (char *)xmlGetNodePath(node) : ""; \ apath = anode ? (char *)xmlGetNodePath(anode) : ""; \ clen = strlen(cpath); \ plen = strlen("/noit/checks"); \ child = xmlNewNode(NULL, (xmlChar *)#a); \ xmlNodeAddContent(child, (xmlChar *)value); \ if(!strncmp(cpath, apath, clen) && apath[clen] == '/') { \ } \ else { \ xmlSetProp(child, (xmlChar *)"inherited", (xmlChar *)apath+plen); \ } \ xmlAddChild(parent, child); \ } \ } while(0) attr = xmlNewNode(NULL, (xmlChar *)"attributes"); xmlAddChild(root, attr); SHOW_ATTR(attr,node,uuid); /* Name is odd, it falls back transparently to module */ if(!INHERIT(node, module, tmp, module)) module = NULL; xmlAddChild(attr, (tmp = xmlNewNode(NULL, (xmlChar *)"name"))); if(MYATTR(node, name, anode, value)) xmlNodeAddContent(tmp, (xmlChar *)value); else if(module) xmlNodeAddContent(tmp, (xmlChar *)module); SHOW_ATTR(attr,node,module); SHOW_ATTR(attr,node,target); SHOW_ATTR(attr,node,period); SHOW_ATTR(attr,node,timeout); SHOW_ATTR(attr,node,oncheck); SHOW_ATTR(attr,node,filterset); SHOW_ATTR(attr,node,disable); /* Add the config */ config = xmlNewNode(NULL, (xmlChar *)"config"); configh = noit_conf_get_hash(node, "config"); while(noit_hash_next(configh, &iter, &k, &klen, &data)) NODE_CONTENT(config, k, data); noit_hash_destroy(configh, free, free); free(configh); xmlAddChild(root, config); /* Add the state */ check = noit_poller_lookup(checkid); if(!check) { state = xmlNewNode(NULL, (xmlChar *)"state"); xmlSetProp(state, (xmlChar *)"error", (xmlChar *)"true"); } else state = noit_check_state_as_xml(check); xmlAddChild(root, state); noit_http_response_ok(ctx, "text/xml"); noit_http_response_xml(ctx, doc); noit_http_response_end(ctx); goto cleanup; not_found: noit_http_response_not_found(ctx, "text/html"); noit_http_response_end(ctx); goto cleanup; error: noit_http_response_standard(ctx, error_code, "ERROR", "text/html"); noit_http_response_end(ctx); goto cleanup; cleanup: if(pobj) xmlXPathFreeObject(pobj); if(doc) xmlFreeDoc(doc); return 0; }