dovecot-2.2: lib-http: Unified http-request.h and http-response....

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/dca140149d80
changeset: 16744:dca140149d80
user:      Stephan Bosch <stephan at rename-it.nl>
date:      Sun Sep 15 03:44:42 2013 +0300
description:
lib-http: Unified http-request.h and http-response.h headers.
Renamed struct http_response_header to struct http_header_field,
encapsulated the array in struct http_header and put it all in
http-header.h/c Added inline utility functions for header querying and
getting response/request payload size.

diffstat:

 src/lib-http/Makefile.am            |   6 ++
 src/lib-http/http-client-request.c  |   4 +-
 src/lib-http/http-header.c          |  98 +++++++++++++++++++++++++++++++++++++
 src/lib-http/http-header.h          |  39 ++++++++++++++
 src/lib-http/http-message-parser.c  |  39 +++++---------
 src/lib-http/http-message-parser.h  |   6 +-
 src/lib-http/http-request-parser.c  |   2 +-
 src/lib-http/http-request-parser.h  |  18 +------
 src/lib-http/http-request.c         |  28 ++++++++++
 src/lib-http/http-request.h         |  55 ++++++++++++++++++++
 src/lib-http/http-response-parser.c |   3 +-
 src/lib-http/http-response.c        |  31 +++++++++++
 src/lib-http/http-response.h        |  54 +++++++++++++++++--
 13 files changed, 327 insertions(+), 56 deletions(-)

diffs (truncated from 565 to 300 lines):

diff -r d59ac8efc5af -r dca140149d80 src/lib-http/Makefile.am
--- a/src/lib-http/Makefile.am	Sun Sep 15 03:39:45 2013 +0300
+++ b/src/lib-http/Makefile.am	Sun Sep 15 03:44:42 2013 +0300
@@ -10,10 +10,13 @@
 	http-date.c \
 	http-url.c \
 	http-parser.c \
+	http-header.c \
 	http-header-parser.c \
 	http-transfer-chunked.c \
 	http-message-parser.c \
+	http-request.c \
 	http-request-parser.c \
+	http-response.c \
 	http-response-parser.c \
 	http-client-request.c \
 	http-client-connection.c \
@@ -25,9 +28,11 @@
 	http-date.h \
 	http-url.h \
 	http-parser.h \
+	http-header.h \
 	http-header-parser.h \
 	http-transfer.h \
 	http-message-parser.h \
+	http-request.h \
 	http-request-parser.h \
 	http-response.h \
 	http-response-parser.h \
@@ -84,6 +89,7 @@
 test_http_response_parser_LDADD = \
 	http-date.lo \
 	http-parser.lo \
+	http-header.lo \
 	http-header-parser.lo \
 	http-transfer-chunked.lo \
 	http-message-parser.lo \
diff -r d59ac8efc5af -r dca140149d80 src/lib-http/http-client-request.c
--- a/src/lib-http/http-client-request.c	Sun Sep 15 03:39:45 2013 +0300
+++ b/src/lib-http/http-client-request.c	Sun Sep 15 03:44:42 2013 +0300
@@ -513,9 +513,7 @@
 	if (callback != NULL) {
 		struct http_response response;
 
-		memset(&response, 0, sizeof(response));
-		response.status = status;
-		response.reason = error;
+		http_response_init(&response, status, error);
 		(void)callback(&response, req->context);
 	}
 }
diff -r d59ac8efc5af -r dca140149d80 src/lib-http/http-header.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-http/http-header.c	Sun Sep 15 03:44:42 2013 +0300
@@ -0,0 +1,98 @@
+/* Copyright (c) 2013 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "array.h"
+
+#include "http-header.h"
+
+struct http_header {
+	ARRAY_TYPE(http_header_field) fields;
+	/* FIXME: ARRAY(struct http_header_field *) *btree; */
+};
+
+struct http_header *
+http_header_create(pool_t pool, unsigned int init_count)
+{
+	struct http_header *header;
+
+	header = p_new(pool, struct http_header, 1);
+	p_array_init(&header->fields, pool, init_count);
+
+	return header;
+}
+
+const struct http_header_field *
+http_header_field_add(struct http_header *header,
+	const char *name, const unsigned char *data, size_t size)
+{
+	struct http_header_field *hfield;
+	pool_t pool = array_get_pool(&header->fields);
+	void *value;
+
+	hfield = array_append_space(&header->fields);
+	hfield->key = p_strdup(pool, name);
+	hfield->size = size;
+
+	value = p_malloc(pool, size+1);
+	memcpy(value, data, size);
+	hfield->value = (const char *)value;
+
+	return hfield;
+}
+
+void http_header_field_delete(struct http_header *header, const char *name)
+{
+	ARRAY_TYPE(http_header_field) *hfields = &header->fields;
+	const struct http_header_field *hfield;
+
+	array_foreach(hfields, hfield) {
+		if (http_header_field_is(hfield, name)) {
+			array_delete(hfields, array_foreach_idx(hfields, hfield), 1);
+		}
+	}
+}
+
+const ARRAY_TYPE(http_header_field) *
+http_header_get_fields(const struct http_header *header)
+{
+	return &header->fields;
+}
+
+const struct http_header_field *
+http_header_field_find(const struct http_header *header, const char *name)
+{
+	const struct http_header_field *hfield;
+
+	array_foreach(&header->fields, hfield) {
+		if (http_header_field_is(hfield, name))
+			return hfield;
+	}
+
+	return NULL;
+}
+
+const char *
+http_header_field_get(const struct http_header *header, const char *name)
+{
+	const struct http_header_field *hfield =
+		http_header_field_find(header, name);
+	return (hfield == NULL ? NULL : hfield->value);
+}
+
+int http_header_field_find_unique(const struct http_header *header,
+	const char *name, const struct http_header_field **hfield_r)
+{
+	const struct http_header_field *hfield, *hfield_found = NULL;
+
+	array_foreach(&header->fields, hfield) {
+		if (http_header_field_is(hfield, name)) {
+			if (hfield_found != NULL)
+				return -1;
+			hfield_found = hfield;
+		}
+	}
+
+	*hfield_r = hfield_found;
+	return (hfield_found == NULL ? 0 : 1);
+}
+
diff -r d59ac8efc5af -r dca140149d80 src/lib-http/http-header.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-http/http-header.h	Sun Sep 15 03:44:42 2013 +0300
@@ -0,0 +1,39 @@
+#ifndef HTTP_HEADER_H
+#define HTTP_HEADER_H
+
+struct http_header;
+
+struct http_header_field {
+	const char *key; /* FIXME: rename to 'name' for v2.3 */
+	const char *value;
+	size_t size;
+};
+ARRAY_DEFINE_TYPE(http_header_field, struct http_header_field);
+
+static inline bool http_header_field_is(const struct http_header_field *hfield,
+	const char *name)
+{
+	return (strcasecmp(hfield->key, name) == 0);
+}
+
+struct http_header *
+http_header_create(pool_t pool, unsigned int init_count);
+
+const struct http_header_field *
+http_header_field_add(struct http_header *header,
+	const char *name, const unsigned char *data, size_t size);
+void http_header_field_delete(struct http_header *header, const char *name);
+
+const ARRAY_TYPE(http_header_field) *
+http_header_get_fields(const struct http_header *header) ATTR_PURE;
+
+const struct http_header_field *
+http_header_field_find(const struct http_header *header, const char *name)
+	ATTR_PURE;
+const char *
+http_header_field_get(const struct http_header *header, const char *name)
+	ATTR_PURE;
+int http_header_field_find_unique(const struct http_header *header,
+	const char *name, const struct http_header_field **hfield_r) ATTR_PURE;
+
+#endif
diff -r d59ac8efc5af -r dca140149d80 src/lib-http/http-message-parser.c
--- a/src/lib-http/http-message-parser.c	Sun Sep 15 03:39:45 2013 +0300
+++ b/src/lib-http/http-message-parser.c	Sun Sep 15 03:44:42 2013 +0300
@@ -4,6 +4,7 @@
 #include "array.h"
 #include "istream.h"
 #include "http-parser.h"
+#include "http-header.h"
 #include "http-header-parser.h"
 #include "http-date.h"
 #include "http-transfer.h"
@@ -48,7 +49,7 @@
 		pool_ref(pool);
 	}
 	parser->msg.date = (time_t)-1;
-	p_array_init(&parser->msg.headers, parser->msg.pool, 32);
+	parser->msg.header = http_header_create(parser->msg.pool, 32);
 	p_array_init(&parser->msg.connection_options, parser->msg.pool, 4);
 }
 
@@ -93,19 +94,14 @@
 }
 
 static int
-http_message_parse_header(struct http_message_parser *parser, const char *name,
-			  const unsigned char *data, size_t size,
+http_message_parse_header(struct http_message_parser *parser,
+			  const char *name, const unsigned char *data, size_t size,
 			  const char **error_r)
 {
-	struct http_response_header *hdr;
+	const struct http_header_field *hdr;
 	struct http_parser hparser;
-	void *value;
 
-	hdr = array_append_space(&parser->msg.headers);
-	hdr->key = p_strdup(parser->msg.pool, name);
-	hdr->value = value = p_malloc(parser->msg.pool, size+1);
-	memcpy(value, data, size);
-	hdr->size = size;
+	hdr = http_header_field_add(parser->msg.header, name, data, size);
 
 	/* https://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-23
 	     Section 3.2.2:
@@ -284,20 +280,21 @@
 int http_message_parse_headers(struct http_message_parser *parser,
 			       const char **error_r)
 {
+	const unsigned char *field_data;
 	const char *field_name, *error;
-	const unsigned char *field_data;
 	size_t field_size;
 	int ret;
 
 	/* *( header-field CRLF ) CRLF */
-	while ((ret=http_header_parse_next_field
-		(parser->header_parser, &field_name, &field_data, &field_size, &error)) > 0) {
+	while ((ret=http_header_parse_next_field(parser->header_parser,
+		&field_name, &field_data, &field_size, &error)) > 0) {
 		if (field_name == NULL) {
 			/* EOH */
 			return 1;
 		}
-		if (http_message_parse_header(parser, field_name, field_data,
-					      field_size, error_r) < 0)
+
+		if (http_message_parse_header(parser,
+			field_name, field_data, field_size, error_r) < 0)
 			return -1;
 	}
 
@@ -378,17 +375,9 @@
        handled as an error.  A sender MUST remove the received Content-
        Length field prior to forwarding such a message downstream.
 		 */
-		if (parser->msg.have_content_length) {
-			ARRAY_TYPE(http_response_header) *headers = &parser->msg.headers;
-			const struct http_response_header *hdr;
+		if (parser->msg.have_content_length)
+			http_header_field_delete(parser->msg.header, "Content-Length");
 
-			array_foreach(headers, hdr) {
-				if (strcasecmp(hdr->key, "Content-Length") == 0) {
-					array_delete(headers, array_foreach_idx(headers, hdr), 1);
-					break;
-				}
-			}
-		}
 	} else if (parser->msg.content_length > 0) {
 		/* Got explicit message size from Content-Length: header */
 		parser->payload =
diff -r d59ac8efc5af -r dca140149d80 src/lib-http/http-message-parser.h
--- a/src/lib-http/http-message-parser.h	Sun Sep 15 03:39:45 2013 +0300
+++ b/src/lib-http/http-message-parser.h	Sun Sep 15 03:44:42 2013 +0300
@@ -4,15 +4,17 @@
 #include "http-response.h"
 #include "http-transfer.h"
 
+struct http_header;
+
 struct http_message {
 	pool_t pool;
 
 	unsigned int version_major;


More information about the dovecot-cvs mailing list