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