diff options
author | rofl0r <rofl0r@users.noreply.github.com> | 2021-03-28 20:40:17 +0100 |
---|---|---|
committer | rofl0r <rofl0r@users.noreply.github.com> | 2021-04-16 14:41:40 +0100 |
commit | 2529597ea0201c147b4bb5fb713040b117368b50 (patch) | |
tree | ac96fd5f735a5d973f72b1ed5b1524275a578683 | |
parent | bc87de3482b8bbbc8e59651638eb8545831ccd64 (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.c | 9 | ||||
-rw-r--r-- | src/reverse-proxy.c | 29 | ||||
-rw-r--r-- | src/reverse-proxy.h | 3 |
3 files changed, 31 insertions, 10 deletions
@@ -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 |