Changeset 4f39b4d05385ed2a6a1620e2e3a578b2de6a937a

Show
Ignore:
Timestamp:
06/05/09 01:44:24 (6 years ago)
Author:
Theo Schlossnagle <jesus@omniti.com>
git-committer:
Theo Schlossnagle <jesus@omniti.com> 1244166264 +0000
git-parent:

[71ecd80d52072d3327e42dd7c5d60c6efec2b650]

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

use regular expression instead, and add a body moatcher as a bonus... closes #141

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • src/modules/http.c

    r3e39e03 r4f39b4d  
    3939#include <math.h> 
    4040 
     41#include <pcre.h> 
     42 
    4143#include <libxml/parser.h> 
    4244#include <libxml/tree.h> 
     
    177179  struct timeval duration; 
    178180  stats_t current; 
    179   int expect_code = 200
     181  pcre *expect_code = NULL, *body_match = NULL
    180182  u_int32_t duration_ms; 
    181   void *code_str; /* void * for use with hash */ 
    182   char human_buffer[256], code[4], rt[14]; 
     183  void *code_str, *body_str; /* void * for use with hash */ 
     184  char human_buffer[256], code[4], rt[14], bmatch[30]; 
     185  const char *error; 
     186  int body_matched = 1; 
     187  int erroffset; 
     188  int ovector[30]; 
    183189 
    184190  noit_check_stats_clear(&current); 
    185191 
    186   if(noit_hash_retrieve(check->config, "code", strlen("code"), &code_str)) 
    187     expect_code = atoi((const char *)code_str); 
     192  if(!noit_hash_retrieve(check->config, "code", strlen("code"), &code_str)) { 
     193    code_str = "^200$"; 
     194  } 
     195  expect_code = pcre_compile((const char *)code_str, 0, 
     196                             &error, &erroffset, NULL); 
     197  if(!expect_code) 
     198    noitL(nlerr, "http code match /%s/ failed @ %d: %s\n", (char *)code_str, 
     199          erroffset, error); 
     200           
     201  if(noit_hash_retrieve(check->config, "body", strlen("body"), &body_str)) { 
     202    body_match = pcre_compile((const char *)body_str, 0, 
     203                              &error, &erroffset, NULL); 
     204    if(!body_match) 
     205      noitL(nlerr, "http body match /%s/ failed @ %d: %s\n", 
     206            (char *)body_str, erroffset, error); 
     207  } 
    188208 
    189209  sub_timeval(ci->finish_time, check->last_fire_time, &duration); 
     
    192212  snprintf(rt, sizeof(rt), "%.3fs", 
    193213           (float)duration.tv_sec + (float)duration.tv_usec / 1000000.0); 
     214 
     215  bmatch[0] = '\0'; 
     216  if(body_match) { 
     217    if(pcre_exec(body_match, NULL, ci->body.b, ci->body.l, 0, 0, 
     218                 ovector, sizeof(ovector)/sizeof(*ovector)) <= 0) { 
     219      body_matched = 0; 
     220    } 
     221    snprintf(bmatch, sizeof(bmatch), 
     222             ",body=%s", body_matched ? "matched" : "failed"); 
     223  } 
     224 
    194225  snprintf(human_buffer, sizeof(human_buffer), 
    195            "code=%s,rt=%s,bytes=%d", 
     226           "code=%s,rt=%s,bytes=%d%s", 
    196227           ci->status.code ? code : "undefined", 
    197228           ci->timed_out ? "timeout" : rt, 
    198            ci->body.l); 
     229           ci->body.l, bmatch); 
    199230  noitL(nldeb, "http(%s) [%s]\n", check->target, human_buffer); 
    200231 
     
    203234  duration_ms = current.duration; 
    204235  current.available = (ci->timed_out || !ci->status.code) ? NP_UNAVAILABLE : NP_AVAILABLE; 
    205   current.state = (ci->status.code != expect_code) ? NP_BAD : NP_GOOD; 
     236 
     237  if(body_matched == 0) current.state = NP_BAD; 
     238  else if(expect_code && 
     239          pcre_exec(expect_code, NULL, code, strlen(code), 0, 0, 
     240                    ovector, sizeof(ovector)/sizeof(*ovector)) > 0) 
     241    current.state = NP_GOOD; 
     242  else 
     243    current.state = NP_BAD; 
     244 
    206245  current.status = human_buffer; 
    207246  if(current.available == NP_AVAILABLE) { 
     
    219258  } 
    220259  noit_check_set_stats(self, check, &current); 
     260  if(expect_code) pcre_free(expect_code); 
     261  if(body_match) pcre_free(body_match); 
    221262} 
    222263static void resmon_part_log_results_xml(noit_module_t *self, 
  • src/modules/http.xml

    r9d30fdf r4f39b4d  
    11<module> 
    22  <name>http</name> 
    3   <description><para>The http module performs GET requests over either HTTP or HTTPS and checks the return code.</para> 
     3  <description><para>The http module performs GET requests over either HTTP or HTTPS and checks the return code and optionally the body.</para> 
    44  </description> 
    55  <loader>C</loader> 
     
    2828    <parameter name="code" 
    2929               required="optional" 
    30                default="200" 
    31                allowed="[1-5][0-9][0-9]">The HTTP code that is expected.  If the code received matches this code, the check is marked as "good," if it does not match, it is marked as "bad."</parameter> 
     30               default="^200$" 
     31               allowed=".+">The HTTP code that is expected.  If the code received does not match this regular expression, the check is marked as "bad."</parameter> 
     32    <parameter name="body" 
     33               required="optional" 
     34               allowed=".+">This regular expression is matched against the body of the response.  If a match is not found, the check will be marked as "bad."</parameter> 
    3235  </checkconfig> 
    3336  <examples>