dovecot-2.2: lib-http: Adjusted response and request parsers to ...

dovecot at dovecot.org dovecot at dovecot.org
Sun Sep 15 03:38:25 EEST 2013


details:   http://hg.dovecot.org/dovecot-2.2/rev/adb4d013073d
changeset: 16740:adb4d013073d
user:      Stephan Bosch <stephan at rename-it.nl>
date:      Sun Sep 15 03:36:18 2013 +0300
description:
lib-http: Adjusted response and request parsers to accept a request/response object to fill with data, rather than have it return one.

diffstat:

 src/lib-http/http-client-connection.c    |  24 +++++++++---------
 src/lib-http/http-request-parser.c       |  29 ++++++++++++----------
 src/lib-http/http-request-parser.h       |   2 +-
 src/lib-http/http-response-parser.c      |  40 +++++++++++++++++--------------
 src/lib-http/http-response-parser.h      |   2 +-
 src/lib-http/test-http-response-parser.c |  11 ++++----
 src/lib-http/test-http-server.c          |   9 ++++---
 7 files changed, 62 insertions(+), 55 deletions(-)

diffs (truncated from 345 to 300 lines):

diff -r a6ed95a30cb1 -r adb4d013073d src/lib-http/http-client-connection.c
--- a/src/lib-http/http-client-connection.c	Sun Sep 15 03:35:04 2013 +0300
+++ b/src/lib-http/http-client-connection.c	Sun Sep 15 03:36:18 2013 +0300
@@ -488,7 +488,7 @@
 {
 	struct http_client_connection *conn =
 		(struct http_client_connection *)_conn;
-	struct http_response *response;
+	struct http_response response;
 	struct http_client_request *const *req_idx;
 	struct http_client_request *req = NULL;
 	int finished = 0, ret;
@@ -547,7 +547,7 @@
 		   (Continue) status message.  Unexpected 1xx status responses MAY be
 		   ignored by a user agent.
 		 */
-		if (req->payload_sync && response->status == 100) {
+		if (req->payload_sync && response.status == 100) {
 			if (conn->payload_continue) {
 				http_client_connection_debug(conn,
 					"Got 100-continue response after timeout");
@@ -564,16 +564,16 @@
 					t_strdup_printf("Failed to send request: %s", error));
 			}
 			return;
-		} else if (response->status / 100 == 1) {
+		} else if (response.status / 100 == 1) {
 			/* ignore them for now */
 			http_client_connection_debug(conn,
-				"Got unexpected %u response; ignoring", response->status);
+				"Got unexpected %u response; ignoring", response.status);
 			continue;
 		} 
 
 		http_client_connection_debug(conn,
 			"Got %u response for request %s",
-			response->status, http_client_request_label(req));
+			response.status, http_client_request_label(req));
 
 		/* remove request from queue */
 		array_delete(&conn->request_wait_list, 0, 1);
@@ -581,25 +581,25 @@
 		i_assert(req->refcount > 1 || aborted);
 		http_client_request_unref(&req);
 		
-		conn->close_indicated = response->connection_close;
+		conn->close_indicated = response.connection_close;
 		if (req->payload_sync && !conn->payload_continue)
 			conn->output_locked = FALSE;	
 
 		if (!aborted) {
-			if (response->status == 417 && req->payload_sync) {
+			if (response.status == 417 && req->payload_sync) {
 				/* drop Expect: continue */
 				req->payload_sync = FALSE;
 				conn->output_locked = FALSE;
 				conn->peer->no_payload_sync = TRUE;
-				http_client_request_retry(req, response->status, response->reason);
+				http_client_request_retry(req, response.status, response.reason);
 	
-			} else if (response->status / 100 == 3 && response->status != 304 &&
-				response->location != NULL) {
+			} else if (response.status / 100 == 3 && response.status != 304 &&
+				response.location != NULL) {
 				/* redirect */
-				http_client_request_redirect(req, response->status, response->location);
+				http_client_request_redirect(req, response.status, response.location);
 			} else {
 				/* response for application */
-				if (!http_client_connection_return_response(conn, req, response))
+				if (!http_client_connection_return_response(conn, req, &response))
 					return;
 			}
 
diff -r a6ed95a30cb1 -r adb4d013073d src/lib-http/http-request-parser.c
--- a/src/lib-http/http-request-parser.c	Sun Sep 15 03:35:04 2013 +0300
+++ b/src/lib-http/http-request-parser.c	Sun Sep 15 03:36:18 2013 +0300
@@ -23,7 +23,8 @@
 	struct http_message_parser parser;
 	enum http_request_parser_state state;
 
-	struct http_request request;
+	const char *request_method;
+	const char *request_target;
 
 	unsigned int skipping_line:1;
 };
@@ -49,7 +50,8 @@
 http_request_parser_restart(struct http_request_parser *parser)
 {
 	http_message_parser_restart(&parser->parser);
-	memset(&parser->request, 0, sizeof(parser->request));
+	parser->request_method = NULL;
+	parser->request_target = NULL;
 }
 
 static int http_request_parse_method(struct http_request_parser *parser)
@@ -63,7 +65,7 @@
 
 	if (p == parser->parser.end)
 		return 0;
-	parser->request.method =
+	parser->request_method =
 		p_strdup_until(parser->parser.msg_pool, parser->parser.cur, p);
 	parser->parser.cur = p;
 	return 1;
@@ -82,7 +84,7 @@
 
 	if (p == parser->parser.end)
 		return 0;
-	parser->request.target =
+	parser->request_target =
 		p_strdup_until(parser->parser.msg_pool, parser->parser.cur, p);
 	parser->parser.cur = p;
 	return 1;
@@ -246,7 +248,7 @@
 }
 
 int http_request_parse_next(struct http_request_parser *parser,
-			    struct http_request **request_r,
+			    struct http_request *request,
 			    const char **error_r)
 {
 	int ret;
@@ -271,13 +273,14 @@
 		return -1;
 	parser->state = HTTP_REQUEST_PARSE_STATE_INIT;
 
-	parser->request.version_major = parser->parser.msg.version_major;
-	parser->request.version_minor = parser->parser.msg.version_minor;
-	parser->request.date = parser->parser.msg.date;
-	parser->request.payload = parser->parser.payload;
-	parser->request.headers = parser->parser.msg.headers;
-	parser->request.connection_close = parser->parser.msg.connection_close;
-
-	*request_r = &parser->request;
+	memset(request, 0, sizeof(*request));
+	request->method = parser->request_method;
+	request->target = 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;
+	request->payload = parser->parser.payload;
+	request->headers = parser->parser.msg.headers;
+	request->connection_close = parser->parser.msg.connection_close;
 	return 1;
 }
diff -r a6ed95a30cb1 -r adb4d013073d src/lib-http/http-request-parser.h
--- a/src/lib-http/http-request-parser.h	Sun Sep 15 03:35:04 2013 +0300
+++ b/src/lib-http/http-request-parser.h	Sun Sep 15 03:36:18 2013 +0300
@@ -23,7 +23,7 @@
 void http_request_parser_deinit(struct http_request_parser **_parser);
 
 int http_request_parse_next(struct http_request_parser *parser,
-			    struct http_request **request_r,
+			    struct http_request *request,
 			    const char **error_r);
 
 #endif
diff -r a6ed95a30cb1 -r adb4d013073d src/lib-http/http-response-parser.c
--- a/src/lib-http/http-response-parser.c	Sun Sep 15 03:35:04 2013 +0300
+++ b/src/lib-http/http-response-parser.c	Sun Sep 15 03:36:18 2013 +0300
@@ -24,7 +24,8 @@
 	struct http_message_parser parser;
 	enum http_response_parser_state state;
 
-	struct http_response response;
+	unsigned int response_status;
+	const char *response_reason;
 };
 
 struct http_response_parser *http_response_parser_init(struct istream *input)
@@ -48,7 +49,8 @@
 http_response_parser_restart(struct http_response_parser *parser)
 {
 	http_message_parser_restart(&parser->parser);
-	memset(&parser->response, 0, sizeof(parser->response));
+	parser->response_status = 0;
+	parser->response_reason = NULL;
 }
 
 static int http_response_parse_status(struct http_response_parser *parser)
@@ -62,7 +64,7 @@
 		return 0;
 	if (!i_isdigit(p[0]) || !i_isdigit(p[1]) || !i_isdigit(p[2]))
 		return -1;
-	parser->response.status =
+	parser->response_status =
 		(p[0] - '0')*100 + (p[1] - '0')*10 + (p[2] - '0');
 	parser->parser.cur += 3;
 	return 1;
@@ -74,12 +76,13 @@
 
 	/* reason-phrase = *( HTAB / SP / VCHAR / obs-text )
 	 */
+	// FIXME: limit length
 	while (p < parser->parser.end && http_char_is_text(*p))
 		p++;
 
 	if (p == parser->parser.end)
 		return 0;
-	parser->response.reason =
+	parser->response_reason =
 		p_strdup_until(parser->parser.msg_pool, parser->parser.cur, p);
 	parser->parser.cur = p;
 	return 1;
@@ -223,7 +226,7 @@
 }
 
 int http_response_parse_next(struct http_response_parser *parser,
-			     bool no_payload, struct http_response **response_r,
+			     bool no_payload, struct http_response *response,
 			     const char **error_r)
 {
 	int ret;
@@ -251,11 +254,11 @@
 	   A server MUST NOT send a Content-Length header field in any response
 	   with a status code of 1xx (Informational) or 204 (No Content). [...]
 	 */
-	if ((parser->response.status / 100 == 1 || parser->response.status == 204) &&
+	if ((parser->response_status / 100 == 1 || parser->response_status == 204) &&
 	    parser->parser.msg.content_length > 0) {
 		*error_r = t_strdup_printf(
 			"Unexpected Content-Length header field for %u response "
-			"(length=%"PRIuUOFF_T")", parser->response.status,
+			"(length=%"PRIuUOFF_T")", parser->response_status,
 			parser->parser.msg.content_length);
 		return -1;
 	}
@@ -269,8 +272,8 @@
 	   header fields, regardless of the header fields present in the
 	   message, and thus cannot contain a message body.
 	 */
-	if (parser->response.status / 100 == 1 || parser->response.status == 204
-		|| parser->response.status == 304) { // HEAD is handled in caller
+	if (parser->response_status / 100 == 1 || parser->response_status == 204
+		|| parser->response_status == 304) { // HEAD is handled in caller
 		no_payload = TRUE;
 	}
 
@@ -281,14 +284,15 @@
 	}
 	parser->state = HTTP_RESPONSE_PARSE_STATE_INIT;
 
-	parser->response.version_major = parser->parser.msg.version_major;
-	parser->response.version_minor = parser->parser.msg.version_minor;
-	parser->response.location = parser->parser.msg.location;
-	parser->response.date = parser->parser.msg.date;
-	parser->response.payload = parser->parser.payload;
-	parser->response.headers = parser->parser.msg.headers;
-	parser->response.connection_close = parser->parser.msg.connection_close;
-
-	*response_r = &parser->response;
+	memset(response, 0, sizeof(*response));
+	response->status = parser->response_status;
+	response->reason = parser->response_reason;
+	response->version_major = parser->parser.msg.version_major;
+	response->version_minor = parser->parser.msg.version_minor;
+	response->location = parser->parser.msg.location;
+	response->date = parser->parser.msg.date;
+	response->payload = parser->parser.payload;
+	response->headers = parser->parser.msg.headers;
+	response->connection_close = parser->parser.msg.connection_close;
 	return 1;
 }
diff -r a6ed95a30cb1 -r adb4d013073d src/lib-http/http-response-parser.h
--- a/src/lib-http/http-response-parser.h	Sun Sep 15 03:35:04 2013 +0300
+++ b/src/lib-http/http-response-parser.h	Sun Sep 15 03:36:18 2013 +0300
@@ -10,7 +10,7 @@
 void http_response_parser_deinit(struct http_response_parser **_parser);
 
 int http_response_parse_next(struct http_response_parser *parser,
-			     bool no_payload, struct http_response **response_r,
+			     bool no_payload, struct http_response *response,
 			     const char **error_r);
 
 #endif
diff -r a6ed95a30cb1 -r adb4d013073d src/lib-http/test-http-response-parser.c
--- a/src/lib-http/test-http-response-parser.c	Sun Sep 15 03:35:04 2013 +0300
+++ b/src/lib-http/test-http-response-parser.c	Sun Sep 15 03:36:18 2013 +0300
@@ -99,7 +99,7 @@
 		struct ostream *output;
 		const struct http_response_parse_test *test;
 		struct http_response_parser *parser;
-		struct http_response *response = NULL;
+		struct http_response response;
 		const char *response_text, *payload, *error;
 		unsigned int pos, response_text_len;
 		int ret = 0;
@@ -119,11 +119,11 @@
 		}
 		test_istream_set_size(input, response_text_len);
 		while (ret > 0) {
-			if (response->payload != NULL) {
+			if (response.payload != NULL) {
 				buffer_set_used_size(payload_buffer, 0);
 				output = o_stream_create_buffer(payload_buffer);
 				test_out("payload receive", 
-					o_stream_send_istream(output, response->payload));
+					o_stream_send_istream(output, response.payload));


More information about the dovecot-cvs mailing list