mirror of
				https://github.com/jart/cosmopolitan.git
				synced 2025-10-26 19:16:41 +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(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; | ||||
|   if (url.scheme.n) { | ||||
| #ifndef UNSECURE
 | ||||
|  | @ -179,6 +183,9 @@ static int LuaFetch(lua_State *L) { | |||
|   if (!IsAcceptableHost(host, -1)) { | ||||
|     return LuaNilError(L, "invalid host"); | ||||
|   } | ||||
|   if (!IsAcceptablePort(port, -1)) { | ||||
|     return LuaNilError(L, "invalid port"); | ||||
|   } | ||||
|   if (!hosthdr) hosthdr = gc(xasprintf("%s:%s", host, port)); | ||||
| 
 | ||||
|   // check if hosthdr is in keepalive table
 | ||||
|  | @ -496,9 +503,47 @@ Finished: | |||
| 
 | ||||
|     lua_pushinteger(L, numredirects + 1); | ||||
|     lua_setfield(L, -2, "numredirects"); | ||||
|     // replace URL with Location header
 | ||||
|     lua_pushlstring(L, FetchHeaderData(kHttpLocation), | ||||
|                     FetchHeaderLength(kHttpLocation)); | ||||
|     // 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), | ||||
|                       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); | ||||
| 
 | ||||
|     DestroyHttpMessage(&msg); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue