dovecot-2.2: lib-http: http-client: Allow overriding all implici...
dovecot at dovecot.org
dovecot at dovecot.org
Tue Sep 17 02:41:36 EEST 2013
details: http://hg.dovecot.org/dovecot-2.2/rev/145be4e876a8
changeset: 16758:145be4e876a8
user: Stephan Bosch <stephan at rename-it.nl>
date: Tue Sep 17 02:40:17 2013 +0300
description:
lib-http: http-client: Allow overriding all implicitly generated special headers.
Which are: Connection, Content-Length, Date, Expect, Host, and Transfer-Encoding.
diffstat:
src/lib-http/http-client-private.h | 6 +++
src/lib-http/http-client-request.c | 74 ++++++++++++++++++++++++++++---------
2 files changed, 62 insertions(+), 18 deletions(-)
diffs (127 lines):
diff -r a114a8bfce61 -r 145be4e876a8 src/lib-http/http-client-private.h
--- a/src/lib-http/http-client-private.h Mon Sep 16 13:17:52 2013 +0300
+++ b/src/lib-http/http-client-private.h Tue Sep 17 02:40:17 2013 +0300
@@ -69,6 +69,12 @@
enum http_request_state state;
+ unsigned int have_hdr_connection:1;
+ unsigned int have_hdr_date:1;
+ unsigned int have_hdr_expect:1;
+ unsigned int have_hdr_host:1;
+ unsigned int have_hdr_body_spec:1;
+
unsigned int payload_sync:1;
unsigned int payload_chunked:1;
unsigned int payload_wait:1;
diff -r a114a8bfce61 -r 145be4e876a8 src/lib-http/http-client-request.c
--- a/src/lib-http/http-client-request.c Mon Sep 16 13:17:52 2013 +0300
+++ b/src/lib-http/http-client-request.c Tue Sep 17 02:40:17 2013 +0300
@@ -151,10 +151,31 @@
const char *key, const char *value)
{
i_assert(req->state == HTTP_REQUEST_STATE_NEW);
- /* don't allow setting Date or Connection header directly;
- this is ignored for now for backwards compatibility */
- if (strcasecmp(key, "Date") == 0 || strcasecmp(key, "Connection") == 0)
- return;
+ /* mark presence of special headers */
+ switch (key[0]) {
+ case 'c': case 'C':
+ if (strcasecmp(key, "Connection") == 0)
+ req->have_hdr_connection = TRUE;
+ else if (strcasecmp(key, "Content-Length") == 0)
+ req->have_hdr_body_spec = TRUE;
+ break;
+ case 'd': case 'D':
+ if (strcasecmp(key, "Date") == 0)
+ req->have_hdr_date = TRUE;
+ break;
+ case 'e': case 'E':
+ if (strcasecmp(key, "Expect") == 0)
+ req->have_hdr_expect = TRUE;
+ break;
+ case 'h': case 'H':
+ if (strcasecmp(key, "Host") == 0)
+ req->have_hdr_host = TRUE;
+ break;
+ case 't': case 'T':
+ if (strcasecmp(key, "Transfer-Encoding") == 0)
+ req->have_hdr_body_spec = TRUE;
+ break;
+ }
str_printfa(req->headers, "%s: %s\r\n", key, value);
}
@@ -407,40 +428,57 @@
i_assert(!req->conn->output_locked);
i_assert(req->payload_output == NULL);
+ /* create request line */
str_append(rtext, req->method);
str_append(rtext, " ");
str_append(rtext, req->target);
- str_append(rtext, " HTTP/1.1\r\nHost: ");
- str_append(rtext, req->hostname);
- if ((!req->ssl &&req->port != HTTP_DEFAULT_PORT) ||
- (req->ssl && req->port != HTTPS_DEFAULT_PORT)) {
- str_printfa(rtext, ":%u", req->port);
+ str_append(rtext, " HTTP/1.1\r\n");
+
+ /* create special headers implicitly if not set explicitly using
+ http_client_request_add_header() */
+ if (!req->have_hdr_host) {
+ str_append(rtext, "Host: ");
+ str_append(rtext, req->hostname);
+ if ((!req->ssl &&req->port != HTTP_DEFAULT_PORT) ||
+ (req->ssl && req->port != HTTPS_DEFAULT_PORT)) {
+ str_printfa(rtext, ":%u", req->port);
+ }
+ str_append(rtext, "\r\n");
}
- str_append(rtext, "\r\nDate: ");
- str_append(rtext, http_date_create(req->date));
- str_append(rtext, "\r\n");
- if (req->payload_sync) {
+ if (!req->have_hdr_date) {
+ str_append(rtext, "Date: ");
+ str_append(rtext, http_date_create(req->date));
+ str_append(rtext, "\r\n");
+ }
+ if (!req->have_hdr_expect && req->payload_sync) {
str_append(rtext, "Expect: 100-continue\r\n");
}
if (req->payload_chunked) {
// FIXME: can't do this for a HTTP/1.0 server
- str_append(rtext, "Transfer-Encoding: chunked\r\n");
+ if (!req->have_hdr_body_spec)
+ str_append(rtext, "Transfer-Encoding: chunked\r\n");
req->payload_output =
http_transfer_chunked_ostream_create(output);
} else if (req->payload_input != NULL) {
/* send Content-Length if we have specified a payload,
even if it's 0 bytes. */
- str_printfa(rtext, "Content-Length: %"PRIuUOFF_T"\r\n",
- req->payload_size);
+ if (!req->have_hdr_body_spec) {
+ str_printfa(rtext, "Content-Length: %"PRIuUOFF_T"\r\n",
+ req->payload_size);
+ }
req->payload_output = output;
o_stream_ref(output);
}
- str_append(rtext, "Connection: Keep-Alive\r\n");
+ if (!req->have_hdr_connection)
+ str_append(rtext, "Connection: Keep-Alive\r\n");
+ /* request line + implicit headers */
iov[0].iov_base = str_data(rtext);
- iov[0].iov_len = str_len(rtext);
+ iov[0].iov_len = str_len(rtext);
+ /* explicit headers */
iov[1].iov_base = str_data(req->headers);
iov[1].iov_len = str_len(req->headers);
+ /* end of header */
iov[2].iov_base = "\r\n";
iov[2].iov_len = 2;
More information about the dovecot-cvs
mailing list