static int rest_get_noit_config(noit_http_rest_closure_t *restc, int npats, char **pats) { noit_http_session_ctx *ctx = restc->http_ctx; char *xml = NULL; if(npats != 0) { noit_http_response_server_error(ctx, "text/xml"); noit_http_response_end(ctx); return 0; } xml = ingestor->get_noit_config(restc->remote_cn); if(xml == NULL) { char buff[1024]; snprintf(buff, sizeof(buff), "<error><remote_cn>%s</remote_cn>" "<row_count>%d</row_count></error>\n", restc->remote_cn, 0); noit_http_response_append(ctx, buff, strlen(buff)); noit_http_response_not_found(ctx, "text/xml"); } else { noit_http_response_append(ctx, xml, strlen(xml)); noit_http_response_ok(ctx, "text/xml"); } if(xml) free(xml); noit_http_response_end(ctx); return 0; }
static int noit_rest_eventer_sockets(noit_http_rest_closure_t *restc, int n, char **p) { const char *jsonstr; struct json_object *doc; doc = json_object_new_array(); eventer_foreach_fdevent(json_spit_event, doc); noit_http_response_ok(restc->http_ctx, "application/json"); jsonstr = json_object_to_json_string(doc); noit_http_response_append(restc->http_ctx, jsonstr, strlen(jsonstr)); noit_http_response_append(restc->http_ctx, "\n", 1); json_object_put(doc); noit_http_response_end(restc->http_ctx); return 0; }
static int noit_rest_eventer_jobq(noit_http_rest_closure_t *restc, int n, char **p) { const char *jsonstr; struct json_object *doc; doc = json_object_new_object(); eventer_jobq_process_each(json_spit_jobq, doc); noit_http_response_ok(restc->http_ctx, "application/json"); jsonstr = json_object_to_json_string(doc); noit_http_response_append(restc->http_ctx, jsonstr, strlen(jsonstr)); noit_http_response_append(restc->http_ctx, "\n", 1); json_object_put(doc); noit_http_response_end(restc->http_ctx); return 0; }
static int stratcon_ingest_launch_file_ingestion(const char *path, const char *remote_str, const char *remote_cn, const char *id_str) { char msg[PATH_MAX + 7], hfile[PATH_MAX]; /*file:\r\n*/ if(strcmp(path + strlen(path) - 2, ".h")) { snprintf(hfile, sizeof(hfile), "%s.h", path); if(link(path, hfile) < 0 && errno != EEXIST) { noitL(noit_error, "cannot link journal %s: %s\n", path, strerror(errno)); return -1; } } else strlcpy(hfile, path, sizeof(hfile)); noitL(noit_debug, " handoff -> %s\n", hfile); pthread_mutex_lock(&http_ctx_lock); if(the_one_and_only) { noit_http_session_ctx *ctx = the_one_and_only; snprintf(msg, sizeof(msg), "file:%s\r\n", hfile); if(noit_http_response_append(ctx,msg,strlen(msg)) == noit_false || noit_http_response_flush(ctx, noit_false) == noit_false) { noitL(noit_error, "handoff endpoint disconnected\n"); the_one_and_only = NULL; } } pthread_mutex_unlock(&http_ctx_lock); return 0; }
int noit_rest_eventer_logs(noit_http_rest_closure_t *restc, int n, char **p) { char *endptr = NULL; const char *since_s, *last_s; const char *jsonstr; char errbuf[128]; unsigned long long since; int last = 0; struct json_object *doc; noit_log_stream_t ls; noit_http_request *req = noit_http_session_request(restc->http_ctx); since_s = noit_http_request_querystring(req, "since"); if(since_s) since = strtoull(since_s, &endptr, 10); last_s = noit_http_request_querystring(req, "last"); if(last_s) last = atoi(last_s); assert(n==1); ls = noit_log_stream_find(p[0]); if(!ls || strcmp(noit_log_stream_get_type(ls),"memory")) goto not_found; doc = json_object_new_array(); if(endptr != since_s) noit_log_memory_lines_since(ls, since, json_spit_log, doc); else noit_log_memory_lines(ls, last, json_spit_log, doc); noit_http_response_ok(restc->http_ctx, "application/json"); jsonstr = json_object_to_json_string(doc); noit_http_response_append(restc->http_ctx, jsonstr, strlen(jsonstr)); noit_http_response_append(restc->http_ctx, "\n", 1); json_object_put(doc); noit_http_response_end(restc->http_ctx); return 0; not_found: doc = json_object_new_object(); snprintf(errbuf, sizeof(errbuf), "log '%s' not found", p[0]); json_object_object_add(doc, "error", json_object_new_string(errbuf)); jsonstr = json_object_to_json_string(doc); noit_http_response_not_found(restc->http_ctx, "application/json"); noit_http_response_append(restc->http_ctx, jsonstr, strlen(jsonstr)); noit_http_response_append(restc->http_ctx, "\n", 1); json_object_put(doc); noit_http_response_end(restc->http_ctx); return 0; }
static int handoff_request_dispatcher(noit_http_session_ctx *ctx) { char *hello = "message:hello\r\n"; if(the_one_and_only) { hello = "message:already connected\r\n"; noit_http_response_server_error(ctx, "text/plain"); noit_http_response_append(ctx, hello, strlen(hello)); noit_http_response_end(ctx); return 0; } the_one_and_only = ctx; noit_http_response_status_set(ctx, 200, "OK"); noit_http_response_option_set(ctx, NOIT_HTTP_CHUNKED); noit_http_response_header_set(ctx, "Content-Type", "text/plain"); noit_http_response_append(ctx, hello, strlen(hello)); noit_http_response_flush(ctx, noit_false); return EVENTER_EXCEPTION; }
static int rest_show_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, **subs = NULL; int nsubs, i; noit_log_stream_t feed; jlog_ctx *jctx = NULL; xmlDocPtr doc = NULL; xmlNodePtr root = NULL, subnodes; 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); if((nsubs = jlog_ctx_list_subscribers(jctx, &subs)) == -1) { err = jlog_ctx_err_string(jctx); goto error; } doc = xmlNewDoc((xmlChar *)"1.0"); root = xmlNewDocNode(doc, NULL, (xmlChar *)"feed", NULL); xmlDocSetRootElement(doc, root); subnodes = xmlNewNode(NULL, (xmlChar *)"subscribers"); for(i=0; i<nsubs; i++) { xmlNewChild(subnodes, NULL, (xmlChar *)"subscriber", (xmlChar *)subs[i]); } xmlAddChild(root, subnodes); noit_http_response_ok(restc->http_ctx, "text/xml"); noit_http_response_xml(restc->http_ctx, doc); noit_http_response_end(restc->http_ctx); if(subs) jlog_ctx_list_subscribers_dispose(jctx, subs); xmlFreeDoc(doc); jlog_ctx_close(jctx); return 0; error: if(doc) xmlFreeDoc(doc); if(subs) jlog_ctx_list_subscribers_dispose(jctx, subs); noit_http_response_server_error(ctx, "text/plain"); noit_http_response_append(ctx, err, strlen(err)); noit_http_response_end(ctx); if(jctx) jlog_ctx_close(jctx); return 0; }
static int noit_lua_http_write(lua_State *L) { noit_boolean status = noit_false; size_t inlen; const char *message; CCALL_DECL(L, noit_http_session_ctx, http_ctx, 2); message = lua_tolstring(L, 2, &inlen); if(message) status = noit_http_response_append(http_ctx, message, inlen); lua_pushboolean(L, status); return 1; }
static void stratcon_ingest_launch_file_ingestion(const char *path, const char *remote_str, const char *remote_cn, const char *id_str) { char msg[PATH_MAX + 7]; /*file:\r\n*/ noitL(noit_error, " handoff -> %s\n", path); if(the_one_and_only) { noit_http_session_ctx *ctx = the_one_and_only; snprintf(msg, sizeof(msg), "file:%s\r\n", path); if(noit_http_response_append(ctx,msg,strlen(msg)) == noit_false || noit_http_response_flush(ctx, noit_false) == noit_false) { noitL(noit_error, "handoff endpoint disconnected\n"); the_one_and_only = NULL; } } }
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 noit_capabilities_rest(noit_http_rest_closure_t *restc, int n, char **p) { noit_capsvc_closure_t cl = { 0 }; const char *mtype = "application/xml"; if(n > 0 && !strcmp(p[0], ".json")) { noit_capabilities_tobuff_json(&cl, NULL); mtype = "application/json"; } else noit_capabilities_tobuff(&cl, NULL); if(!cl.buff) goto error; noit_http_response_ok(restc->http_ctx, mtype); noit_http_response_append(restc->http_ctx, cl.buff, cl.towrite); noit_http_response_end(restc->http_ctx); free(cl.buff); return 0; error: noit_http_response_server_error(restc->http_ctx, "text/html"); noit_http_response_end(restc->http_ctx); return 0; }
int stratcon_request_dispatcher(noit_http_session_ctx *ctx) { const char *key, *value; realtime_context *rc = noit_http_session_dispatcher_closure(ctx); int klen; noit_hash_iter iter = NOIT_HASH_ITER_ZERO; noit_http_request *req = noit_http_session_request(ctx); if(rc->setup == RC_INITIAL) { eventer_t completion; struct realtime_tracker *node; char c[1024]; int num_interests; const char *uri_str = noit_http_request_uri_str(req); noit_hash_table *headers = noit_http_request_headers_table(req); num_interests = stratcon_realtime_uri_parse(rc, uri_str); if(num_interests == 0) { noit_http_response_status_set(ctx, 404, "OK"); noit_http_response_option_set(ctx, NOIT_HTTP_CLOSE); noit_http_response_end(ctx); return 0; } noitL(noit_error, "http: %s %s %s\n", noit_http_request_method_str(req), uri_str, noit_http_request_protocol_str(req)); while(noit_hash_next_str(headers, &iter, &key, &klen, &value)) { noitL(noit_error, "http: [%s: %s]\n", key, value); } noit_http_response_status_set(ctx, 200, "OK"); noit_http_response_option_set(ctx, NOIT_HTTP_CHUNKED); /*noit_http_response_option_set(ctx, NOIT_HTTP_GZIP);*/ /*noit_http_response_option_set(ctx, NOIT_HTTP_DEFLATE);*/ noit_http_response_header_set(ctx, "Content-Type", "text/html"); snprintf(c, sizeof(c), "<html><head><script>document.domain='%s';</script></head><body>\n", rc->document_domain); noit_http_response_append(ctx, c, strlen(c)); /* this dumb crap is to make some browsers happy (Safari) */ memset(c, ' ', sizeof(c)); noit_http_response_append(ctx, c, sizeof(c)); noit_http_response_flush(ctx, noit_false); rc->setup = RC_REQ_RECV; /* Each interest references the ctx */ for(node = rc->checklist; node; node = node->next) { char uuid_str[UUID_STR_LEN+1]; noit_http_session_ref_inc(ctx); uuid_unparse_lower(node->checkid, uuid_str); noitL(noit_error, "Resolving uuid: %s\n", uuid_str); } completion = eventer_alloc(); completion->mask = EVENTER_TIMER; completion->callback = stratcon_realtime_http_postresolve; completion->closure = ctx; gettimeofday(&completion->whence, NULL); stratcon_datastore_push(DS_OP_FIND_COMPLETE, NULL, NULL, rc->checklist, completion); } return EVENTER_EXCEPTION; }
int noit_rest_simple_file_handler(noit_http_rest_closure_t *restc, int npats, char **pats) { int drlen = 0; const char *document_root = NULL; const char *index_file = NULL; noit_http_session_ctx *ctx = restc->http_ctx; char file[PATH_MAX], rfile[PATH_MAX]; struct stat st; int fd; void *contents = MAP_FAILED; const char *dot = NULL, *slash; const char *content_type = "application/octet-stream"; if(npats != 1 || !noit_hash_retr_str(restc->ac->config, "document_root", strlen("document_root"), &document_root)) { goto not_found; } if(!noit_hash_retr_str(restc->ac->config, "index_file", strlen("index_file"), &index_file)) { index_file = "index.html"; } drlen = strlen(document_root); snprintf(file, sizeof(file), "%s/%s", document_root, pats[0]); if(file[strlen(file) - 1] == '/') { snprintf(file + strlen(file), sizeof(file) - strlen(file), "%s", index_file); } /* resolve */ if(realpath(file, rfile) == NULL) goto not_found; /* restrict */ if(strncmp(rfile, document_root, drlen)) goto denied; if(rfile[drlen] != '/' && rfile[drlen + 1] != '/') goto denied; /* stat */ /* coverity[fs_check_call] */ if(stat(rfile, &st) != 0) { switch (errno) { case EACCES: goto denied; default: goto not_found; } } /* open */ if(st.st_size > 0) { /* coverity[toctou] */ fd = open(rfile, O_RDONLY); if(fd < 0) goto not_found; contents = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0); close(fd); if(contents == MAP_FAILED) goto not_found; } /* set content type */ slash = strchr(rfile, '/'); while(slash) { const char *nslash = strchr(slash+1, '/'); if(!nslash) break; slash = nslash; } if(slash) dot = strchr(slash+1, '.'); while(dot) { const char *ndot = strchr(dot+1, '.'); if(!ndot) break; dot = ndot; } /* If there is no extention, just use the filename */ if(!dot) dot = slash+1; if(dot) { char ext[PATH_MAX]; strlcpy(ext, "mime_type_", sizeof(ext)); strlcpy(ext+strlen(ext), dot+1, sizeof(ext)-strlen(ext)); if(!noit_hash_retr_str(restc->ac->config, ext, strlen(ext), &content_type)) { if(!noit_hash_retr_str(&mime_type_defaults, dot+1, strlen(dot+1), &content_type)) { content_type = "application/octet-stream"; } } } noit_http_response_ok(ctx, content_type); if(st.st_size > 0) { noit_http_response_append(ctx, contents, st.st_size); munmap(contents, st.st_size); } noit_http_response_end(ctx); return 0; denied: noit_http_response_denied(ctx, "text/html"); noit_http_response_end(ctx); return 0; not_found: noit_http_response_not_found(ctx, "text/html"); noit_http_response_end(ctx); return 0; }
int noit_rest_simple_file_handler(noit_http_rest_closure_t *restc, int npats, char **pats) { int drlen = 0; const char *document_root = NULL; const char *index_file = NULL; noit_http_session_ctx *ctx = restc->http_ctx; char file[PATH_MAX], rfile[PATH_MAX]; struct stat st; int fd; void *contents = MAP_FAILED; if(npats != 1 || !noit_hash_retr_str(restc->ac->config, "document_root", strlen("document_root"), &document_root)) { goto not_found; } if(!noit_hash_retr_str(restc->ac->config, "index_file", strlen("index_file"), &index_file)) { index_file = "index.html"; } drlen = strlen(document_root); snprintf(file, sizeof(file), "%s/%s", document_root, pats[0]); if(file[strlen(file) - 1] == '/') { snprintf(file + strlen(file), sizeof(file) - strlen(file), "%s", index_file); } /* resolve */ if(realpath(file, rfile) == NULL) goto not_found; /* restrict */ if(strncmp(rfile, document_root, drlen)) goto denied; if(rfile[drlen] != '/' && rfile[drlen + 1] != '/') goto denied; /* stat */ if(stat(rfile, &st) != 0) { switch (errno) { case EACCES: goto denied; default: goto not_found; } } /* open */ if(st.st_size > 0) { fd = open(rfile, O_RDONLY); if(fd < 0) goto not_found; contents = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0); close(fd); if(contents == MAP_FAILED) goto not_found; } noit_http_response_ok(ctx, "text/html"); if(st.st_size > 0) { noit_http_response_append(ctx, contents, st.st_size); munmap(contents, st.st_size); } noit_http_response_end(ctx); return 0; denied: noit_http_response_denied(ctx, "text/html"); noit_http_response_end(ctx); return 0; not_found: noit_http_response_not_found(ctx, "text/html"); noit_http_response_end(ctx); return 0; }