summaryrefslogtreecommitdiffstats
path: root/web/attachments/410030-checkhttpgzipdeflate.patch
diff options
context:
space:
mode:
Diffstat (limited to 'web/attachments/410030-checkhttpgzipdeflate.patch')
-rw-r--r--web/attachments/410030-checkhttpgzipdeflate.patch328
1 files changed, 328 insertions, 0 deletions
diff --git a/web/attachments/410030-checkhttpgzipdeflate.patch b/web/attachments/410030-checkhttpgzipdeflate.patch
new file mode 100644
index 0000000..0850a70
--- /dev/null
+++ b/web/attachments/410030-checkhttpgzipdeflate.patch
@@ -0,0 +1,328 @@
1diff --git a/plugins/check_http.c b/plugins/check_http.c
2index 433c28e..a71cfe6 100644
3--- a/plugins/check_http.c
4+++ b/plugins/check_http.c
5@@ -41,7 +41,9 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net";
6 #include "netutils.h"
7 #include "utils.h"
8 #include "base64.h"
9+#include "zlib.h"
10 #include <ctype.h>
11+#include <stdlib.h>
12
13 #define INPUT_DELIMITER ";"
14 #define STICKY_NONE 0
15@@ -114,6 +116,8 @@ int followsticky = STICKY_NONE;
16 int use_ssl = FALSE;
17 int use_sni = FALSE;
18 int verbose = FALSE;
19+int decompress = FALSE;
20+int chunked = FALSE;
21 int sd;
22 int min_page_len = 0;
23 int max_page_len = 0;
24@@ -134,6 +138,14 @@ char *perfd_size (int page_len);
25 void print_help (void);
26 void print_usage (void);
27
28+int page_content_decompress(const char *in_buf,int in_size,
29+ char **data,int *out_size,int type);
30+int find_header_info(const char* header,
31+ char* content,const char* keyword);
32+int get_content_encoding(const char* header);
33+int get_transfer_encoding(const char* header);
34+char* decodechunked(char * chunked, unsigned int *inputlen);
35+
36 int
37 main (int argc, char **argv)
38 {
39@@ -214,6 +226,8 @@ process_arguments (int argc, char **argv)
40 {"invert-regex", no_argument, NULL, INVERT_REGEX},
41 {"use-ipv4", no_argument, 0, '4'},
42 {"use-ipv6", no_argument, 0, '6'},
43+ {"decompress",no_argument,0,'d'},
44+ {"chunked",no_argument,0,'X'},
45 {0, 0, 0, 0}
46 };
47
48@@ -234,7 +248,7 @@ process_arguments (int argc, char **argv)
49 }
50
51 while (1) {
52- c = getopt_long (argc, argv, "Vvh46t:c:w:A:k:H:P:j:T:I:a:b:e:p:s:R:r:u:f:C:nlLSm:M:N", longopts, &option);
53+ c = getopt_long (argc, argv, "Vvh46t:c:w:A:k:H:P:j:T:I:a:b:e:p:s:R:r:u:f:C:nlLSm:M:NdX", longopts, &option);
54 if (c == -1 || c == EOF)
55 break;
56
57@@ -406,6 +420,12 @@ process_arguments (int argc, char **argv)
58 case 'v': /* verbose */
59 verbose = TRUE;
60 break;
61+ case 'd': /* decompress */
62+ decompress = TRUE;
63+ break;
64+ case 'X': /*chunked*/
65+ chunked = TRUE;
66+ break;
67 case 'm': /* min_page_length */
68 {
69 char *tmp;
70@@ -793,6 +813,9 @@ check_http (void)
71 int page_len = 0;
72 int result = STATE_OK;
73
74+ char *uncompress_page;
75+ int uncompress_page_size;
76+
77 /* try to connect to the host at the given port number */
78 if (my_tcp_connect (server_address, server_port, &sd) != STATE_OK)
79 die (STATE_CRITICAL, _("HTTP CRITICAL - Unable to open TCP socket\n"));
80@@ -870,18 +893,15 @@ check_http (void)
81 my_send (buf, strlen (buf));
82
83 /* fetch the page */
84- full_page = strdup("");
85+ full_page =(char*)malloc(sizeof(char)*4096);
86 while ((i = my_recv (buffer, MAX_INPUT_BUFFER-1)) > 0) {
87- buffer[i] = '\0';
88- asprintf (&full_page_new, "%s%s", full_page, buffer);
89- free (full_page);
90- full_page = full_page_new;
91+ full_page = realloc(full_page, pagesize + i);
92+ memcpy(full_page + pagesize, buffer, i);
93 pagesize += i;
94-
95- if (no_body && document_headers_done (full_page)) {
96- i = 0;
97- break;
98- }
99+ if (no_body && document_headers_done (full_page)) {
100+ i = 0;
101+ break;
102+ }
103 }
104
105 if (i < 0 && errno != ECONNRESET) {
106@@ -951,6 +971,28 @@ check_http (void)
107 }
108 page += (size_t) strspn (page, "\r\n");
109 header[pos - header] = 0;
110+
111+ /*deal chunked data*/
112+ if(get_transfer_encoding(header)==1 && chunked) {
113+ pagesize = pagesize - (page-header);
114+ page = decodechunked(page,&pagesize);
115+ }
116+ else {
117+ pagesize = get_content_length(header);
118+ }
119+
120+ /*decompress the page content*/
121+ int content_encoding = get_content_encoding(header);
122+ if(decompress && (content_encoding == 1 || content_encoding == 2)) {
123+ result = page_content_decompress(page,pagesize,&uncompress_page,
124+ &uncompress_page_size,content_encoding);
125+
126+ if(result == 0) {
127+ page = uncompress_page;
128+ pagesize = uncompress_page_size;
129+ }
130+ }
131+
132 if (verbose)
133 printf ("**** HEADER ****\n%s\n**** CONTENT ****\n%s\n", header,
134 (no_body ? " [[ skipped ]]" : page));
135@@ -1384,6 +1426,8 @@ print_help (void)
136 printf (UT_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
137
138 printf (UT_VERBOSE);
139+ printf (UT_DECOMPRESS);
140+ printf (UT_CHUNKED);
141
142 printf ("\n");
143 printf ("%s\n", _("Notes:"));
144@@ -1432,3 +1476,167 @@ print_usage (void)
145 printf (" [-A string] [-k string] [-S] [--sni] [-C <age>] [-T <content-type>]\n");
146 printf (" [-j method]\n");
147 }
148+
149+/* HTTP gzip or deflate decompress;
150+ * type = 1 represent gzip format
151+ * type = 2 represent deflate format */
152+int page_content_decompress(const char *in_buf,int in_size,
153+ char **out_buf_ptr, int *out_size,int type)
154+{
155+ z_stream stream = {0}; /* decompression stream */
156+ char *out_buf = NULL;
157+ int out_buf_bytes = 0;
158+ char tmp_buf[4096];
159+ int result;
160+ int new_bytes;
161+
162+ stream.zalloc = (alloc_func)0;
163+ stream.zfree = (free_func)0;
164+ stream.opaque = (voidpf)0;
165+ stream.next_in = (void*) in_buf;
166+ stream.avail_in = in_size;
167+ stream.next_out = tmp_buf;
168+ stream.avail_out = sizeof tmp_buf;
169+
170+ switch (type) {
171+ case 1: /*gzip*/
172+ if(inflateInit2(&stream,MAX_WBITS+32) != Z_OK)
173+ return -1;
174+ break;
175+ case 2: /*deflate*/
176+ if(inflateInit2(&stream,-MAX_WBITS) != Z_OK)
177+ return -1;
178+ }
179+
180+ do {
181+ result = inflate(&stream,Z_NO_FLUSH);
182+ switch (result) {
183+ case Z_BUF_ERROR:
184+ if(stream.avail_in == 0)
185+ goto DONE; /*zlib bug */
186+ case Z_ERRNO:
187+ case Z_NEED_DICT:
188+ case Z_MEM_ERROR:
189+ case Z_DATA_ERROR:
190+ inflateEnd(&stream);
191+ free(out_buf);
192+ return -1;
193+ }
194+ if(stream.avail_out < sizeof tmp_buf) {
195+ new_bytes = sizeof tmp_buf - stream.avail_out;
196+ out_buf = realloc(out_buf,out_buf_bytes + new_bytes);
197+ memcpy (out_buf + out_buf_bytes,tmp_buf,new_bytes);
198+ out_buf_bytes += new_bytes;
199+ stream.next_out = tmp_buf;
200+ stream.avail_out = sizeof tmp_buf;
201+ }
202+ else {
203+ inflateEnd(&stream);
204+ free(out_buf);
205+ return -1;
206+ }
207+ }
208+ while(result != Z_STREAM_END);
209+
210+DONE:
211+
212+ if(inflateEnd(&stream) != Z_OK) {
213+ free(out_buf);
214+ return -1;
215+ }
216+
217+ *out_size = out_buf_bytes;
218+ out_buf = realloc(out_buf,out_buf_bytes + 1);
219+ out_buf[out_buf_bytes] = 0;
220+ *out_buf_ptr = out_buf;
221+
222+ return 0;
223+}
224+
225+/*find content from header data by keyword*/
226+int find_header_info(const char* header,char* content,const char* keyword) {
227+ char* start = strstr(header,keyword);
228+ if(start != 0) {
229+ start = start + strcspn(start,": ");
230+ start += strspn(start,": ");
231+ char* end = start + strcspn(start," \r\n");
232+ if( content != NULL) {
233+ memcpy(content,start,end-start);
234+ }
235+ return 1;
236+ }
237+ else{
238+ return 0;
239+ }
240+}
241+
242+/*find Content-Encoding from the header info;
243+ *if Content-Encoding equal 'gzip' return 1,or return 0.
244+ */
245+int get_content_encoding(const char* header) {
246+ int result = 0;
247+ int ret = 0;
248+ char* content_encoding = (char*)malloc(sizeof(char)*10);
249+ result = find_header_info(header,content_encoding,"Content-Encoding");
250+
251+ if(result && strncmp(content_encoding,"gzip",4)==0) {
252+ ret = 1;
253+ }
254+ else if(result && strncmp(content_encoding,"deflate",7)==0) {
255+ ret = 2;
256+ }
257+ else {
258+ ret = 0;
259+ }
260+ if(content_encoding != NULL) {
261+ free(content_encoding);
262+ }
263+ return ret;
264+}
265+
266+/*find Transfer-Encoding from the header info;
267+ * if Content-Encoding equal 'chunked' return 1,or return 0.
268+ */
269+int get_transfer_encoding(const char* header) {
270+ int result = 0;
271+ int ret = 0;
272+ char *transfer_encoding = (char*)malloc(sizeof(char)*10);
273+ result = find_header_info(header,transfer_encoding,"Transfer-Encoding");
274+
275+ if(result && strncmp(transfer_encoding,"chunked",7)==0){
276+ ret = 1;
277+ }
278+ else {
279+ ret = 0;
280+ }
281+
282+ if(transfer_encoding != NULL) {
283+ free(transfer_encoding);
284+ }
285+ return ret;
286+}
287+
288+/* Returns NULL on invalid input */
289+char* decodechunked(char * chunked, unsigned int *inputlen) {
290+ char *orig = chunked, *dest = chunked;
291+ unsigned long chunklen;
292+ while((chunklen = strtoul(orig, &orig, 16))) {
293+ /* process one more chunk: */
294+ /* skip chunk-extension part */
295+ while(*orig && (*orig != '\r'))
296+ orig++;
297+ /* skip '\r\n' after chunk length */
298+ orig += 2;
299+ if(( chunklen > (chunked + *inputlen - orig)))
300+ /* insane chunk length. Well... */
301+ return NULL;
302+ memmove(dest, orig, chunklen);
303+ dest += chunklen;
304+ orig += chunklen;
305+ /* and go to the next chunk */
306+ }
307+ *dest = '\0';
308+ *inputlen = dest - chunked;
309+
310+ return chunked;
311+}
312diff --git a/plugins/utils.h b/plugins/utils.h
313index 3c3f189..78a74aa 100644
314--- a/plugins/utils.h
315+++ b/plugins/utils.h
316@@ -204,4 +204,12 @@ The nagios plugins come with ABSOLUTELY NO WARRANTY. You may redistribute\n\
317 copies of the plugins under the terms of the GNU General Public License.\n\
318 For more information about these matters, see the file named COPYING.\n")
319
320+#define UT_DECOMPRESS _("\
321+ -d, --decompress\n\
322+ Decompress the contents of page which were compressed by gzip or deflate.\n")
323+
324+#define UT_CHUNKED _("\
325+ -X, --chunked\n\
326+ Deal with the data which was transferred by chunked encoding.")
327+
328 #endif /* NP_UTILS_H */