Hello, Here is patch to add "host" header to outgoing HTTP/1.1 requests. Please, review.
Without the patch libevent-based evhttp-client.c can't get reply from any sane server because the request is rejected with "400 Bad request" and workaround - adding the header manually - is required. -- WBRBW, Leonid Evdokimov xmpp:l...@darkk.net.ru && http://darkk.net.ru tel:+79816800702 && tel:+79050965222
#include <event2/event.h> #include <event2/dns.h> #include <event2/http.h> #include <sys/queue.h> #include <event2/keyvalq_struct.h> /* ugly :( */ #include <stdlib.h> #include <stdio.h> void httpcb(struct evhttp_request *req, void *arg) { struct evkeyvalq *ihead = evhttp_request_get_input_headers(req); struct evkeyvalq *ohead = evhttp_request_get_output_headers(req); struct evkeyval *h; printf("%s %s HTTP/x.x\n", evhttp_request_get_command(req) == EVHTTP_REQ_GET ? "GET" : "...", evhttp_request_get_uri(req)); TAILQ_FOREACH(h, ohead, next) { printf("%s: %s\n", h->key, h->value); } printf("\n"); printf("HTTP/x.x %d ...\n", evhttp_request_get_response_code(req)); TAILQ_FOREACH(h, ihead, next) { printf("%s: %s\n", h->key, h->value); } printf("\n"); event_base_loopbreak(arg); } int main(int argc, char* argv[]) { if (argc != 4) { printf("Usage: %s <host> <port> <path>\n", argv[0]); return 1; } struct event_base* evbase = event_base_new(); struct evdns_base *evdns = evdns_base_new(evbase, 1); struct evhttp_connection *conn = evhttp_connection_base_new (evbase, evdns, argv[1], atoi(argv[2])); evhttp_connection_set_timeout(conn, 10); struct evhttp_request* req = evhttp_request_new(httpcb, evbase); /* @see 0006-Add-Host-header-in-HTTP-1.1-requests-if-it-s-missing.patch * struct evkeyvalq *hout = evhttp_request_get_output_headers(req); * evhttp_add_header, (hout, "Host", "example.org:8080"); */ evhttp_make_request(conn, req, EVHTTP_REQ_GET, argv[3]); event_base_loop(evbase, 0); /* NB: it's not cleaned up during event_base_free */ evhttp_connection_free(conn); /* evdns_base_free is called during event_base_free, but noone should rely * on that */ const int send_err_shutdown = 0; evdns_base_free(evdns, send_err_shutdown); event_base_free(evbase); return 0; }
From a87fc928f7a61ca691861154ffd9ba3e6aec0397 Mon Sep 17 00:00:00 2001 From: Leonid Evdokimov <da...@yandex-team.ru> Date: Fri, 19 Aug 2011 14:47:20 +0400 Subject: [PATCH 6/6] Add Host header in HTTP/1.1 requests if it's missing. --- http.c | 12 ++++++++++++ 1 files changed, 12 insertions(+), 0 deletions(-) diff --git a/http.c b/http.c index 58fef16..823bf19 100644 --- a/http.c +++ b/http.c @@ -456,6 +456,18 @@ evhttp_make_header_request(struct evhttp_connection *evcon, "%s %s HTTP/%d.%d\r\n", method, req->uri, req->major, req->minor); + if (req->major == 1 && req->minor >= 1 && + evhttp_find_header(req->output_headers, "Host") == NULL) { + if (evcon->port == 80) { + evhttp_add_header(req->output_headers, "Host", evcon->address); + } + else { + char host[255 + 1 + 5 + 1]; + evutil_snprintf(host, sizeof(host), "%s:%u", evcon->address, evcon->port); + evhttp_add_header(req->output_headers, "Host", host); + } + } + /* Add the content length on a post or put request if missing */ if ((req->type == EVHTTP_REQ_POST || req->type == EVHTTP_REQ_PUT) && evhttp_find_header(req->output_headers, "Content-Length") == NULL){ -- 1.7.4.1