dovecot-2.2: lib-http: Adjusted request parser to pre-parse the ...

dovecot at dovecot.org dovecot at dovecot.org
Sun Sep 15 03:50:34 EEST 2013


details:   http://hg.dovecot.org/dovecot-2.2/rev/eeaa68773f73
changeset: 16748:eeaa68773f73
user:      Stephan Bosch <stephan at rename-it.nl>
date:      Sun Sep 15 03:47:54 2013 +0300
description:
lib-http: Adjusted request parser to pre-parse the request target and host header into a proper target url.

diffstat:

 src/lib-http/http-request-parser.c |  30 +++++++++++++++++++++++++++++-
 src/lib-http/http-request.h        |   3 ++-
 src/lib-http/test-http-server.c    |   4 ++--
 3 files changed, 33 insertions(+), 4 deletions(-)

diffs (85 lines):

diff -r 29ceb7126b91 -r eeaa68773f73 src/lib-http/http-request-parser.c
--- a/src/lib-http/http-request-parser.c	Sun Sep 15 03:47:29 2013 +0300
+++ b/src/lib-http/http-request-parser.c	Sun Sep 15 03:47:54 2013 +0300
@@ -2,6 +2,7 @@
 
 #include "lib.h"
 #include "istream.h"
+#include "http-url.h"
 #include "http-parser.h"
 #include "http-message-parser.h"
 #include "http-request-parser.h"
@@ -258,6 +259,8 @@
 			    pool_t pool, struct http_request *request,
 			    const char **error_r)
 {
+	const struct http_header_field *hdr;
+	const char *error;
 	int ret;
 
 	/* make sure we finished streaming payload from previous request
@@ -280,9 +283,34 @@
 		return -1;
 	parser->state = HTTP_REQUEST_PARSE_STATE_INIT;
 
+	/* https://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-23
+	     Section 5.4:
+
+	   A server MUST respond with a 400 (Bad Request) status code to any
+	   HTTP/1.1 request message that lacks a Host header field and to any
+	   request message that contains more than one Host header field or a
+	   Host header field with an invalid field-value.
+	 */
+	if ((ret=http_header_field_find_unique
+		(parser->parser.msg.header, "Host", &hdr)) <= 0) {
+		if (ret == 0)
+			*error_r = "Missing Host header";
+		else
+			*error_r = "Duplicate Host header";
+		return -1;
+	}
+
 	memset(request, 0, sizeof(*request));
+
+	if (http_url_request_target_parse(parser->request_target, hdr->value,
+		parser->parser.msg.pool, &request->target, &error) < 0) {
+		*error_r = t_strdup_printf("Bad request target `%s': %s",
+			parser->request_target, error);
+		return -1;
+	}
+
 	request->method = parser->request_method;
-	request->target = parser->request_target;
+	request->target_raw = parser->request_target;
 	request->version_major = parser->parser.msg.version_major;
 	request->version_minor = parser->parser.msg.version_minor;
 	request->date = parser->parser.msg.date;
diff -r 29ceb7126b91 -r eeaa68773f73 src/lib-http/http-request.h
--- a/src/lib-http/http-request.h	Sun Sep 15 03:47:29 2013 +0300
+++ b/src/lib-http/http-request.h	Sun Sep 15 03:47:54 2013 +0300
@@ -20,7 +20,8 @@
 struct http_request {
 	const char *method;
 
-	const char *target;
+	const char *target_raw;
+	struct http_request_target target;
 
 	unsigned char version_major;
 	unsigned char version_minor;
diff -r 29ceb7126b91 -r eeaa68773f73 src/lib-http/test-http-server.c
--- a/src/lib-http/test-http-server.c	Sun Sep 15 03:47:29 2013 +0300
+++ b/src/lib-http/test-http-server.c	Sun Sep 15 03:47:54 2013 +0300
@@ -37,10 +37,10 @@
 	}
 	str_append(str, "HTTP/1.1 200 OK\r\n");
 	str_printfa(str, "Date: %s\r\n", http_date_create(ioloop_time));
-	str_printfa(str, "Content-Length: %d\r\n", (int)strlen(request->target));
+	str_printfa(str, "Content-Length: %d\r\n", (int)strlen(request->target_raw));
 	str_append(str, "Content-Type: text/plain\r\n");
 	str_append(str, "\r\n");
-	str_append(str, request->target);
+	str_append(str, request->target_raw);
 	o_stream_send(client->conn.output, str_data(str), str_len(str));
 	return 0;
 }


More information about the dovecot-cvs mailing list