Redbean fix redirect (#294)

* Fix redbean crash during redirect in debug logging mode

* Add reset for redirect loop check in redbean Route

Without this reset a combination of RoutePath() and Route() calls
could return "508 loop detected", since RoutePath could be called
twice for the same redirected path.

The protection against looping is still there, as it can only
loop inside the Route() call (as it always serves something).

* Update redbean redirect message for clarity
This commit is contained in:
Paul Kulchenko 2021-10-25 14:04:57 -07:00 committed by GitHub
parent 49db877fbe
commit 013f03e33f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -2917,7 +2917,7 @@ static char *HandleRedirect(struct Redirect *r) {
struct Asset *a; struct Asset *a;
if (!r->code && (a = GetAsset(r->location.s, r->location.n))) { if (!r->code && (a = GetAsset(r->location.s, r->location.n))) {
LockInc(&shared->c.rewrites); LockInc(&shared->c.rewrites);
DEBUGF("(rsp) rewriting to %`'s", r->location.s); DEBUGF("(rsp) internal redirect to %`'s", r->location.s);
if (!HasString(&loops, r->location.s, r->location.n)) { if (!HasString(&loops, r->location.s, r->location.n)) {
AddString(&loops, r->location.s, r->location.n); AddString(&loops, r->location.s, r->location.n);
return RoutePath(r->location.s, r->location.n); return RoutePath(r->location.s, r->location.n);
@ -2931,7 +2931,7 @@ static char *HandleRedirect(struct Redirect *r) {
LockInc(&shared->c.redirects); LockInc(&shared->c.redirects);
code = r->code; code = r->code;
if (!code) code = 307; if (!code) code = 307;
DEBUGF("(rsp) %d redirect to %`'s", code, r->location); DEBUGF("(rsp) %d redirect to %`'s", code, r->location.s);
return AppendHeader( return AppendHeader(
SetStatus(code, GetHttpReason(code)), "Location", SetStatus(code, GetHttpReason(code)), "Location",
FreeLater(EncodeHttpHeaderValue(r->location.s, r->location.n, 0))); FreeLater(EncodeHttpHeaderValue(r->location.s, r->location.n, 0)));
@ -5938,6 +5938,10 @@ static char *HandleRequest(void) {
static char *Route(const char *host, size_t hostlen, const char *path, static char *Route(const char *host, size_t hostlen, const char *path,
size_t pathlen) { size_t pathlen) {
char *p; char *p;
// reset the redirect loop check, as it can only be looping inside
// this function (as it always serves something); otherwise
// successful RoutePath and Route may fail with "508 loop detected"
loops.n = 0;
if (logmessages) LogMessage("received", inbuf.p, hdrsize); if (logmessages) LogMessage("received", inbuf.p, hdrsize);
if (hostlen && (p = RouteHost(host, hostlen, path, pathlen))) { if (hostlen && (p = RouteHost(host, hostlen, path, pathlen))) {
return p; return p;