fielding 98/07/21 22:48:21
Modified: src CHANGES
src/main http_protocol.c
Log:
Fixed problem with buffered response message not being sent for
the read_request error conditions of URI-too-long (414) and
malformed header fields (400). We now create enough of the request
record so that it is adequately logged as well.
PR: 2646 from Jim Gettys
Revision Changes Path
1.976 +4 -0 apache-1.3/src/CHANGES
Index: CHANGES
===================================================================
RCS file: /home/cvs/apache-1.3/src/CHANGES,v
retrieving revision 1.975
retrieving revision 1.976
diff -u -r1.975 -r1.976
--- CHANGES 1998/07/21 15:39:40 1.975
+++ CHANGES 1998/07/22 05:48:19 1.976
@@ -1,5 +1,9 @@
Changes with Apache 1.3.2
+ *) Fixed problem with buffered response message not being sent for
+ the read_request error conditions of URI-too-long (414) and
+ malformed header fields (400). [Roy Fielding] PR#2646
+
*) Add support for the Max-Forwards: header line required by RFC2068 for
the TRACE method. This allows apache to TRACE along a chain of proxies
up to a predetermined depth. [Martin Kraemer]
1.226 +48 -46 apache-1.3/src/main/http_protocol.c
Index: http_protocol.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/main/http_protocol.c,v
retrieving revision 1.225
retrieving revision 1.226
diff -u -r1.225 -r1.226
--- http_protocol.c 1998/07/19 05:55:16 1.225
+++ http_protocol.c 1998/07/22 05:48:21 1.226
@@ -656,20 +656,9 @@
/* we've probably got something to do, ignore graceful restart requests
*/
#ifdef SIGUSR1
signal(SIGUSR1, SIG_IGN);
-#endif /* SIGUSR1 */
+#endif
+
ap_bsetflag(conn->client, B_SAFEREAD, 0);
- if (len == (HUGE_STRING_LEN - 1)) {
- ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r->server,
- "request failed for %s, reason: URI too long",
- ap_get_remote_host(r->connection, r->per_dir_config,
REMOTE_NAME));
- /* hack to deal with the HTTP_REQUEST_TIME_OUT setting up above: */
- if (r->status == HTTP_REQUEST_TIME_OUT) {
- r->status = HTTP_OK;
- }
- r->request_time = time(NULL);
- ap_die (HTTP_REQUEST_URI_TOO_LARGE, r);
- return 0;
- }
r->request_time = time(NULL);
r->the_request = ap_pstrdup(r->pool, l);
@@ -700,8 +689,16 @@
ap_parse_uri(r, uri);
+ if (len == (HUGE_STRING_LEN - 1)) {
+ r->status = HTTP_REQUEST_URI_TOO_LARGE;
+ r->proto_num = HTTP_VERSION(1,0);
+ r->protocol = ap_pstrdup(r->pool, "HTTP/1.0");
+ return 0;
+ }
+
r->assbackwards = (ll[0] == '\0');
r->protocol = ap_pstrdup(r->pool, ll[0] ? ll : "HTTP/0.9");
+
if (2 == sscanf(r->protocol, "HTTP/%u.%u", &major, &minor)
&& minor < HTTP_VERSION(1,0)) /* don't allow HTTP/0.1000 */
r->proto_num = HTTP_VERSION(major, minor);
@@ -725,23 +722,15 @@
while ((len = getline(field, MAX_STRING_LEN, c->client, 1)) > 0) {
char *copy = ap_palloc(r->pool, len + 1);
memcpy(copy, field, len + 1);
-
- if (!(value = strchr(copy, ':'))) { /* Find the colon separator */
- /* if there's none, this request is screwed up.
- * a hack to deal with how we set HTTP_REQUEST_TIME_OUT earlier.*/
- if (r->status == HTTP_REQUEST_TIME_OUT)
- r->status = HTTP_OK;
-
- ap_die (HTTP_BAD_REQUEST, r);
- return;
- }
+
+ if (!(value = strchr(copy, ':'))) { /* Find the colon separator
*/
+ r->status = HTTP_BAD_REQUEST; /* or abort the bad request
*/
+ return;
+ }
*value = '\0';
++value;
- /* XXX: RFC2068 defines only SP and HT as whitespace, this test is
- * wrong... and so are many others probably.
- */
- while (ap_isspace(*value))
+ while (*value == ' ' || *value == '\t')
++value; /* Skip to start of value */
/* XXX: should strip trailing whitespace as well */
@@ -754,7 +743,7 @@
>= MAX_STRING_LEN - 1) {
/* soak up the extra data */
}
- if (len == 0) /* time to exit the larger loop as well */
+ if (len <= 0) /* time to exit the larger loop as well */
break;
}
}
@@ -796,34 +785,47 @@
r->status = HTTP_REQUEST_TIME_OUT; /* Until we get a request */
r->the_request = NULL;
- /* Get the request... */
-
#ifdef CHARSET_EBCDIC
ap_bsetflag(r->connection->client, B_ASCII2EBCDIC|B_EBCDIC2ASCII, 1);
-#endif /* CHARSET_EBCDIC */
+#endif
+
+ /* Get the request... */
+
ap_keepalive_timeout("read request line", r);
if (!read_request_line(r)) {
ap_kill_timeout(r);
- if (r->status != HTTP_REQUEST_TIME_OUT) {
- /* we must have had an error.*/
- ap_log_transaction(r);
- }
+ if (r->status == HTTP_REQUEST_URI_TOO_LARGE) {
+
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r->server,
+ "request failed for %s, reason: URI too long",
+ ap_get_remote_host(r->connection, r->per_dir_config,
+ REMOTE_NAME));
+ ap_send_error_response(r, 0);
+ ap_bflush(r->connection->client);
+ ap_log_transaction(r);
+ }
+ r->connection->aborted = 1;
return NULL;
}
if (!r->assbackwards) {
ap_hard_timeout("read request headers", r);
get_mime_headers(r);
- if (r->status != HTTP_REQUEST_TIME_OUT) {/* we must have had an
error.*/
- ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r->server,
- "request failed for %s: error reading the headers",
- ap_get_remote_host(r->connection, r->per_dir_config,
- REMOTE_NAME));
- ap_log_transaction(r);
- return NULL;
- }
-
+ ap_kill_timeout(r);
+ if (r->status != HTTP_REQUEST_TIME_OUT) {
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r->server,
+ "request failed for %s: error reading the headers",
+ ap_get_remote_host(r->connection,
r->per_dir_config,
+ REMOTE_NAME));
+ ap_send_error_response(r, 0);
+ ap_bflush(r->connection->client);
+ ap_log_transaction(r);
+ r->connection->aborted = 1;
+ return NULL;
+ }
+ }
+ else {
+ ap_kill_timeout(r);
}
- ap_kill_timeout(r);
r->status = HTTP_OK; /* Until further notice. */
@@ -839,7 +841,7 @@
if ((access_status = ap_run_post_read_request(r))) {
ap_die(access_status, r);
- ap_log_transaction(r);
+ ap_log_transaction(r);
return NULL;
}