summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorrofl0r <rofl0r@users.noreply.github.com>2021-03-28 20:40:17 +0100
committerrofl0r <rofl0r@users.noreply.github.com>2021-04-16 14:41:40 +0100
commit2529597ea0201c147b4bb5fb713040b117368b50 (patch)
treeac96fd5f735a5d973f72b1ed5b1524275a578683
parentbc87de3482b8bbbc8e59651638eb8545831ccd64 (diff)
reverse: redirect if path without trailing slash is detected
if for example: ReversePath = "/foo/" and user requests "http://tinyproxy/foo" the common behaviour for HTTP servers is to send a http 301 redirect to the correct url. we now do the same.
-rw-r--r--src/reqs.c9
-rw-r--r--src/reverse-proxy.c29
-rw-r--r--src/reverse-proxy.h3
3 files changed, 31 insertions, 10 deletions
diff --git a/src/reqs.c b/src/reqs.c
index 4d49583..61a5eb0 100644
--- a/src/reqs.c
+++ b/src/reqs.c
@@ -383,10 +383,17 @@ BAD_REQUEST_ERROR:
* we'll be closing anyway.
*/
char *reverse_url;
+ int reverse_status;
- reverse_url = reverse_rewrite_url (connptr, hashofheaders, url);
+ reverse_url = reverse_rewrite_url (connptr, hashofheaders, url, &reverse_status);
if (reverse_url != NULL) {
+ if (reverse_status == 301) {
+ char buf[PATH_MAX];
+ snprintf (buf, sizeof buf, "Location: %s\r\n", reverse_url);
+ send_http_headers (connptr, 301, "Moved Permanently", buf);
+ goto fail;
+ }
safefree (url);
url = reverse_url;
} else if (config->reverseonly) {
diff --git a/src/reverse-proxy.c b/src/reverse-proxy.c
index 4008120..68f04a6 100644
--- a/src/reverse-proxy.c
+++ b/src/reverse-proxy.c
@@ -93,10 +93,16 @@ void reversepath_add (const char *path, const char *url,
*/
struct reversepath *reversepath_get (char *url, struct reversepath *reverse)
{
+ size_t l, lu, lp;
while (reverse) {
- if (strstr (url, reverse->path) == url)
+ lu = strlen (url);
+ lp = strlen (reverse->path);
+ if ((
+ (l = lu) == lp-1 ||
+ (l = lp) <= lu
+ ) &&
+ !memcmp(url, reverse->path, l))
return reverse;
-
reverse = reverse->next;
}
@@ -122,23 +128,30 @@ void free_reversepath_list (struct reversepath *reverse)
* Rewrite the URL for reverse proxying.
*/
char *reverse_rewrite_url (struct conn_s *connptr, orderedmap hashofheaders,
- char *url)
+ char *url, int *status)
{
char *rewrite_url = NULL;
char *cookie = NULL;
char *cookieval;
struct reversepath *reverse = NULL;
+ *status = 0;
+
/* Reverse requests always start with a slash */
if (*url == '/') {
/* First try locating the reverse mapping by request url */
reverse = reversepath_get (url, config->reversepath_list);
if (reverse) {
- rewrite_url = (char *)
- safemalloc (strlen (url) + strlen (reverse->url) +
- 1);
- strcpy (rewrite_url, reverse->url);
- strcat (rewrite_url, url + strlen (reverse->path));
+ size_t lu = strlen (url);
+ size_t lrp = strlen (reverse->path);
+ if (lrp > lu) {
+ rewrite_url = safestrdup (reverse->path);
+ *status = 301;
+ } else {
+ rewrite_url = safemalloc (
+ strlen (reverse->url) + lu + 1);
+ sprintf (rewrite_url, "%s%s", reverse->url, url + lrp);
+ }
} else if (config->reversemagic
&& (cookie = orderedmap_find (hashofheaders,
"cookie"))) {
diff --git a/src/reverse-proxy.h b/src/reverse-proxy.h
index a2d6619..a9a5bdd 100644
--- a/src/reverse-proxy.h
+++ b/src/reverse-proxy.h
@@ -38,6 +38,7 @@ extern struct reversepath *reversepath_get (char *url,
struct reversepath *reverse);
void free_reversepath_list (struct reversepath *reverse);
extern char *reverse_rewrite_url (struct conn_s *connptr,
- orderedmap hashofheaders, char *url);
+ orderedmap hashofheaders, char *url,
+ int *status);
#endif