summaryrefslogtreecommitdiff
path: root/src/reverse_proxy.c
diff options
context:
space:
mode:
authorRobert James Kaes <rjkaes@users.sourceforge.net>2005-08-16 04:03:19 +0000
committerRobert James Kaes <rjkaes@users.sourceforge.net>2005-08-16 04:03:19 +0000
commit4c58663041dbfdb751066da695af95e3aa83cbe7 (patch)
treede83968499735e7ed5ad2959e7b959a08ec9c167 /src/reverse_proxy.c
parent808bdbd1e9eab8e4fcd925442495d019b67f0b5a (diff)
downloadtinyproxy-4c58663041dbfdb751066da695af95e3aa83cbe7.tar.gz
tinyproxy-4c58663041dbfdb751066da695af95e3aa83cbe7.zip
* [Refactor] Moved Reverse Proxy Code
Moved the reverse proxy code from reqs.c into it's own files (reverse_proxy.c). The code in reqs.c is way too complicated, so I want to move unrelated code into their own files to simplify the main concepts in reqs.c.
Diffstat (limited to 'src/reverse_proxy.c')
-rw-r--r--src/reverse_proxy.c154
1 files changed, 154 insertions, 0 deletions
diff --git a/src/reverse_proxy.c b/src/reverse_proxy.c
new file mode 100644
index 0000000..40f15f4
--- /dev/null
+++ b/src/reverse_proxy.c
@@ -0,0 +1,154 @@
+/* $Id: reverse_proxy.c,v 1.1 2005-08-16 04:03:19 rjkaes Exp $
+ *
+ * Allow tinyproxy to be used as a reverse proxy.
+ *
+ * Copyright (C) 1999-2005 Robert James Kaes (rjkaes@users.sourceforge.net)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#include "tinyproxy.h"
+#include "reverse_proxy.h"
+
+#include "conns.h"
+#include "heap.h"
+#include "htmlerror.h"
+#include "log.h"
+
+/*
+ * Add entry to the reversepath list
+ */
+void
+reversepath_add(const char *path, const char *url)
+{
+ struct reversepath *reverse;
+
+ if (url == NULL) {
+ log_message(LOG_WARNING,
+ "Illegal reverse proxy rule: missing url");
+ return;
+ }
+
+ if (!strstr(url, "://")) {
+ log_message(LOG_WARNING,
+ "Skipping reverse proxy rule: '%s' is not a valid url",
+ url);
+ return;
+ }
+
+ if (path && *path != '/') {
+ log_message(LOG_WARNING,
+ "Skipping reverse proxy rule: path '%s' doesn't start with a /",
+ path);
+ return;
+ }
+
+ if (!(reverse = safemalloc(sizeof(struct reversepath)))) {
+ log_message(LOG_ERR,
+ "Unable to allocate memory in reversepath_add()");
+ return;
+ }
+
+ if (!path)
+ reverse->path = safestrdup("/");
+ else
+ reverse->path = safestrdup(path);
+
+ reverse->url = safestrdup(url);
+
+ reverse->next = config.reversepath_list;
+ config.reversepath_list = reverse;
+
+ log_message(LOG_INFO,
+ "Added reverse proxy rule: %s -> %s", reverse->path,
+ reverse->url);
+}
+
+/*
+ * Check if a request url is in the reversepath list
+ */
+struct reversepath *
+reversepath_get(char *url)
+{
+ struct reversepath *reverse = config.reversepath_list;
+
+ while (reverse) {
+ if (strstr(url, reverse->path) == url)
+ return reverse;
+
+ reverse = reverse->next;
+ }
+
+ return NULL;
+}
+
+/*
+ * Rewrite the URL for reverse proxying.
+ */
+char *
+reverse_rewrite_url(struct conn_s *connptr, hashmap_t hashofheaders, char *url)
+{
+ char *rewrite_url = NULL;
+ char *cookie = NULL;
+ char *cookieval;
+ struct reversepath *reverse;
+
+ /* Reverse requests always start with a slash */
+ if (*url == '/') {
+ /* First try locating the reverse mapping by request url */
+ reverse = reversepath_get(url);
+ if (reverse) {
+ rewrite_url = safemalloc(strlen(url) +
+ strlen(reverse->url) + 1);
+ strcpy(rewrite_url, reverse->url);
+ strcat(rewrite_url, url + strlen(reverse->path));
+ } else if (config.reversemagic
+ && hashmap_entry_by_key(hashofheaders,
+ "cookie",
+ (void **)&cookie) > 0) {
+
+ /* No match - try the magical tracking cookie next */
+ if ((cookieval = strstr(cookie, REVERSE_COOKIE "="))
+ && (reverse =
+ reversepath_get(cookieval +
+ strlen(REVERSE_COOKIE) + 1))) {
+
+ rewrite_url = safemalloc(strlen(url) +
+ strlen
+ (reverse->url) + 1);
+ strcpy(rewrite_url, reverse->url);
+ strcat(rewrite_url, url + 1);
+
+ log_message(LOG_INFO,
+ "Magical tracking cookie says: %s",
+ reverse->path);
+ }
+ }
+ }
+
+ /* Forward proxy support off and no reverse path match found */
+ if (config.reverseonly && !rewrite_url) {
+ log_message(LOG_ERR, "Bad request");
+ indicate_http_error(connptr, 400, "Bad Request",
+ "detail",
+ "Request has an invalid URL", "url",
+ url, NULL);
+ return NULL;
+ }
+
+ log_message(LOG_CONN, "Rewriting URL: %s -> %s", url, rewrite_url);
+
+ /* Store reverse path so that the magical tracking cookie can be set */
+ if (config.reversemagic)
+ connptr->reversepath = safestrdup(reverse->path);
+
+ return rewrite_url;
+}