# add data; data= datasvc; datasvc= tag support to hosts.cfg # # Similar to regular URL check, but sends body of response to # xymond as a 'data' message. # # datasvc does the same, but also sends the results as a status result, # similar to a blank content check. # --- xymonnet/contest.h.storehttpdata 2012-04-05 15:32:28.048305282 -0700 +++ xymonnet/contest.h 2012-04-05 16:09:38.736117950 -0700 @@ -135,6 +135,9 @@ #define CONTENTCHECK_NOREGEX 3 #define CONTENTCHECK_CONTENTTYPE 4 +#define CONTENTSAVE_NONE 0 +#define CONTENTSAVE_FULL 1 + #define HTTPVER_ANY 0 #define HTTPVER_10 1 #define HTTPVER_11 2 @@ -169,6 +172,7 @@ char *contenttype; /* Content-type: header from server */ int contentcheck; /* 0=no content check, 1=regex check, 2=digest check */ + int contentsave; /* 0=don't save content, 1=save content */ void *exp; /* data for content match (digest, or regexp data) */ digestctx_t *digestctx; /* OpenSSL data for digest handling */ char *digest; /* Digest of the data received from the server */ --- lib/url.c.datahttp 2012-04-05 17:53:13.238628887 -0700 +++ lib/url.c 2012-04-05 18:15:48.231101602 -0700 @@ -488,6 +488,18 @@ } else if (strncmp(inp, "cont=", 5) == 0) { weburl->testtype = WEBTEST_CONT; urlstart = gethttpcolumn(inp+5, &weburl->columnname); + } else if (strncmp(inp, "data;", 5) == 0) { + weburl->testtype = WEBTEST_DATA; + urlstart = inp+5; + } else if (strncmp(inp, "data=", 5) == 0) { + weburl->testtype = WEBTEST_DATA; + urlstart = gethttpcolumn(inp+5, &weburl->columnname); + } else if (strncmp(inp, "datasvc;", 8) == 0) { + weburl->testtype = WEBTEST_DATASVC; + urlstart = inp+8; + } else if (strncmp(inp, "datasvc=", 8) == 0) { + weburl->testtype = WEBTEST_DATASVC; + urlstart = gethttpcolumn(inp+8, &weburl->columnname); } else if (strncmp(inp, "nocont;", 7) == 0) { weburl->testtype = WEBTEST_NOCONT; urlstart = inp+7; @@ -545,6 +551,8 @@ break; case WEBTEST_CONT: + case WEBTEST_DATA: + case WEBTEST_DATASVC: case WEBTEST_NOCONT: case WEBTEST_TYPE: expstart = strchr(urlstart, ';'); --- xymonnet/httptest.c.datahttp 2012-04-05 17:53:13.499358439 -0700 +++ xymonnet/httptest.c 2012-04-05 18:24:27.977044590 -0700 @@ -133,13 +133,24 @@ if (len1chunk > 0) { switch (item->contentcheck) { - case CONTENTCHECK_NONE: - case CONTENTCHECK_CONTENTTYPE: - /* No need to save output - just drop it */ - break; - case CONTENTCHECK_REGEX: case CONTENTCHECK_NOREGEX: + item->contentsave = CONTENTSAVE_FULL; + break; + + case CONTENTCHECK_DIGEST: + /* Run the data through our digest routine, but discard the raw data */ + if ((item->digestctx == NULL) || (digest_data(item->digestctx, buf, len1chunk) != 0)) { + errprintf("Failed to hash data for digest\n"); + } + break; + } + + switch (item->contentsave) { + case CONTENTSAVE_NONE: + /* No need to save output - just drop it */ + break; + case CONTENTSAVE_FULL: /* Save the full data */ if ((item->output == NULL) || (item->outlen == 0)) { item->output = (unsigned char *)malloc(len1chunk+1); @@ -152,13 +163,6 @@ item->outlen += len1chunk; *(item->output + item->outlen) = '\0'; /* Just in case ... */ break; - - case CONTENTCHECK_DIGEST: - /* Run the data through our digest routine, but discard the raw data */ - if ((item->digestctx == NULL) || (digest_data(item->digestctx, buf, len1chunk) != 0)) { - errprintf("Failed to hash data for digest\n"); - } - break; } buf += len1chunk; @@ -353,6 +357,7 @@ httptest->url = strdup(decodedurl); httptest->contlen = -1; + httptest->contentsave = CONTENTSAVE_NONE; httptest->parsestatus = (httptest->weburl.proxyurl ? httptest->weburl.proxyurl->parseerror : httptest->weburl.desturl->parseerror); /* If there was a parse error in the URL, dont run the test */ @@ -412,6 +422,11 @@ httptest->contentcheck = CONTENTCHECK_NOREGEX; break; + case WEBTEST_DATA: + case WEBTEST_DATASVC: + httptest->contentsave = CONTENTSAVE_FULL; + break; + case WEBTEST_POST: case WEBTEST_SOAP: if (httptest->weburl.expdata == NULL) { @@ -443,6 +452,9 @@ break; } + /* Do we need the callback to save the raw data even if no content check? */ + if (t->senddata >= 2) httptest->contentsave = CONTENTSAVE_FULL; + /* Compile the hashes and regex's for those tests that use it */ switch (httptest->contentcheck) { case CONTENTCHECK_DIGEST: --- xymonnet/xymonnet.c.datahttp 2012-04-05 17:53:13.479373389 -0700 +++ xymonnet/xymonnet.c 2012-04-05 18:18:21.115045292 -0700 @@ -555,6 +555,10 @@ argnmatch(testspec, "content=http") || argnmatch(testspec, "cont;http") || argnmatch(testspec, "cont=") || + argnmatch(testspec, "data;http") || + argnmatch(testspec, "data=") || + argnmatch(testspec, "datasvc;http") || + argnmatch(testspec, "datasvc=") || argnmatch(testspec, "nocont;http") || argnmatch(testspec, "nocont=") || argnmatch(testspec, "post;http") || @@ -581,6 +583,10 @@ s = httptest; if (!url.desturl->ip) add_url_to_dns_queue(testspec); + if (argnmatch(testspec, "data;http") || argnmatch(testspec, "data=")) + sendasdata = 2; + if (argnmatch(testspec, "datasvc;http") || argnmatch(testspec, "datasvc=")) + sendasdata = 3; } } else if (argnmatch(testspec, "apache") || argnmatch(testspec, "apache=")) { --- lib/url.h.datahttp 2012-04-05 18:27:20.954865158 -0700 +++ lib/url.h 2012-04-05 18:29:14.190099414 -0700 @@ -26,7 +26,7 @@ } urlelem_t; enum webtesttype_t { - WEBTEST_PLAIN, WEBTEST_CONTENT, WEBTEST_CONT, WEBTEST_NOCONT, WEBTEST_POST, WEBTEST_NOPOST, WEBTEST_TYPE, WEBTEST_STATUS, WEBTEST_SOAP, WEBTEST_NOSOAP, + WEBTEST_PLAIN, WEBTEST_CONTENT, WEBTEST_CONT, WEBTEST_NOCONT, WEBTEST_DATA, WEBTEST_DATASVC, WEBTEST_POST, WEBTEST_NOPOST, WEBTEST_TYPE, WEBTEST_STATUS, WEBTEST_SOAP, WEBTEST_NOSOAP, }; typedef struct weburl_t { --- xymonnet/httpresult.c.datahttp 2012-04-05 20:33:55.076052410 -0700 +++ xymonnet/httpresult.c 2012-04-06 13:28:46.519137215 -0700 @@ -111,6 +111,9 @@ char *nopagename; int nopage = 0; int anydown = 0, totalreports = 0; + char *contsave; + int contentsavenum = 0; + contsave = (char *) malloc(128); if (firsttest == NULL) return; @@ -130,7 +133,7 @@ http_data_t *req = (http_data_t *) t->privdata; /* Skip the data-reports for now */ - if (t->senddata) continue; + if (t->senddata == 1) continue; /* Grab session cookies */ update_session_cookies(host->hostname, req->weburl.desturl->host, req->headers); @@ -270,7 +273,7 @@ http_data_t *req = (http_data_t *) t->privdata; /* Skip the "data" reports */ - if (t->senddata) continue; + if (t->senddata == 1) continue; urlmsg = (char *)malloc(1024 + strlen(req->url)); sprintf(urlmsg, "\n&%s %s - ", colorname(req->httpcolor), req->url); @@ -312,7 +315,7 @@ char *urlmsg; http_data_t *req = (http_data_t *) t->privdata; - if ((t->senddata) || (!req->weburl.columnname) || (req->contentcheck != CONTENTCHECK_NONE)) continue; + if ((t->senddata == 1) || (t->senddata == 2) || (!req->weburl.columnname) || (req->contentcheck != CONTENTCHECK_NONE)) continue; /* Handle the "badtest" stuff */ color = req->httpcolor; @@ -379,2 +379,11 @@ if (req->output) data = req->output; + if (req->weburl.columnname) { + strcpy(contsave, req->weburl.columnname); + } + else { + if (contentsavenum > 0) sprintf(contsave, "%s%d", "httpdata", contentsavenum); + else strcpy(contsave, "httpdata"); + + contentsavenum++; + } @@ -390,1 +390,1 @@ - sprintf(msgline, "data %s.%s\n", commafy(host->hostname), req->weburl.columnname); + sprintf(msgline, "data %s.%s\n", commafy(host->hostname), contsave); @@ -420,2 +420,3 @@ xfree(svcname); + xfree(contsave); freestrbuffer(msgtext); @@ -432,7 +445,7 @@ int got_data = 1; /* Skip the "data"-only messages */ - if (t->senddata) continue; + if ((t->senddata == 1) || (t->senddata == 2)) continue; if (!req->contentcheck) continue; /* We have a content check */ --- common/hosts.cfg.5.datahttp 2012-05-07 07:31:51.621588413 -0700 +++ common/hosts.cfg.5 2012-05-07 08:39:46.744706486 -0700 @@ -1128,6 +1128,24 @@ This syntax is deprecated. You should use the "cont" tag instead, see above. +.IP data[=COLUMN];URL; +.IP datasvc=[=COLUMN];URL; + +These tags are used to specify an http/https check where the raw +contents of the page retrieved are sent over the "data" channel +with a dataname of COLUMN. Although Xymon doesn't process it further, +custom scripts could read this data and generate status reports. + +The "datasvc" tag ALSO creates a separate service status report +for this URL. + +Column-names cannot include whitespace or semi-colon. If no name +is specified, "httpdata" is used. If more than one unnamed data +test is used, numbers are appended to the test name. + +You can hide the HTML data on a per-host (not per-test) basis +by adding the \fBHIDEHTTP\fR tag to the host entry. + .IP post[=COLUMN];URL;form-data;[expected_data_regexp|#digesttype:digest] This tag can be used to test web pages, that use an input form. Data can be posted to the form by specifying them