2008-05-24 16:05:49 +08:00
|
|
|
/* tinyproxy - A fast light-weight HTTP proxy
|
|
|
|
* Copyright (C) 1999-2005 Robert James Kaes <rjkaes@users.sourceforge.net>
|
2005-08-16 12:03:19 +08:00
|
|
|
*
|
2008-05-24 16:05:49 +08:00
|
|
|
* 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 of the License, or
|
|
|
|
* (at your option) any later version.
|
2005-08-16 12:03:19 +08:00
|
|
|
*
|
2008-05-24 16:05:49 +08:00
|
|
|
* 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.
|
2005-08-16 12:03:19 +08:00
|
|
|
*
|
2008-05-24 16:05:49 +08:00
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
2005-08-16 12:03:19 +08:00
|
|
|
*/
|
|
|
|
|
2008-05-24 16:05:49 +08:00
|
|
|
/* Allow tinyproxy to be used as a reverse proxy. */
|
|
|
|
|
2009-08-07 06:12:53 +08:00
|
|
|
#include "main.h"
|
2008-03-09 09:33:54 +08:00
|
|
|
#include "reverse-proxy.h"
|
2005-08-16 12:03:19 +08:00
|
|
|
|
|
|
|
#include "conns.h"
|
|
|
|
#include "heap.h"
|
2008-05-24 16:17:14 +08:00
|
|
|
#include "html-error.h"
|
2005-08-16 12:03:19 +08:00
|
|
|
#include "log.h"
|
2009-12-08 06:39:25 +08:00
|
|
|
#include "conf.h"
|
2005-08-16 12:03:19 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Add entry to the reversepath list
|
|
|
|
*/
|
2009-12-07 05:53:17 +08:00
|
|
|
void reversepath_add (const char *path, const char *url,
|
|
|
|
struct reversepath **reversepath_list)
|
2005-08-16 12:03:19 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2009-09-23 10:17:11 +08:00
|
|
|
reverse = (struct reversepath *) safemalloc (sizeof
|
|
|
|
(struct reversepath));
|
|
|
|
if (!reverse) {
|
2009-09-15 03:41:25 +08:00
|
|
|
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);
|
|
|
|
|
2009-12-07 05:53:17 +08:00
|
|
|
reverse->next = *reversepath_list;
|
|
|
|
*reversepath_list = reverse;
|
2009-09-15 03:41:25 +08:00
|
|
|
|
|
|
|
log_message (LOG_INFO,
|
|
|
|
"Added reverse proxy rule: %s -> %s", reverse->path,
|
|
|
|
reverse->url);
|
2005-08-16 12:03:19 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check if a request url is in the reversepath list
|
|
|
|
*/
|
2009-12-07 05:59:08 +08:00
|
|
|
struct reversepath *reversepath_get (char *url, struct reversepath *reverse)
|
2005-08-16 12:03:19 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
while (reverse) {
|
|
|
|
if (strstr (url, reverse->path) == url)
|
|
|
|
return reverse;
|
2005-08-16 12:03:19 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
reverse = reverse->next;
|
|
|
|
}
|
2005-08-16 12:03:19 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
return NULL;
|
2005-08-16 12:03:19 +08:00
|
|
|
}
|
|
|
|
|
2009-12-07 06:04:05 +08:00
|
|
|
/**
|
|
|
|
* Free a reversepath list
|
|
|
|
*/
|
|
|
|
|
|
|
|
void free_reversepath_list (struct reversepath *reverse)
|
|
|
|
{
|
|
|
|
while (reverse) {
|
|
|
|
struct reversepath *tmp = reverse;
|
|
|
|
reverse = reverse->next;
|
|
|
|
safefree (tmp->url);
|
|
|
|
safefree (tmp->path);
|
|
|
|
safefree (tmp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-08-16 12:03:19 +08:00
|
|
|
/*
|
|
|
|
* Rewrite the URL for reverse proxying.
|
|
|
|
*/
|
2009-09-15 03:41:25 +08:00
|
|
|
char *reverse_rewrite_url (struct conn_s *connptr, hashmap_t hashofheaders,
|
|
|
|
char *url)
|
2005-08-16 12:03:19 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
char *rewrite_url = NULL;
|
|
|
|
char *cookie = NULL;
|
|
|
|
char *cookieval;
|
2009-09-23 10:17:20 +08:00
|
|
|
struct reversepath *reverse = NULL;
|
2009-09-15 03:41:25 +08:00
|
|
|
|
|
|
|
/* Reverse requests always start with a slash */
|
|
|
|
if (*url == '/') {
|
|
|
|
/* First try locating the reverse mapping by request url */
|
2009-12-07 05:59:08 +08:00
|
|
|
reverse = reversepath_get (url, config.reversepath_list);
|
2009-09-15 03:41:25 +08:00
|
|
|
if (reverse) {
|
2009-09-23 10:17:11 +08:00
|
|
|
rewrite_url = (char *)
|
2009-09-15 03:41:25 +08:00
|
|
|
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 +
|
2009-12-07 05:59:08 +08:00
|
|
|
strlen (REVERSE_COOKIE) + 1,
|
|
|
|
config.reversepath_list)))
|
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
|
2009-09-23 10:17:11 +08:00
|
|
|
rewrite_url = (char *) safemalloc
|
|
|
|
(strlen (url) +
|
|
|
|
strlen (reverse->url) +
|
|
|
|
1);
|
2009-09-15 03:41:25 +08:00
|
|
|
strcpy (rewrite_url, reverse->url);
|
|
|
|
strcat (rewrite_url, url + 1);
|
|
|
|
|
|
|
|
log_message (LOG_INFO,
|
|
|
|
"Magical tracking cookie says: %s",
|
|
|
|
reverse->path);
|
|
|
|
}
|
|
|
|
}
|
2008-12-08 21:39:44 +08:00
|
|
|
}
|
2008-12-01 23:01:11 +08:00
|
|
|
|
2016-09-11 01:22:45 +08:00
|
|
|
if (rewrite_url == NULL) {
|
2009-09-15 03:41:25 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
2008-12-01 23:01:11 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
log_message (LOG_CONN, "Rewriting URL: %s -> %s", url, rewrite_url);
|
2008-12-01 23:01:11 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
/* Store reverse path so that the magical tracking cookie can be set */
|
2009-09-23 10:17:20 +08:00
|
|
|
if (config.reversemagic && reverse)
|
2009-09-15 03:41:25 +08:00
|
|
|
connptr->reversepath = safestrdup (reverse->path);
|
2008-12-01 23:01:11 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
return rewrite_url;
|
2005-08-16 12:03:19 +08:00
|
|
|
}
|