Преглед изворни кода

plugins/check_http: chunked Transfer-Encoding

Koen Wilde пре 11 година
родитељ
комит
24b8869019
2 измењених фајлова са 86 додато и 8 уклоњено
  1. 82 1
      plugins/check_http.c
  2. 4 7
      plugins/tests/check_http.t

+ 82 - 1
plugins/check_http.c

@@ -676,6 +676,83 @@ expected_statuscode (const char *reply, const char *statuscodes)
   return result;
 }
 
+char *
+decode_chunked_page (const char *raw, char *dst)
+{
+  unsigned long int chunksize;
+  char *raw_pos;
+  char *dst_pos;
+
+  raw_pos = (char *)raw;
+  dst_pos = dst;
+  while (chunksize = strtoul(raw_pos, NULL, 16)) {
+    // soak up the optional chunk params (which we will ignore)
+    for (; *raw_pos && *raw_pos != '\r' && *raw_pos != '\n'; raw_pos++)
+      ;
+
+    raw_pos += 2; // soak up the leading CRLF
+
+    strncpy(dst_pos, raw_pos, chunksize);
+
+    dst_pos += chunksize;
+    raw_pos += chunksize;
+    raw_pos += 2; // soak up the ending CRLF
+  }
+  *dst_pos = '\0';
+
+  return dst;
+}
+
+static char *header_value (const char *headers, const char *header)
+{
+  char *s;
+  char *value;
+  const char *value_start;
+  int value_size;
+
+  s = strstr(headers, header);
+  if (s == NULL)
+    return NULL;
+
+  while (*s && !isspace(*s) && *s != ':')
+    s++;
+  if (*s && *s == ':')
+    s++;
+  while (*s && isspace(*s))
+    s++;
+
+  for (value_start = s; *s && *s != '\r' && *s != '\n'; s++)
+    ;
+
+  value_size = (s - value_start);
+  value = (char *) malloc(value_size + 1);
+  if (!value)
+    die (STATE_UNKNOWN, _("HTTP_UNKOWN - Memory allocation error\n"));
+
+  strncpy(value, value_start, value_size);
+
+  value[value_size] = '\0';
+
+  return value;
+}
+
+static int
+chunked_transfer_encoding (const char *headers)
+{
+  int result;
+  char *encoding = header_value(headers, "Transfer-Encoding");
+  if (!encoding)
+    return 0;
+
+  if (strncmp(encoding, "chunked", sizeof("chunked")) == 0)
+    result = 1;
+  else
+    result = 0;
+
+  free(encoding);
+  return result;
+}
+
 static int
 check_document_dates (const char *headers, char **msg)
 {
@@ -1051,6 +1128,10 @@ check_http (void)
   }
   page += (size_t) strspn (page, "\r\n");
   header[pos - header] = 0;
+
+  if (chunked_transfer_encoding(header))
+    page = decode_chunked_page(page, page);
+
   if (verbose)
     printf ("**** HEADER ****\n%s\n**** CONTENT ****\n%s\n", header,
                 (no_body ? "  [[ skipped ]]" : page));
@@ -1125,6 +1206,7 @@ check_http (void)
     result = max_state_alt(check_document_dates(header, &msg), result);
   }
 
+
   /* Page and Header content checks go here */
   if (strlen (header_expect)) {
     if (!strstr (header, header_expect)) {
@@ -1137,7 +1219,6 @@ check_http (void)
     }
   }
 
-
   if (strlen (string_expect)) {
     if (!strstr (page, string_expect)) {
       strncpy(&output_string_search[0],string_expect,sizeof(output_string_search));

+ 4 - 7
plugins/tests/check_http.t

@@ -381,13 +381,10 @@ sub run_common_tests {
 	is( $result->return_code, 0, $cmd);
 	like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output );
 
-	SKIP: {
-		skip "FIXME: Chunked-encoding isn't supported yet", 2 unless ($ENV{HTTP_CHUNKED});
-		$cmd = "$command -u /chunked -s foobarbaz";
-		$result = NPTest->testCmd( $cmd );
-		is( $result->return_code, 0, $cmd);
-		like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output );
-	}
+  $cmd = "$command -u /chunked -s foobarbaz";
+  $result = NPTest->testCmd( $cmd );
+  is( $result->return_code, 0, $cmd);
+  like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output );
 
   # These tests may block
 	print "ALRM\n";