Changeset 02569455fdf31dd93db18514b0b4cda5d5181ff7
- Timestamp:
- 09/13/09 14:43:17 (4 years ago)
- git-parent:
- Files:
-
- src/Makefile.in (modified) (1 diff)
- src/noit_check_rest.c (added)
- src/noit_check_rest.h (added)
- src/noit_check_tools.c (modified) (1 diff)
- src/noit_check_tools.h (modified) (1 diff)
- src/noit_conf_checks.c (modified) (2 diffs)
- src/noit_http.c (modified) (4 diffs)
- src/noit_http.h (modified) (2 diffs)
- src/noit_rest.c (modified) (4 diffs)
- src/noit_rest.h (modified) (1 diff)
- src/noitd.c (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
src/Makefile.in
r2ea7724 r0256945 41 41 noit_capabilities_listener.o noit_xml.o \ 42 42 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 44 44 45 45 STRATCON_OBJS=stratcond.o noit_listener.o \ src/noit_check_tools.c
r88a7178 r0256945 212 212 noit_hash_destroy(attrs, NULL, NULL); 213 213 } 214 215 int 216 noit_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 76 76 API_EXPORT(void) 77 77 noit_check_release_attrs(noit_hash_table *attrs); 78 API_EXPORT(int) 79 noit_check_xpath(char *xpath, int len, 80 const char *base, const char *arg); 78 81 79 82 src/noit_conf_checks.c
r88a7178 r0256945 46 46 #include "noit_conf_private.h" 47 47 #include "noit_check.h" 48 #include "noit_check_tools.h" 48 49 #include "noit_filters.h" 49 50 #include "noit_console.h" … … 112 113 noit_conf_t_userdata_t *info, 113 114 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) { 143 119 char *path = (!info || !strcmp(info->path, "/")) ? "" : info->path; 144 120 snprintf(xpath, len, "/noit%s%s%s[@uuid]", src/noit_http.c
r6688159 r0256945 39 39 #include <assert.h> 40 40 #include <zlib.h> 41 #include <libxml/tree.h> 41 42 42 43 #define REQ_PAT "\r\n\r\n" … … 562 563 struct timeval *now) { 563 564 noit_http_session_ctx *ctx = closure; 564 int rv ;565 int rv = 0; 565 566 int mask = origmask; 566 567 … … 833 834 struct bchain *in) { 834 835 struct bchain *out; 835 int ilen, maxlen , hexlen;836 int ilen, maxlen = in->size, hexlen; 836 837 int opts = ctx->res.output_options; 837 838 … … 945 946 return noit_true; 946 947 } 948 949 950 /* Helper functions */ 951 952 static int 953 noit_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 } 958 static int 959 noit_http_close_xml(void *vctx) { 960 noit_http_response_end((noit_http_session_ctx *)vctx); 961 return 0; 962 } 963 void 964 noit_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 35 35 36 36 #include "noit_defines.h" 37 #include <libxml/tree.h> 37 38 #include "eventer/eventer.h" 38 39 #include "utils/noit_hash.h" … … 156 157 API_EXPORT(noit_boolean) noit_http_response_end(noit_http_session_ctx *); 157 158 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 173 API_EXPORT(void) 174 noit_http_response_xml(noit_http_session_ctx *, xmlDocPtr); 175 176 158 177 #endif src/noit_rest.c
r6688159 r0256945 36 36 #include "noit_rest.h" 37 37 38 #include <pcre.h> 39 40 struct 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 }; 48 struct rule_container { 49 char *base; 50 struct rest_url_dispatcher *rules; 51 struct rest_url_dispatcher *rules_endptr; 52 }; 53 noit_hash_table dispatch_points = NOIT_HASH_EMPTY; 54 55 static rest_request_handler 56 noit_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 } 103 int 104 noit_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 38 145 static noit_http_rest_closure_t * 39 146 noit_http_rest_closure_alloc() { … … 43 150 } 44 151 static void 152 noit_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 } 162 static void 45 163 noit_http_rest_closure_free(noit_http_rest_closure_t *restc) { 164 free(restc->remote_cn); 165 noit_http_rest_clean_request(restc); 46 166 free(restc); 47 167 } … … 49 169 int 50 170 noit_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"); 53 181 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); 57 183 noit_http_response_end(ctx); 58 184 return 0; … … 79 205 const char *primer = ""; 80 206 ac->service_ctx = restc = noit_http_rest_closure_alloc(); 207 restc->remote_cn = strdup(ac->remote_cn ? ac->remote_cn : ""); 81 208 restc->http_ctx = 82 209 noit_http_session_ctx_new(noit_rest_request_dispatcher, src/noit_rest.h
r7e47bd8 r0256945 42 42 #define NOIT_CONTROL_POST 0x504f5354 43 43 44 typedef struct { 44 typedef struct noit_http_rest_closure noit_http_rest_closure_t; 45 46 typedef int (*rest_request_handler)(noit_http_rest_closure_t *, 47 int npats, char **pats); 48 49 struct noit_http_rest_closure { 45 50 noit_http_session_ctx *http_ctx; 51 char *remote_cn; 52 rest_request_handler fastpath; 53 int nparams; 54 char **params; 46 55 int wants_shutdown; 47 } noit_http_rest_closure_t;56 }; 48 57 49 58 API_EXPORT(void) noit_http_rest_init(); 50 59 60 API_EXPORT(int) 61 noit_http_rest_register(const char *method, const char *base, 62 const char *expression, rest_request_handler f); 63 51 64 #endif src/noitd.c
r7e47bd8 r0256945 53 53 #include "noit_jlog_listener.h" 54 54 #include "noit_rest.h" 55 #include "noit_check_rest.h" 55 56 #include "noit_livestream_listener.h" 56 57 #include "noit_capabilities_listener.h" … … 183 184 noit_jlog_listener_init(); 184 185 noit_http_rest_init(); 186 noit_check_rest_init(); 185 187 noit_livestream_listener_init(); 186 188
