From 0f59dcf76fe0db77a4d73c11f6e9ce23d4b277ea Mon Sep 17 00:00:00 2001 From: reyk Date: Mon, 11 Aug 2008 08:07:14 +0000 Subject: [PATCH] better handling of HTTP POSTs or requests with Content-Length. --- usr.sbin/relayd/relay.c | 42 +++++++++++++++++++++++++--------------- usr.sbin/relayd/relayd.h | 21 ++++++++++---------- 2 files changed, 37 insertions(+), 26 deletions(-) diff --git a/usr.sbin/relayd/relay.c b/usr.sbin/relayd/relay.c index fb83a7cebb7..31bbb9649fa 100644 --- a/usr.sbin/relayd/relay.c +++ b/usr.sbin/relayd/relay.c @@ -1,4 +1,4 @@ -/* $OpenBSD: relay.c,v 1.102 2008/08/11 06:42:06 reyk Exp $ */ +/* $OpenBSD: relay.c,v 1.103 2008/08/11 08:07:14 reyk Exp $ */ /* * Copyright (c) 2006, 2007, 2008 Reyk Floeter @@ -1146,7 +1146,7 @@ relay_read_httpcontent(struct bufferevent *bev, void *arg) size_t size; if (gettimeofday(&con->se_tv_last, NULL) == -1) - goto done; + goto fail; size = EVBUFFER_LENGTH(src); DPRINTF("relay_read_httpcontent: size %d, to read %d", size, cre->toread); @@ -1161,7 +1161,7 @@ relay_read_httpcontent(struct bufferevent *bev, void *arg) size, cre->toread); if (con->se_done) goto done; - if (EVBUFFER_LENGTH(src) && bev->readcb != relay_read_httpcontent) + if (bev->readcb != relay_read_httpcontent) bev->readcb(bev, arg); bufferevent_enable(bev, EV_READ); return; @@ -1183,7 +1183,7 @@ relay_read_httpchunks(struct bufferevent *bev, void *arg) size_t size; if (gettimeofday(&con->se_tv_last, NULL) == -1) - goto done; + goto fail; size = EVBUFFER_LENGTH(src); DPRINTF("relay_read_httpchunks: size %d, to read %d", size, cre->toread); @@ -1282,11 +1282,15 @@ relay_read_http(struct bufferevent *bev, void *arg) size_t size; if (gettimeofday(&con->se_tv_last, NULL) == -1) - goto done; + goto fail; size = EVBUFFER_LENGTH(src); DPRINTF("relay_read_http: size %d, to read %d", size, cre->toread); - if (!size) - return; + if (!size) { + if (cre->dir == RELAY_DIR_RESPONSE) + return; + cre->toread = 0; + goto done; + } pk.type = NODE_TYPE_HEADER; @@ -1345,9 +1349,7 @@ relay_read_http(struct bufferevent *bev, void *arg) if (cre->dir == RELAY_DIR_RESPONSE) { cre->method = HTTP_METHOD_RESPONSE; goto lookup; - } else if (strcmp("GET", pk.key) == 0) - cre->method = HTTP_METHOD_GET; - else if (strcmp("HEAD", pk.key) == 0) + } else if (strcmp("HEAD", pk.key) == 0) cre->method = HTTP_METHOD_HEAD; else if (strcmp("POST", pk.key) == 0) cre->method = HTTP_METHOD_POST; @@ -1361,6 +1363,10 @@ relay_read_http(struct bufferevent *bev, void *arg) cre->method = HTTP_METHOD_TRACE; else if (strcmp("CONNECT", pk.key) == 0) cre->method = HTTP_METHOD_CONNECT; + else { + /* Use GET method as the default */ + cre->method = HTTP_METHOD_GET; + } /* * Decode the path and query @@ -1496,6 +1502,9 @@ relay_read_http(struct bufferevent *bev, void *arg) } switch (cre->method) { + case HTTP_METHOD_NONE: + relay_close_http(con, 406, "no method", 0); + return; case HTTP_METHOD_CONNECT: /* Data stream */ bev->readcb = relay_read; @@ -1526,12 +1535,14 @@ relay_read_http(struct bufferevent *bev, void *arg) /* Write empty newline and switch to relay mode */ if (relay_bufferevent_print(cre->dst, "\r\n") == -1) goto fail; + cre->line = 0; cre->method = 0; cre->done = 0; cre->chunked = 0; - if (cre->dir == RELAY_DIR_REQUEST && + done: + if (cre->dir == RELAY_DIR_REQUEST && !cre->toread && proto->lateconnect && cre->dst->bev == NULL) { if (rlay->rl_conf.fwdmode == FWD_TRANS) { relay_bindanyreq(con, 0, IPPROTO_TCP); @@ -1542,15 +1553,14 @@ relay_read_http(struct bufferevent *bev, void *arg) return; } } - if (con->se_done) - goto done; + if (con->se_done) { + relay_close(con, "last http read (done)"); + return; + } if (EVBUFFER_LENGTH(src) && bev->readcb != relay_read_http) bev->readcb(bev, arg); bufferevent_enable(bev, EV_READ); return; - done: - relay_close(con, "last http read (done)"); - return; fail: relay_close_http(con, 500, strerror(errno), 0); return; diff --git a/usr.sbin/relayd/relayd.h b/usr.sbin/relayd/relayd.h index 30143f13b9f..e9a527999d4 100644 --- a/usr.sbin/relayd/relayd.h +++ b/usr.sbin/relayd/relayd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: relayd.h,v 1.109 2008/07/22 23:17:37 reyk Exp $ */ +/* $OpenBSD: relayd.h,v 1.110 2008/08/11 08:07:14 reyk Exp $ */ /* * Copyright (c) 2006, 2007 Pierre-Yves Ritschard @@ -227,15 +227,16 @@ struct ctl_tcp_event { }; enum httpmethod { - HTTP_METHOD_GET = 0, - HTTP_METHOD_HEAD = 1, - HTTP_METHOD_POST = 2, - HTTP_METHOD_PUT = 3, - HTTP_METHOD_DELETE = 4, - HTTP_METHOD_OPTIONS = 5, - HTTP_METHOD_TRACE = 6, - HTTP_METHOD_CONNECT = 7, - HTTP_METHOD_RESPONSE = 8 /* Server response */ + HTTP_METHOD_NONE = 0, + HTTP_METHOD_GET = 1, + HTTP_METHOD_HEAD = 2, + HTTP_METHOD_POST = 3, + HTTP_METHOD_PUT = 4, + HTTP_METHOD_DELETE = 5, + HTTP_METHOD_OPTIONS = 6, + HTTP_METHOD_TRACE = 7, + HTTP_METHOD_CONNECT = 8, + HTTP_METHOD_RESPONSE = 9 /* Server response */ }; enum direction { -- 2.20.1