noit_boolean noit_http_rest_client_cert_auth(noit_http_rest_closure_t *restc, int npats, char **pats) { struct noit_rest_acl *acl; struct noit_rest_acl_rule *rule; noit_http_request *req = noit_http_session_request(restc->http_ctx); const char *uri_str; const char *remote_cn = ""; int ovector[30]; if(restc->remote_cn) remote_cn = restc->remote_cn; uri_str = noit_http_request_uri_str(req); for(acl = global_rest_acls; acl; acl = acl->next) { if(acl->cn && pcre_exec(acl->cn, NULL, remote_cn, 0, 0, 0, ovector, sizeof(ovector)/sizeof(*ovector)) <= 0) continue; if(acl->url && pcre_exec(acl->url, NULL, uri_str, strlen(uri_str), 0, 0, ovector, sizeof(ovector)/sizeof(*ovector)) <= 0) continue; for(rule = acl->rules; rule; rule = rule->next) { if(rule->cn && pcre_exec(rule->cn, NULL, remote_cn, 0, 0, 0, ovector, sizeof(ovector)/sizeof(*ovector)) <= 0) continue; if(rule->url && pcre_exec(rule->url, NULL, uri_str, strlen(uri_str), 0, 0, ovector, sizeof(ovector)/sizeof(*ovector)) <= 0) continue; return rule->allow; } return acl->allow; } return noit_false; }
static rest_request_handler noit_http_get_handler(noit_http_rest_closure_t *restc) { struct rule_container *cont = NULL; struct rest_url_dispatcher *rule; noit_http_request *req = noit_http_session_request(restc->http_ctx); const char *uri_str; const char *eoq, *eob; uri_str = noit_http_request_uri_str(req); eoq = strchr(uri_str, '?'); if(!eoq) eoq = uri_str + strlen(uri_str); eob = eoq - 1; /* find the right base */ while(1) { void *vcont; while(eob >= uri_str && *eob != '/') eob--; if(eob < uri_str) break; /* off the front */ if(noit_hash_retrieve(&dispatch_points, uri_str, eob - uri_str + 1, &vcont)) { cont = vcont; eob++; /* move past the determined base */ break; } eob--; } if(!cont) return NULL; for(rule = cont->rules; rule; rule = rule->next) { int ovector[30]; int cnt; if(strcmp(rule->method, noit_http_request_method_str(req))) continue; if((cnt = pcre_exec(rule->expression, rule->extra, eob, eoq - eob, 0, 0, ovector, sizeof(ovector)/sizeof(*ovector))) > 0) { /* We match, set 'er up */ restc->fastpath = rule->handler; restc->nparams = cnt - 1; if(restc->nparams) { restc->params = calloc(restc->nparams, sizeof(*restc->params)); for(cnt = 0; cnt < restc->nparams; cnt++) { int start = ovector[(cnt+1)*2]; int end = ovector[(cnt+1)*2+1]; restc->params[cnt] = malloc(end - start + 1); memcpy(restc->params[cnt], eob + start, end - start); restc->params[cnt][end - start] = '\0'; } } if(rule->auth && !rule->auth(restc, restc->nparams, restc->params)) return noit_http_rest_permission_denied; return restc->fastpath; } } return NULL; }
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; }
static int noit_lua_http_request_uri(lua_State *L) { CCALL_DECL(L, noit_http_request, req, 1); lua_pushstring(L, noit_http_request_uri_str(req)); return 1; }