Changeset 02569455fdf31dd93db18514b0b4cda5d5181ff7

Show
Ignore:
Timestamp:
09/13/09 14:43:17 (5 years ago)
Author:
Theo Schlossnagle <jesus@omniti.com>
git-committer:
Theo Schlossnagle <jesus@omniti.com> 1252852997 +0000
git-parent:

[57a2287f4d549439df74e04e133e5a4e40582d97]

git-author:
Theo Schlossnagle <jesus@omniti.com> 1252852997 +0000
Message:

work on #171, getting check info works

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • src/Makefile.in

    r2ea7724 r0256945  
    4141        noit_capabilities_listener.o noit_xml.o \ 
    4242        noit_jlog_listener.o noit_livestream_listener.o noit_filters.o \ 
    43         noit_http.o noit_rest.o 
     43        noit_http.o noit_rest.o noit_check_rest.o 
    4444 
    4545STRATCON_OBJS=stratcond.o noit_listener.o \ 
  • src/noit_check_tools.c

    r88a7178 r0256945  
    212212  noit_hash_destroy(attrs, NULL, NULL); 
    213213} 
     214 
     215int 
     216noit_check_xpath(char *xpath, int len, 
     217                 const char *base, const char *arg) { 
     218  uuid_t checkid; 
     219  int base_trailing_slash; 
     220  char argcopy[1024], *target, *module, *name; 
     221 
     222  base_trailing_slash = (base[strlen(base)-1] == '/'); 
     223  xpath[0] = '\0'; 
     224  argcopy[0] = '\0'; 
     225  if(arg) strlcpy(argcopy, arg, sizeof(argcopy)); 
     226 
     227  if(uuid_parse(argcopy, checkid) == 0) { 
     228    /* If they kill by uuid, we'll seek and destroy -- find it anywhere */ 
     229    snprintf(xpath, len, "/noit/checks%s%s/check[@uuid=\"%s\"]", 
     230             base, base_trailing_slash ? "" : "/", argcopy); 
     231  } 
     232  else if((module = strchr(argcopy, '`')) != NULL) { 
     233    noit_check_t *check; 
     234    char uuid_str[37]; 
     235    target = argcopy; 
     236    *module++ = '\0'; 
     237    if((name = strchr(module+1, '`')) == NULL) 
     238      name = module; 
     239    else 
     240      name++; 
     241    check = noit_poller_lookup_by_name(target, name); 
     242    if(!check) { 
     243      return -1; 
     244    } 
     245    uuid_unparse_lower(check->checkid, uuid_str); 
     246    snprintf(xpath, len, "/noit/checks%s%s/check[@uuid=\"%s\"]", 
     247             base, base_trailing_slash ? "" : "/", uuid_str); 
     248  } 
     249  return strlen(xpath); 
     250} 
  • src/noit_check_tools.h

    r88a7178 r0256945  
    7676API_EXPORT(void) 
    7777  noit_check_release_attrs(noit_hash_table *attrs); 
     78API_EXPORT(int) 
     79  noit_check_xpath(char *xpath, int len, 
     80                   const char *base, const char *arg); 
    7881 
    7982 
  • src/noit_conf_checks.c

    r88a7178 r0256945  
    4646#include "noit_conf_private.h" 
    4747#include "noit_check.h" 
     48#include "noit_check_tools.h" 
    4849#include "noit_filters.h" 
    4950#include "noit_console.h" 
     
    112113                           noit_conf_t_userdata_t *info, 
    113114                           const char *arg) { 
    114   uuid_t checkid; 
    115   char argcopy[1024], *target, *module, *name; 
    116  
    117   argcopy[0] = '\0'; 
    118   if(arg) strlcpy(argcopy, arg, sizeof(argcopy)); 
    119  
    120   if(uuid_parse(argcopy, checkid) == 0) { 
    121     /* If they kill by uuid, we'll seek and destroy -- find it anywhere */ 
    122     snprintf(xpath, len, "/noit/checks//check[@uuid=\"%s\"]", 
    123              argcopy); 
    124   } 
    125   else if((module = strchr(argcopy, '`')) != NULL) { 
    126     noit_check_t *check; 
    127     char uuid_str[37]; 
    128     target = argcopy; 
    129     *module++ = '\0'; 
    130     if((name = strchr(module+1, '`')) == NULL) 
    131       name = module; 
    132     else 
    133       name++; 
    134     check = noit_poller_lookup_by_name(target, name); 
    135     if(!check) { 
    136       return -1; 
    137     } 
    138     uuid_unparse_lower(check->checkid, uuid_str); 
    139     snprintf(xpath, len, "/noit/checks//check[@uuid=\"%s\"]", 
    140              uuid_str); 
    141   } 
    142   else { 
     115  int rv; 
     116  rv = noit_check_xpath(xpath, len, "/", arg); 
     117  if(rv == -1) return -1; 
     118  if(rv == 0) { 
    143119    char *path = (!info || !strcmp(info->path, "/")) ? "" : info->path; 
    144120    snprintf(xpath, len, "/noit%s%s%s[@uuid]", 
  • src/noit_http.c

    r6688159 r0256945  
    3939#include <assert.h> 
    4040#include <zlib.h> 
     41#include <libxml/tree.h> 
    4142 
    4243#define REQ_PAT "\r\n\r\n" 
     
    562563                        struct timeval *now) { 
    563564  noit_http_session_ctx *ctx = closure; 
    564   int rv
     565  int rv = 0
    565566  int mask = origmask; 
    566567 
     
    833834                                struct bchain *in) { 
    834835  struct bchain *out; 
    835   int ilen, maxlen, hexlen; 
     836  int ilen, maxlen = in->size, hexlen; 
    836837  int opts = ctx->res.output_options; 
    837838 
     
    945946  return noit_true; 
    946947} 
     948 
     949 
     950/* Helper functions */ 
     951 
     952static int 
     953noit_http_write_xml(void *vctx, const char *buffer, int len) { 
     954  if(noit_http_response_append((noit_http_session_ctx *)vctx, buffer, len)) 
     955    return len; 
     956  return -1; 
     957} 
     958static int 
     959noit_http_close_xml(void *vctx) { 
     960  noit_http_response_end((noit_http_session_ctx *)vctx); 
     961  return 0; 
     962} 
     963void 
     964noit_http_response_xml(noit_http_session_ctx *ctx, xmlDocPtr doc) { 
     965  xmlOutputBufferPtr out; 
     966  xmlCharEncodingHandlerPtr enc; 
     967  enc = xmlGetCharEncodingHandler(XML_CHAR_ENCODING_UTF8); 
     968  out = xmlOutputBufferCreateIO(noit_http_write_xml, 
     969                                noit_http_close_xml, 
     970                                ctx, enc); 
     971  xmlSaveFormatFileTo(out, doc, "utf8", 1); 
     972} 
     973 
  • src/noit_http.h

    r7e47bd8 r0256945  
    3535 
    3636#include "noit_defines.h" 
     37#include <libxml/tree.h> 
    3738#include "eventer/eventer.h" 
    3839#include "utils/noit_hash.h" 
     
    156157API_EXPORT(noit_boolean) noit_http_response_end(noit_http_session_ctx *); 
    157158 
     159#define noit_http_response_server_error(ctx, type) \ 
     160  noit_http_response_standard(ctx, 500, "ERROR", type) 
     161#define noit_http_response_ok(ctx, type) \ 
     162  noit_http_response_standard(ctx, 200, "OK", type) 
     163#define noit_http_response_not_found(ctx, type) \ 
     164  noit_http_response_standard(ctx, 404, "NOT FOUND", type) 
     165 
     166#define noit_http_response_standard(ctx, code, name, type) do { \ 
     167  noit_http_response_status_set(ctx, code, name); \ 
     168  noit_http_response_header_set(ctx, "Content-Type", type); \ 
     169  noit_http_response_option_set(ctx, NOIT_HTTP_CHUNKED); \ 
     170  noit_http_response_option_set(ctx, NOIT_HTTP_DEFLATE); \ 
     171} while(0) 
     172 
     173API_EXPORT(void) 
     174  noit_http_response_xml(noit_http_session_ctx *, xmlDocPtr); 
     175 
     176 
    158177#endif 
  • src/noit_rest.c

    r6688159 r0256945  
    3636#include "noit_rest.h" 
    3737 
     38#include <pcre.h> 
     39 
     40struct rest_url_dispatcher { 
     41  char *method; 
     42  pcre *expression; 
     43  pcre_extra *extra; 
     44  rest_request_handler handler; 
     45  /* Chain to the next one */ 
     46  struct rest_url_dispatcher *next; 
     47}; 
     48struct rule_container { 
     49  char *base; 
     50  struct rest_url_dispatcher *rules; 
     51  struct rest_url_dispatcher *rules_endptr; 
     52}; 
     53noit_hash_table dispatch_points = NOIT_HASH_EMPTY; 
     54 
     55static rest_request_handler 
     56noit_http_get_handler(noit_http_rest_closure_t *restc) { 
     57  struct rule_container *cont = NULL; 
     58  struct rest_url_dispatcher *rule; 
     59  char *eoq, *eob; 
     60  eoq = strchr(restc->http_ctx->req.uri_str, '?'); 
     61  if(!eoq) 
     62    eoq = restc->http_ctx->req.uri_str + strlen(restc->http_ctx->req.uri_str); 
     63  eob = eoq - 1; 
     64 
     65  /* find the right base */ 
     66  while(1) { 
     67    void *vcont; 
     68    while(eob >= restc->http_ctx->req.uri_str && *eob != '/') eob--; 
     69    if(eob < restc->http_ctx->req.uri_str) break; /* off the front */ 
     70    if(noit_hash_retrieve(&dispatch_points, restc->http_ctx->req.uri_str, 
     71                          eob - restc->http_ctx->req.uri_str + 1, &vcont)) { 
     72      cont = vcont; 
     73      eob++; /* move past the determined base */ 
     74      break; 
     75    } 
     76    eob--; 
     77  } 
     78  if(!cont) return NULL; 
     79  for(rule = cont->rules; rule; rule = rule->next) { 
     80    int ovector[30]; 
     81    int cnt; 
     82    if(strcmp(rule->method, restc->http_ctx->req.method_str)) continue; 
     83    if((cnt = pcre_exec(rule->expression, rule->extra, eob, eoq - eob, 0, 0, 
     84                        ovector, sizeof(ovector)/sizeof(*ovector))) > 0) { 
     85      /* We match, set 'er up */ 
     86      restc->fastpath = rule->handler; 
     87      restc->nparams = cnt - 1; 
     88      if(restc->nparams) { 
     89        restc->params = calloc(restc->nparams, sizeof(*restc->params)); 
     90        for(cnt = 0; cnt < restc->nparams; cnt++) { 
     91          int start = ovector[(cnt+1)*2]; 
     92          int end = ovector[(cnt+1)*2+1]; 
     93          restc->params[cnt] = malloc(end - start + 1); 
     94          memcpy(restc->params[cnt], eob + start, end - start); 
     95          restc->params[cnt][end - start] = '\0'; 
     96        } 
     97      } 
     98      return restc->fastpath; 
     99    } 
     100  } 
     101  return NULL; 
     102} 
     103int 
     104noit_http_rest_register(const char *method, const char *base, 
     105                        const char *expr, rest_request_handler f) { 
     106  void *vcont; 
     107  struct rule_container *cont; 
     108  struct rest_url_dispatcher *rule; 
     109  const char *error; 
     110  int erroffset; 
     111  pcre *pcre_expr; 
     112  int blen = strlen(base); 
     113  /* base must end in a /, 'cause I said so */ 
     114  if(blen == 0 || base[blen-1] != '/') return -1; 
     115  pcre_expr = pcre_compile(expr, 0, &error, &erroffset, NULL); 
     116  if(!pcre_expr) { 
     117    noitL(noit_error, "Error in rest expr(%s) '%s'@%d: %s\n", 
     118          base, expr, erroffset, error); 
     119    return -1; 
     120  } 
     121  rule = calloc(1, sizeof(*rule)); 
     122  rule->method = strdup(method); 
     123  rule->expression = pcre_expr; 
     124  rule->extra = pcre_study(rule->expression, 0, &error); 
     125  rule->handler = f; 
     126 
     127  /* Make sure we have a container */ 
     128  if(!noit_hash_retrieve(&dispatch_points, base, strlen(base), &vcont)) { 
     129    cont = calloc(1, sizeof(*cont)); 
     130    cont->base = strdup(base); 
     131    noit_hash_store(&dispatch_points, cont->base, strlen(cont->base), cont); 
     132  } 
     133  else cont = vcont; 
     134 
     135  /* Append the rule */ 
     136  if(cont->rules_endptr) { 
     137    cont->rules_endptr->next = rule; 
     138    cont->rules_endptr = cont->rules_endptr->next; 
     139  } 
     140  else 
     141    cont->rules = cont->rules_endptr = rule; 
     142  return 0; 
     143} 
     144 
    38145static noit_http_rest_closure_t * 
    39146noit_http_rest_closure_alloc() { 
     
    43150} 
    44151static void 
     152noit_http_rest_clean_request(noit_http_rest_closure_t *restc) { 
     153  int i; 
     154  if(restc->nparams) { 
     155    for(i=0;i<restc->nparams;i++) free(restc->params[i]); 
     156    free(restc->params); 
     157  } 
     158  restc->nparams = 0; 
     159  restc->params = NULL; 
     160  restc->fastpath = NULL; 
     161} 
     162static void 
    45163noit_http_rest_closure_free(noit_http_rest_closure_t *restc) { 
     164  free(restc->remote_cn); 
     165   noit_http_rest_clean_request(restc); 
    46166  free(restc); 
    47167} 
     
    49169int 
    50170noit_rest_request_dispatcher(noit_http_session_ctx *ctx) { 
    51   noit_http_response_status_set(ctx, 200, "OK"); 
    52   noit_http_response_header_set(ctx, "Content-Type", "application/json"); 
     171  noit_http_rest_closure_t *restc = ctx->dispatcher_closure; 
     172  rest_request_handler handler = restc->fastpath; 
     173  if(!handler) handler = noit_http_get_handler(restc); 
     174  if(handler) { 
     175    int rv; 
     176    rv = handler(restc, restc->nparams, restc->params); 
     177    if(ctx->res.closed) noit_http_rest_clean_request(restc); 
     178    return rv; 
     179  } 
     180  noit_http_response_status_set(ctx, 404, "NOT FOUND"); 
    53181  noit_http_response_option_set(ctx, NOIT_HTTP_CHUNKED); 
    54   noit_http_response_option_set(ctx, NOIT_HTTP_DEFLATE); 
    55   noit_http_response_append(ctx, "{error: 'Foo'}", 14); 
    56   noit_http_response_flush(ctx, noit_false); 
     182  noit_http_rest_clean_request(restc); 
    57183  noit_http_response_end(ctx); 
    58184  return 0; 
     
    79205    const char *primer = ""; 
    80206    ac->service_ctx = restc = noit_http_rest_closure_alloc(); 
     207    restc->remote_cn = strdup(ac->remote_cn ? ac->remote_cn : ""); 
    81208    restc->http_ctx = 
    82209        noit_http_session_ctx_new(noit_rest_request_dispatcher, 
  • src/noit_rest.h

    r7e47bd8 r0256945  
    4242#define NOIT_CONTROL_POST 0x504f5354 
    4343 
    44 typedef struct { 
     44typedef struct noit_http_rest_closure noit_http_rest_closure_t; 
     45 
     46typedef int (*rest_request_handler)(noit_http_rest_closure_t *, 
     47                                    int npats, char **pats); 
     48 
     49struct noit_http_rest_closure { 
    4550  noit_http_session_ctx *http_ctx; 
     51  char *remote_cn; 
     52  rest_request_handler fastpath; 
     53  int nparams; 
     54  char **params; 
    4655  int wants_shutdown; 
    47 } noit_http_rest_closure_t
     56}
    4857 
    4958API_EXPORT(void) noit_http_rest_init(); 
    5059 
     60API_EXPORT(int) 
     61  noit_http_rest_register(const char *method, const char *base, 
     62                          const char *expression, rest_request_handler f); 
     63 
    5164#endif 
  • src/noitd.c

    r7e47bd8 r0256945  
    5353#include "noit_jlog_listener.h" 
    5454#include "noit_rest.h" 
     55#include "noit_check_rest.h" 
    5556#include "noit_livestream_listener.h" 
    5657#include "noit_capabilities_listener.h" 
     
    183184  noit_jlog_listener_init(); 
    184185  noit_http_rest_init(); 
     186  noit_check_rest_init(); 
    185187  noit_livestream_listener_init(); 
    186188