예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #4
0
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;
}