summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2022-01-27 09:00:58 (GMT)
committerSven Nierlein <sven@nierlein.org>2022-01-29 11:17:37 (GMT)
commitee2a60fc4e26828b115051564706f8fbc4c4b153 (patch)
treefe592945ebbbd82556820686f341a3070edb71d1
parent737412f7391ae430a51e8f2c2a3b1ab2d35a6394 (diff)
downloadmonitoring-plugins-ee2a60f.tar.gz
fixed -ffollow for HTTP/2.0 (Fixes #1685): added major_version parsing to PicoHTTPParser
-rw-r--r--plugins/check_curl.c6
-rw-r--r--plugins/picohttpparser/picohttpparser.c30
-rw-r--r--plugins/picohttpparser/picohttpparser.h4
3 files changed, 23 insertions, 17 deletions
diff --git a/plugins/check_curl.c b/plugins/check_curl.c
index 32d919f..7da84de 100644
--- a/plugins/check_curl.c
+++ b/plugins/check_curl.c
@@ -1054,7 +1054,7 @@ redir (curlhelp_write_curlbuf* header_buf)
1054 char *new_url; 1054 char *new_url;
1055 1055
1056 int res = phr_parse_response (header_buf->buf, header_buf->buflen, 1056 int res = phr_parse_response (header_buf->buf, header_buf->buflen,
1057 &status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen, 1057 &status_line.http_major, &status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen,
1058 headers, &nof_headers, 0); 1058 headers, &nof_headers, 0);
1059 1059
1060 location = get_header_value (headers, nof_headers, "location"); 1060 location = get_header_value (headers, nof_headers, "location");
@@ -2200,7 +2200,7 @@ check_document_dates (const curlhelp_write_curlbuf *header_buf, char (*msg)[DEFA
2200 size_t msglen; 2200 size_t msglen;
2201 2201
2202 int res = phr_parse_response (header_buf->buf, header_buf->buflen, 2202 int res = phr_parse_response (header_buf->buf, header_buf->buflen,
2203 &status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen, 2203 &status_line.http_major, &status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen,
2204 headers, &nof_headers, 0); 2204 headers, &nof_headers, 0);
2205 2205
2206 server_date = get_header_value (headers, nof_headers, "date"); 2206 server_date = get_header_value (headers, nof_headers, "date");
@@ -2258,7 +2258,7 @@ get_content_length (const curlhelp_write_curlbuf* header_buf, const curlhelp_wri
2258 curlhelp_statusline status_line; 2258 curlhelp_statusline status_line;
2259 2259
2260 int res = phr_parse_response (header_buf->buf, header_buf->buflen, 2260 int res = phr_parse_response (header_buf->buf, header_buf->buflen,
2261 &status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen, 2261 &status_line.http_major, &status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen,
2262 headers, &nof_headers, 0); 2262 headers, &nof_headers, 0);
2263 2263
2264 content_length_s = get_header_value (headers, nof_headers, "content-length"); 2264 content_length_s = get_header_value (headers, nof_headers, "content-length");
diff --git a/plugins/picohttpparser/picohttpparser.c b/plugins/picohttpparser/picohttpparser.c
index 74ccc3e..d9680b7 100644
--- a/plugins/picohttpparser/picohttpparser.c
+++ b/plugins/picohttpparser/picohttpparser.c
@@ -242,7 +242,7 @@ static const char *is_complete(const char *buf, const char *buf_end, size_t last
242 } while (0) 242 } while (0)
243 243
244/* returned pointer is always within [buf, buf_end), or null */ 244/* returned pointer is always within [buf, buf_end), or null */
245static const char *parse_http_version(const char *buf, const char *buf_end, int *minor_version, int *ret) 245static const char *parse_http_version(const char *buf, const char *buf_end, int *major_version, int *minor_version, int *ret)
246{ 246{
247 /* we want at least [HTTP/1.<two chars>] to try to parse */ 247 /* we want at least [HTTP/1.<two chars>] to try to parse */
248 if (buf_end - buf < 9) { 248 if (buf_end - buf < 9) {
@@ -254,9 +254,13 @@ static const char *parse_http_version(const char *buf, const char *buf_end, int
254 EXPECT_CHAR_NO_CHECK('T'); 254 EXPECT_CHAR_NO_CHECK('T');
255 EXPECT_CHAR_NO_CHECK('P'); 255 EXPECT_CHAR_NO_CHECK('P');
256 EXPECT_CHAR_NO_CHECK('/'); 256 EXPECT_CHAR_NO_CHECK('/');
257 EXPECT_CHAR_NO_CHECK('1'); 257 PARSE_INT(major_version, 1);
258 EXPECT_CHAR_NO_CHECK('.'); 258 if (*major_version == 1) {
259 PARSE_INT(minor_version, 1); 259 EXPECT_CHAR_NO_CHECK('.');
260 PARSE_INT(minor_version, 1);
261 } else {
262 *minor_version = 0;
263 }
260 return buf; 264 return buf;
261} 265}
262 266
@@ -339,7 +343,7 @@ static const char *parse_headers(const char *buf, const char *buf_end, struct ph
339} 343}
340 344
341static const char *parse_request(const char *buf, const char *buf_end, const char **method, size_t *method_len, const char **path, 345static const char *parse_request(const char *buf, const char *buf_end, const char **method, size_t *method_len, const char **path,
342 size_t *path_len, int *minor_version, struct phr_header *headers, size_t *num_headers, 346 size_t *path_len, int *major_version, int *minor_version, struct phr_header *headers, size_t *num_headers,
343 size_t max_headers, int *ret) 347 size_t max_headers, int *ret)
344{ 348{
345 /* skip first empty line (some clients add CRLF after POST content) */ 349 /* skip first empty line (some clients add CRLF after POST content) */
@@ -364,7 +368,7 @@ static const char *parse_request(const char *buf, const char *buf_end, const cha
364 *ret = -1; 368 *ret = -1;
365 return NULL; 369 return NULL;
366 } 370 }
367 if ((buf = parse_http_version(buf, buf_end, minor_version, ret)) == NULL) { 371 if ((buf = parse_http_version(buf, buf_end, major_version, minor_version, ret)) == NULL) {
368 return NULL; 372 return NULL;
369 } 373 }
370 if (*buf == '\015') { 374 if (*buf == '\015') {
@@ -381,7 +385,7 @@ static const char *parse_request(const char *buf, const char *buf_end, const cha
381} 385}
382 386
383int phr_parse_request(const char *buf_start, size_t len, const char **method, size_t *method_len, const char **path, 387int phr_parse_request(const char *buf_start, size_t len, const char **method, size_t *method_len, const char **path,
384 size_t *path_len, int *minor_version, struct phr_header *headers, size_t *num_headers, size_t last_len) 388 size_t *path_len, int *major_version, int *minor_version, struct phr_header *headers, size_t *num_headers, size_t last_len)
385{ 389{
386 const char *buf = buf_start, *buf_end = buf_start + len; 390 const char *buf = buf_start, *buf_end = buf_start + len;
387 size_t max_headers = *num_headers; 391 size_t max_headers = *num_headers;
@@ -391,6 +395,7 @@ int phr_parse_request(const char *buf_start, size_t len, const char **method, si
391 *method_len = 0; 395 *method_len = 0;
392 *path = NULL; 396 *path = NULL;
393 *path_len = 0; 397 *path_len = 0;
398 *major_version = -1;
394 *minor_version = -1; 399 *minor_version = -1;
395 *num_headers = 0; 400 *num_headers = 0;
396 401
@@ -400,7 +405,7 @@ int phr_parse_request(const char *buf_start, size_t len, const char **method, si
400 return r; 405 return r;
401 } 406 }
402 407
403 if ((buf = parse_request(buf, buf_end, method, method_len, path, path_len, minor_version, headers, num_headers, max_headers, 408 if ((buf = parse_request(buf, buf_end, method, method_len, path, path_len, major_version, minor_version, headers, num_headers, max_headers,
404 &r)) == NULL) { 409 &r)) == NULL) {
405 return r; 410 return r;
406 } 411 }
@@ -408,11 +413,11 @@ int phr_parse_request(const char *buf_start, size_t len, const char **method, si
408 return (int)(buf - buf_start); 413 return (int)(buf - buf_start);
409} 414}
410 415
411static const char *parse_response(const char *buf, const char *buf_end, int *minor_version, int *status, const char **msg, 416static const char *parse_response(const char *buf, const char *buf_end, int *major_version, int *minor_version, int *status, const char **msg,
412 size_t *msg_len, struct phr_header *headers, size_t *num_headers, size_t max_headers, int *ret) 417 size_t *msg_len, struct phr_header *headers, size_t *num_headers, size_t max_headers, int *ret)
413{ 418{
414 /* parse "HTTP/1.x" */ 419 /* parse "HTTP/1.x" */
415 if ((buf = parse_http_version(buf, buf_end, minor_version, ret)) == NULL) { 420 if ((buf = parse_http_version(buf, buf_end, major_version, minor_version, ret)) == NULL) {
416 return NULL; 421 return NULL;
417 } 422 }
418 /* skip space */ 423 /* skip space */
@@ -451,13 +456,14 @@ static const char *parse_response(const char *buf, const char *buf_end, int *min
451 return parse_headers(buf, buf_end, headers, num_headers, max_headers, ret); 456 return parse_headers(buf, buf_end, headers, num_headers, max_headers, ret);
452} 457}
453 458
454int phr_parse_response(const char *buf_start, size_t len, int *minor_version, int *status, const char **msg, size_t *msg_len, 459int phr_parse_response(const char *buf_start, size_t len, int *major_version, int *minor_version, int *status, const char **msg, size_t *msg_len,
455 struct phr_header *headers, size_t *num_headers, size_t last_len) 460 struct phr_header *headers, size_t *num_headers, size_t last_len)
456{ 461{
457 const char *buf = buf_start, *buf_end = buf + len; 462 const char *buf = buf_start, *buf_end = buf + len;
458 size_t max_headers = *num_headers; 463 size_t max_headers = *num_headers;
459 int r; 464 int r;
460 465
466 *major_version = -1;
461 *minor_version = -1; 467 *minor_version = -1;
462 *status = 0; 468 *status = 0;
463 *msg = NULL; 469 *msg = NULL;
@@ -470,7 +476,7 @@ int phr_parse_response(const char *buf_start, size_t len, int *minor_version, in
470 return r; 476 return r;
471 } 477 }
472 478
473 if ((buf = parse_response(buf, buf_end, minor_version, status, msg, msg_len, headers, num_headers, max_headers, &r)) == NULL) { 479 if ((buf = parse_response(buf, buf_end, major_version, minor_version, status, msg, msg_len, headers, num_headers, max_headers, &r)) == NULL) {
474 return r; 480 return r;
475 } 481 }
476 482
diff --git a/plugins/picohttpparser/picohttpparser.h b/plugins/picohttpparser/picohttpparser.h
index 0849f84..8f13b36 100644
--- a/plugins/picohttpparser/picohttpparser.h
+++ b/plugins/picohttpparser/picohttpparser.h
@@ -49,10 +49,10 @@ struct phr_header {
49/* returns number of bytes consumed if successful, -2 if request is partial, 49/* returns number of bytes consumed if successful, -2 if request is partial,
50 * -1 if failed */ 50 * -1 if failed */
51int phr_parse_request(const char *buf, size_t len, const char **method, size_t *method_len, const char **path, size_t *path_len, 51int phr_parse_request(const char *buf, size_t len, const char **method, size_t *method_len, const char **path, size_t *path_len,
52 int *minor_version, struct phr_header *headers, size_t *num_headers, size_t last_len); 52 int *major_version, int *minor_version, struct phr_header *headers, size_t *num_headers, size_t last_len);
53 53
54/* ditto */ 54/* ditto */
55int phr_parse_response(const char *_buf, size_t len, int *minor_version, int *status, const char **msg, size_t *msg_len, 55int phr_parse_response(const char *_buf, size_t len, int *major_version, int *minor_version, int *status, const char **msg, size_t *msg_len,
56 struct phr_header *headers, size_t *num_headers, size_t last_len); 56 struct phr_header *headers, size_t *num_headers, size_t last_len);
57 57
58/* ditto */ 58/* ditto */