summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Orton <jorton@redhat.com>2021-09-17 14:57:34 +0100
committerJoe Orton <jorton@redhat.com>2021-09-17 15:05:38 +0100
commit25819517f0a4f92d89f38d43012e7ba89fa900ee (patch)
treed946887e36f540115bc8e0aa0bb20685a724f4b1
parentb13393cde9de595b206c8f6b0277515d9b5b4182 (diff)
downloadneon-git-excess-1xx.tar.gz
* src/ne_request.c (send_request): Limit number of interim responsesexcess-1xx
which can be read to 128. * test/request.c (fail_excess_1xx): New test case.
-rw-r--r--src/ne_request.c15
-rw-r--r--test/request.c8
2 files changed, 20 insertions, 3 deletions
diff --git a/src/ne_request.c b/src/ne_request.c
index 6bed814..9e06b96 100644
--- a/src/ne_request.c
+++ b/src/ne_request.c
@@ -72,6 +72,8 @@ struct field {
struct field *next;
};
+/* Maximum number of interim responses. */
+#define MAX_INTERIM_RESPONSES (128)
/* Maximum number of header fields per response: */
#define MAX_HEADER_FIELDS (100)
/* Size of hash table; 43 is the smallest prime for which the common
@@ -1015,6 +1017,7 @@ static int send_request(ne_request *req, const ne_buffer *request)
ne_status *const status = &req->status;
int sentbody = 0; /* zero until body has been sent. */
int ret, retry; /* retry non-zero whilst the request should be retried */
+ unsigned count;
ssize_t sret;
/* Send the Request-Line and headers */
@@ -1045,9 +1048,11 @@ static int send_request(ne_request *req, const ne_buffer *request)
/* Loop eating interim 1xx responses; RFC 7231ยง6.2 says clients
* MUST be able to parse unsolicited interim responses. */
- while ((ret = read_status_line(req, status, retry)) == NE_OK
- && status->klass == 1) {
- NE_DEBUG(NE_DBG_HTTP, "Interim %d response.\n", status->code);
+ for (count = 0; count < MAX_INTERIM_RESPONSES
+ && (ret = read_status_line(req, status, retry)) == NE_OK
+ && status->klass == 1; count++) {
+ NE_DEBUG(NE_DBG_HTTP, "[req] Interim %d response %d.\n",
+ status->code, count);
retry = 0; /* successful read() => never retry now. */
/* Discard headers with the interim response. */
if ((ret = discard_headers(req)) != NE_OK) break;
@@ -1060,6 +1065,10 @@ static int send_request(ne_request *req, const ne_buffer *request)
}
}
+ if (count == MAX_INTERIM_RESPONSES) {
+ return aborted(req, _("Too many interim responses"), 0);
+ }
+
return ret;
}
diff --git a/test/request.c b/test/request.c
index 6805024..e663d6d 100644
--- a/test/request.c
+++ b/test/request.c
@@ -2345,6 +2345,13 @@ static int safe_flags(void)
return OK;
}
+static int fail_excess_1xx(void)
+{
+ struct s1xx_args args = {200, 0};
+ return fail_request_with_error(0, serve_1xx, &args, 0,
+ "Too many interim responses");
+}
+
/* TODO: test that ne_set_notifier(, NULL, NULL) DTRT too. */
ne_test tests[] = {
@@ -2439,5 +2446,6 @@ ne_test tests[] = {
T(fail_lookup),
T(fail_double_lookup),
T(safe_flags),
+ T(fail_excess_1xx),
T(NULL)
};