mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-04-21 22:34:51 +00:00
Fix redbean Fetch redirect with relative URL (#1034)
This commit is contained in:
parent
616717fa82
commit
c72904b2f6
1 changed files with 48 additions and 3 deletions
|
@ -141,6 +141,10 @@ static int LuaFetch(lua_State *L) {
|
||||||
*/
|
*/
|
||||||
gc(ParseUrl(urlarg, urlarglen, &url, true));
|
gc(ParseUrl(urlarg, urlarglen, &url, true));
|
||||||
gc(url.params.p);
|
gc(url.params.p);
|
||||||
|
DEBUGF("(ftch) client fetching %`'s (host=%`'.*s, port=%.*s, path=%`'.*s)",
|
||||||
|
urlarg, url.host.n, url.host.p, url.port.n, url.port.p,
|
||||||
|
url.path.n, url.path.p);
|
||||||
|
|
||||||
usingssl = false;
|
usingssl = false;
|
||||||
if (url.scheme.n) {
|
if (url.scheme.n) {
|
||||||
#ifndef UNSECURE
|
#ifndef UNSECURE
|
||||||
|
@ -179,6 +183,9 @@ static int LuaFetch(lua_State *L) {
|
||||||
if (!IsAcceptableHost(host, -1)) {
|
if (!IsAcceptableHost(host, -1)) {
|
||||||
return LuaNilError(L, "invalid host");
|
return LuaNilError(L, "invalid host");
|
||||||
}
|
}
|
||||||
|
if (!IsAcceptablePort(port, -1)) {
|
||||||
|
return LuaNilError(L, "invalid port");
|
||||||
|
}
|
||||||
if (!hosthdr) hosthdr = gc(xasprintf("%s:%s", host, port));
|
if (!hosthdr) hosthdr = gc(xasprintf("%s:%s", host, port));
|
||||||
|
|
||||||
// check if hosthdr is in keepalive table
|
// check if hosthdr is in keepalive table
|
||||||
|
@ -496,9 +503,47 @@ Finished:
|
||||||
|
|
||||||
lua_pushinteger(L, numredirects + 1);
|
lua_pushinteger(L, numredirects + 1);
|
||||||
lua_setfield(L, -2, "numredirects");
|
lua_setfield(L, -2, "numredirects");
|
||||||
// replace URL with Location header
|
// replace URL with Location header, which
|
||||||
|
// can be a relative or absolute URL:
|
||||||
|
// https://www.rfc-editor.org/rfc/rfc3986#section-4.2
|
||||||
|
gc(ParseUrl(FetchHeaderData(kHttpLocation),
|
||||||
|
FetchHeaderLength(kHttpLocation), &url, true));
|
||||||
|
free(url.params.p);
|
||||||
|
VERBOSEF("(ftch) client redirecting %`'.*s "
|
||||||
|
"(scheme=%`'.*s, host=%`'.*s, port=%.*s, path=%`'.*s)",
|
||||||
|
FetchHeaderLength(kHttpLocation), FetchHeaderData(kHttpLocation),
|
||||||
|
url.scheme.n, url.scheme.p, url.host.n, url.host.p,
|
||||||
|
url.port.n, url.port.p, url.path.n, url.path.p);
|
||||||
|
// while it's possible to check for IsAcceptableHost/IsAcceptablePort
|
||||||
|
// it's not clear what to do if they are not;
|
||||||
|
// if they are invalid, redirect returns "invalid host" message
|
||||||
|
if (url.host.n && url.scheme.n) {
|
||||||
lua_pushlstring(L, FetchHeaderData(kHttpLocation),
|
lua_pushlstring(L, FetchHeaderData(kHttpLocation),
|
||||||
FetchHeaderLength(kHttpLocation));
|
FetchHeaderLength(kHttpLocation));
|
||||||
|
} else {
|
||||||
|
gc(ParseUrl(urlarg, urlarglen, &url, true));
|
||||||
|
free(url.params.p);
|
||||||
|
// remove user/pass/fragment for the redirect
|
||||||
|
url.fragment.p = 0, url.fragment.n = 0;
|
||||||
|
url.user.p = 0, url.user.n = 0;
|
||||||
|
url.pass.p = 0, url.pass.n = 0;
|
||||||
|
if (FetchHeaderData(kHttpLocation)[0] == '/') {
|
||||||
|
// if the path is absolute, then use it
|
||||||
|
// so `/redir/more` -> `/less` becomes `/less`
|
||||||
|
url.path.n = 0; // replace the path
|
||||||
|
} else {
|
||||||
|
// if the path is relative, then merge it,
|
||||||
|
// so `/redir/more` -> `less` becomes `/redir/less`
|
||||||
|
while (url.path.n > 0 && url.path.p[url.path.n - 1] != '/') {
|
||||||
|
--url.path.n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
url.path.p = gc(xasprintf("%.*s%.*s", url.path.n, url.path.p,
|
||||||
|
FetchHeaderLength(kHttpLocation),
|
||||||
|
FetchHeaderData(kHttpLocation)));
|
||||||
|
url.path.n = strlen(url.path.p);
|
||||||
|
lua_pushstring(L, gc(EncodeUrl(&url, 0)));
|
||||||
|
}
|
||||||
lua_replace(L, -3);
|
lua_replace(L, -3);
|
||||||
|
|
||||||
DestroyHttpMessage(&msg);
|
DestroyHttpMessage(&msg);
|
||||||
|
|
Loading…
Add table
Reference in a new issue