summaryrefslogtreecommitdiff
path: root/usr.sbin/relayd/relay.c
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2007-11-21 20:41:41 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2007-11-21 20:41:41 +0000
commitd503b83b86378532136eb72791a7e017cb925b21 (patch)
treecd7f50d3667612a403b092b19efe58fc0d4011e2 /usr.sbin/relayd/relay.c
parentffe92c33912140e7bcdb30e19b77c5ec1399c5b0 (diff)
move HTTP cookie and query lookup code from the into separate functions
(the if () else if () block was getting very big).
Diffstat (limited to 'usr.sbin/relayd/relay.c')
-rw-r--r--usr.sbin/relayd/relay.c213
1 files changed, 120 insertions, 93 deletions
diff --git a/usr.sbin/relayd/relay.c b/usr.sbin/relayd/relay.c
index 29c9c886f7c..10c2fbc75f6 100644
--- a/usr.sbin/relayd/relay.c
+++ b/usr.sbin/relayd/relay.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: relay.c,v 1.63 2007/11/21 20:01:45 reyk Exp $ */
+/* $OpenBSD: relay.c,v 1.64 2007/11/21 20:41:40 reyk Exp $ */
/*
* Copyright (c) 2006, 2007 Reyk Floeter <reyk@openbsd.org>
@@ -91,6 +91,8 @@ int relay_handle_http(struct ctl_relay_event *,
struct protonode *, struct protonode *,
struct protonode *, int);
void relay_read_http(struct bufferevent *, void *);
+int relay_lookup_query(struct ctl_relay_event *);
+int relay_lookup_cookie(struct ctl_relay_event *, const char *);
void relay_read_httpcontent(struct bufferevent *, void *);
void relay_read_httpchunks(struct bufferevent *, void *);
char *relay_expand_http(struct ctl_relay_event *, char *,
@@ -281,6 +283,8 @@ relay_shutdown(void)
void
relay_nodedebug(const char *name, struct protonode *pn)
{
+ const char *s;
+
if (pn->action == NODE_ACTION_NONE)
return;
@@ -315,12 +319,13 @@ relay_nodedebug(const char *name, struct protonode *pn)
pn->key);
break;
case NODE_ACTION_EXPECT:
- fprintf(stderr, "expect \"%s\" from \"%s\"",
- pn->value, pn->key);
- break;
case NODE_ACTION_FILTER:
- fprintf(stderr, "filter \"%s\" from \"%s\"",
- pn->value, pn->key);
+ s = pn->action == NODE_ACTION_EXPECT ? "expect" : "filter";
+ if (strcmp(pn->value, "*") == 0)
+ fprintf(stderr, "%s \"%s\"", s, pn->key);
+ else
+ fprintf(stderr, "%s \"%s\" from \"%s\"", s,
+ pn->value, pn->key);
break;
case NODE_ACTION_HASH:
fprintf(stderr, "hash \"%s\"", pn->key);
@@ -1211,7 +1216,7 @@ relay_read_http(struct bufferevent *bev, void *arg)
struct protocol *proto = rlay->proto;
struct evbuffer *src = EVBUFFER_INPUT(bev);
struct protonode *pn, pk, *proot, *pnv = NULL, pkv;
- char *line, *ptr, *val;
+ char *line;
int header = 0, ret, pass = 0;
const char *errstr;
size_t size;
@@ -1341,10 +1346,8 @@ relay_read_http(struct bufferevent *bev, void *arg)
PROTONODE_FOREACH(pnv, proot, entry) {
ret = relay_handle_http(cre, proot,
pnv, &pkv, 0);
- if (ret == PN_FAIL) {
- free(line);
- return;
- }
+ if (ret == PN_FAIL)
+ goto abort;
}
} else if ((cre->method == HTTP_METHOD_POST ||
cre->method == HTTP_METHOD_PUT ||
@@ -1360,8 +1363,7 @@ relay_read_http(struct bufferevent *bev, void *arg)
cre->toread = strtonum(pk.value, 1, INT_MAX, &errstr);
if (errstr) {
relay_close_http(con, 500, errstr);
- free(line);
- return;
+ goto abort;
}
}
lookup:
@@ -1377,82 +1379,13 @@ relay_read_http(struct bufferevent *bev, void *arg)
goto handle;
if (pn->flags & PNFLAG_LOOKUP_QUERY) {
- if (cre->path == NULL || cre->args == NULL ||
- strlen(cre->args) < 2 ||
- (val = strdup(cre->args)) == NULL)
- goto next;
- ptr = val;
- while (ptr != NULL && strlen(ptr)) {
- pkv.key = ptr;
- pkv.type = NODE_TYPE_QUERY;
- if ((ptr = strchr(ptr, '&')) != NULL)
- *ptr++ = '\0';
- if ((pkv.value =
- strchr(pkv.key, '=')) == NULL ||
- strlen(pkv.value) < 1)
- continue;
- *pkv.value++ = '\0';
-
- if ((proot = RB_FIND(proto_tree,
- cre->tree, &pkv)) == NULL)
- continue;
- PROTONODE_FOREACH(pnv, proot, entry) {
- ret = relay_handle_http(cre, proot,
- pnv, &pkv, 0);
- if (ret == PN_FAIL) {
- free(val);
- free(line);
- return;
- }
- }
- }
- free(val);
+ /* Lookup the HTTP query arguments */
+ if (relay_lookup_query(cre) == PN_FAIL)
+ goto abort;
} else if (pn->flags & PNFLAG_LOOKUP_COOKIE) {
- /*
- * Decode the HTTP cookies
- */
- val = strdup(pk.value);
- if (val == NULL)
- goto next;
-
- for (ptr = val; ptr != NULL && strlen(ptr);) {
- if (*ptr == ' ')
- *ptr++ = '\0';
- pkv.key = ptr;
- pkv.type = NODE_TYPE_COOKIE;
- if ((ptr = strchr(ptr, ';')) != NULL)
- *ptr++ = '\0';
- /*
- * XXX We do not handle attributes
- * ($Path, $Domain, or $Port)
- */
- if (*pkv.key == '$')
- continue;
-
- if ((pkv.value =
- strchr(pkv.key, '=')) == NULL ||
- strlen(pkv.value) < 1)
- continue;
- *pkv.value++ = '\0';
- if (*pkv.value == '"')
- *pkv.value++ = '\0';
- if (pkv.value[strlen(pkv.value) - 1] == '"')
- pkv.value[strlen(pkv.value) - 1] = '\0';
-
- if ((proot = RB_FIND(proto_tree,
- cre->tree, &pkv)) == NULL)
- continue;
- PROTONODE_FOREACH(pnv, proot, entry) {
- ret = relay_handle_http(cre, proot,
- pnv, &pkv, 0);
- if (ret == PN_FAIL) {
- free(val);
- free(line);
- return;
- }
- }
- }
- free(val);
+ /* Lookup the HTTP cookie */
+ if (relay_lookup_cookie(cre, pk.value) == PN_FAIL)
+ goto abort;
}
handle:
@@ -1461,10 +1394,8 @@ relay_read_http(struct bufferevent *bev, void *arg)
ret = relay_handle_http(cre, pn, pnv, &pk, header);
if (ret == PN_PASS)
pass = 1;
- else if (ret == PN_FAIL) {
- free(line);
- return;
- }
+ else if (ret == PN_FAIL)
+ goto abort;
}
if (pass) {
@@ -1479,7 +1410,6 @@ relay_read_http(struct bufferevent *bev, void *arg)
}
}
free(line);
- continue;
}
if (cre->done) {
RB_FOREACH(proot, proto_tree, cre->tree) {
@@ -1540,6 +1470,103 @@ relay_read_http(struct bufferevent *bev, void *arg)
return;
fail:
relay_close_http(con, 500, strerror(errno));
+ return;
+ abort:
+ free(line);
+}
+
+int
+relay_lookup_query(struct ctl_relay_event *cre)
+{
+ struct session *con = (struct session *)cre->con;
+ struct protonode *proot, *pnv, pkv;
+ char *val, *ptr;
+ int ret;
+
+ if (cre->path == NULL || cre->args == NULL || strlen(cre->args) < 2)
+ return (PN_PASS);
+ if ((val = strdup(cre->args)) == NULL) {
+ relay_close_http(con, 500, "failed to allocate query");
+ return (PN_FAIL);
+ }
+
+ ptr = val;
+ while (ptr != NULL && strlen(ptr)) {
+ pkv.key = ptr;
+ pkv.type = NODE_TYPE_QUERY;
+ if ((ptr = strchr(ptr, '&')) != NULL)
+ *ptr++ = '\0';
+ if ((pkv.value =
+ strchr(pkv.key, '=')) == NULL ||
+ strlen(pkv.value) < 1)
+ continue;
+ *pkv.value++ = '\0';
+
+ if ((proot = RB_FIND(proto_tree, cre->tree, &pkv)) == NULL)
+ continue;
+ PROTONODE_FOREACH(pnv, proot, entry) {
+ ret = relay_handle_http(cre, proot,
+ pnv, &pkv, 0);
+ if (ret == PN_FAIL)
+ goto done;
+ }
+ }
+
+ ret = PN_PASS;
+ done:
+ free(val);
+ return (ret);
+}
+
+int
+relay_lookup_cookie(struct ctl_relay_event *cre, const char *str)
+{
+ struct session *con = (struct session *)cre->con;
+ struct protonode *proot, *pnv, pkv;
+ char *val, *ptr;
+ int ret;
+
+ if ((val = strdup(str)) == NULL) {
+ relay_close_http(con, 500, "failed to allocate cookie");
+ return (PN_FAIL);
+ }
+
+ for (ptr = val; ptr != NULL && strlen(ptr);) {
+ if (*ptr == ' ')
+ *ptr++ = '\0';
+ pkv.key = ptr;
+ pkv.type = NODE_TYPE_COOKIE;
+ if ((ptr = strchr(ptr, ';')) != NULL)
+ *ptr++ = '\0';
+ /*
+ * XXX We do not handle attributes
+ * ($Path, $Domain, or $Port)
+ */
+ if (*pkv.key == '$')
+ continue;
+
+ if ((pkv.value =
+ strchr(pkv.key, '=')) == NULL ||
+ strlen(pkv.value) < 1)
+ continue;
+ *pkv.value++ = '\0';
+ if (*pkv.value == '"')
+ *pkv.value++ = '\0';
+ if (pkv.value[strlen(pkv.value) - 1] == '"')
+ pkv.value[strlen(pkv.value) - 1] = '\0';
+ if ((proot = RB_FIND(proto_tree, cre->tree, &pkv)) == NULL)
+ continue;
+ PROTONODE_FOREACH(pnv, proot, entry) {
+ ret = relay_handle_http(cre, proot, pnv, &pkv, 0);
+ if (ret == PN_FAIL)
+ goto done;
+ }
+ }
+
+ ret = PN_PASS;
+ done:
+ free(val);
+ return (ret);
}
void