static void noit_lua_hash_to_table(lua_State *L, noit_hash_table *t) { noit_hash_iter iter = NOIT_HASH_ITER_ZERO; const char *key, *value; int klen; lua_createtable(L, 0, t ? t->size : 0); if(t) { while(noit_hash_next_str(t, &iter, &key, &klen, &value)) { lua_pushlstring(L, value, strlen(value)); lua_setfield(L, -2, key); } } return; }
static int configure_eventer() { int rv = 0; noit_hash_table *table; table = noit_conf_get_hash(NULL, "/" APPNAME "/eventer/config"); if(table) { noit_hash_iter iter = NOIT_HASH_ITER_ZERO; const char *key, *value; int klen; while(noit_hash_next_str(table, &iter, &key, &klen, &value)) { int subrv; if((subrv = eventer_propset(key, value)) != 0) rv = subrv; } noit_hash_destroy(table, free, free); free(table); } return rv; }
static int configure_eventer(const char *appname) { int rv = 0; noit_hash_table *table; char appscratch[1024]; snprintf(appscratch, sizeof(appscratch), "/%s/eventer/config", appname); table = noit_conf_get_hash(NULL, appscratch); if(table) { noit_hash_iter iter = NOIT_HASH_ITER_ZERO; const char *key, *value; int klen; while(noit_hash_next_str(table, &iter, &key, &klen, &value)) { int subrv; if((subrv = eventer_propset(key, value)) != 0) rv = subrv; } noit_hash_destroy(table, free, free); free(table); } return rv; }
static int external_invoke(noit_module_t *self, noit_check_t *check, noit_check_t *cause) { struct timeval when, p_int; external_closure_t *ecl; struct check_info *ci = (struct check_info *)check->closure; eventer_t newe; external_data_t *data; noit_hash_table check_attrs_hash = NOIT_HASH_EMPTY; int i, klen; noit_hash_iter iter = NOIT_HASH_ITER_ZERO; const char *name, *value; char interp_fmt[4096], interp_buff[4096]; data = noit_module_get_userdata(self); check->flags |= NP_RUNNING; noitL(data->nldeb, "external_invoke(%p,%s)\n", self, check->target); /* remove a timeout if we still have one -- we should unless someone * has set a lower timeout than the period. */ if(ci->timeout_event) { eventer_remove(ci->timeout_event); free(ci->timeout_event->closure); eventer_free(ci->timeout_event); ci->timeout_event = NULL; } check_info_clean(ci); gettimeofday(&when, NULL); memcpy(&check->last_fire_time, &when, sizeof(when)); /* Setup all our check bits */ ci->check_no = noit_atomic_inc64(&data->check_no_seq); ci->check = check; /* We might want to extract metrics */ if(noit_hash_retr_str(check->config, "output_extract", strlen("output_extract"), &value) != 0) { const char *error; int erroffset; ci->matcher = pcre_compile(value, 0, &error, &erroffset, NULL); if(!ci->matcher) { noitL(data->nlerr, "external pcre /%s/ failed @ %d: %s\n", value, erroffset, error); } } noit_check_make_attrs(check, &check_attrs_hash); /* Count the args */ i = 1; while(1) { char argname[10]; snprintf(argname, sizeof(argname), "arg%d", i); if(noit_hash_retr_str(check->config, argname, strlen(argname), &value) == 0) break; i++; } ci->argcnt = i + 1; /* path, arg0, (i-1 more args) */ ci->arglens = calloc(ci->argcnt, sizeof(*ci->arglens)); ci->args = calloc(ci->argcnt, sizeof(*ci->args)); /* Make the command */ if(noit_hash_retr_str(check->config, "command", strlen("command"), &value) == 0) { value = "/bin/true"; } ci->args[0] = strdup(value); ci->arglens[0] = strlen(ci->args[0]) + 1; i = 0; while(1) { char argname[10]; snprintf(argname, sizeof(argname), "arg%d", i); if(noit_hash_retr_str(check->config, argname, strlen(argname), &value) == 0) { if(i == 0) { /* if we don't have arg0, make it last element of path */ char *cp = ci->args[0] + strlen(ci->args[0]); while(cp > ci->args[0] && *(cp-1) != '/') cp--; value = cp; } else break; /* if we don't have argn, we're done */ } noit_check_interpolate(interp_buff, sizeof(interp_buff), value, &check_attrs_hash, check->config); ci->args[i+1] = strdup(interp_buff); ci->arglens[i+1] = strlen(ci->args[i+1]) + 1; i++; } /* Make the environment */ memset(&iter, 0, sizeof(iter)); ci->envcnt = 0; while(noit_hash_next_str(check->config, &iter, &name, &klen, &value)) if(!strncasecmp(name, "env_", 4)) ci->envcnt++; memset(&iter, 0, sizeof(iter)); ci->envlens = calloc(ci->envcnt, sizeof(*ci->envlens)); ci->envs = calloc(ci->envcnt, sizeof(*ci->envs)); ci->envcnt = 0; while(noit_hash_next_str(check->config, &iter, &name, &klen, &value)) if(!strncasecmp(name, "env_", 4)) { snprintf(interp_fmt, sizeof(interp_fmt), "%s=%s", name+4, value); noit_check_interpolate(interp_buff, sizeof(interp_buff), interp_fmt, &check_attrs_hash, check->config); ci->envs[ci->envcnt] = strdup(interp_buff); ci->envlens[ci->envcnt] = strlen(ci->envs[ci->envcnt]) + 1; ci->envcnt++; } noit_hash_destroy(&check_attrs_hash, NULL, NULL); noit_hash_store(&data->external_checks, (const char *)&ci->check_no, sizeof(ci->check_no), ci); /* Setup a timeout */ newe = eventer_alloc(); newe->mask = EVENTER_TIMER; gettimeofday(&when, NULL); p_int.tv_sec = check->timeout / 1000; p_int.tv_usec = (check->timeout % 1000) * 1000; add_timeval(when, p_int, &newe->whence); ecl = calloc(1, sizeof(*ecl)); ecl->self = self; ecl->check = check; newe->closure = ecl; newe->callback = external_timeout; eventer_add(newe); ci->timeout_event = newe; /* Setup push */ newe = eventer_alloc(); newe->mask = EVENTER_ASYNCH; add_timeval(when, p_int, &newe->whence); ecl = calloc(1, sizeof(*ecl)); ecl->self = self; ecl->check = check; newe->closure = ecl; newe->callback = external_enqueue; eventer_add(newe); 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; }