22d2b680a73ee00f4c37917f6e16ead11db556ef galt Tue Sep 1 02:04:38 2020 -0700 Adding support for relative URL in redirect location in net.c and udc.c. refs#26138 diff --git src/lib/net.c src/lib/net.c index 5a3ba76..f57e054 100644 --- src/lib/net.c +++ src/lib/net.c @@ -3,30 +3,31 @@ * This file is copyright 2002 Jim Kent, but license is hereby * granted for all use - public, private or commercial. */ #include "common.h" #include <signal.h> #include <errno.h> #include <string.h> #include <sys/time.h> #include <pthread.h> #include "errAbort.h" #include "hash.h" #include "net.h" #include "linefile.h" #include "base64.h" #include "cheapcgi.h" +#include "htmlPage.h" #include "https.h" #include "sqlNum.h" #include "obscure.h" #include "errCatch.h" /* Brought errno in to get more useful error messages */ extern int errno; static int netStreamSocketFromAddrInfo(struct addrinfo *address) /* Create a socket from addrinfo structure. * Complain and return something negative if can't. */ { int sd = socket(address->ai_family, address->ai_socktype, address->ai_protocol); if (sd < 0) warn("Couldn't make %s socket.", familyToString(address->ai_family)); @@ -1534,31 +1535,31 @@ *rangeStart = atoll(y); if (z[0] != '\0') *rangeEnd = atoll(z); } } } boolean netSkipHttpHeaderLinesWithRedirect(int sd, char *url, char **redirectedUrl) /* Skip http header lines. Return FALSE if there's a problem. * The input is a standard sd or fd descriptor. * This is meant to be able work even with a re-passable stream handle, * e.g. can pass it to the pipes routines, which means we can't * attach a linefile since filling its buffer reads in more than just the http header. - * Handles 300, 301, 302, 303, 307, 308 http redirects by setting *redirectedUrl to + * Handles 301, 302, 307, 308 http redirects by setting *redirectedUrl to * the new location. */ { char buf[8192]; char *line = buf; int maxbuf = sizeof(buf); int i=0; char c = ' '; int nread = 0; char *sep = NULL; char *headerName = NULL; char *headerVal = NULL; boolean redirect = FALSE; boolean byteRangeUsed = (strstr(url,";byterange=") != NULL); ssize_t byteRangeStart = -1; ssize_t byteRangeEnd = -1; @@ -1781,47 +1782,58 @@ *redirectedSd = -1; *redirectedUrl = NULL; } return TRUE; } close(sd); if (success) { /* we have a new url to try */ ++redirectCount; if (redirectCount > 5) { warn("code 30x redirects: exceeded limit of 5 redirects, %s", newUrl); success = FALSE; } - else if (!startsWith("http://",newUrl) + else + { + // path may be relative + if (!hasProtocol(newUrl)) + { + char *newUrl2 = expandUrlOnBase(url, newUrl); + freeMem(newUrl); + newUrl = newUrl2; + } + if (!startsWith("http://",newUrl) && !startsWith("https://",newUrl)) { warn("redirected to non-http(s): %s", newUrl); success = FALSE; } else { + // transfer password and byteranges if any newUrl = transferParamsToRedirectedUrl(url, newUrl); sd = netUrlOpen(newUrl); if (sd < 0) { warn("Couldn't open %s", newUrl); success = FALSE; } } } + } if (redirectCount > 1) freeMem(url); if (!success) { /* failure after 0 to 5 redirects */ if (redirectCount > 0) freeMem(newUrl); return FALSE; } url = newUrl; } return FALSE; } struct lineFile *netLineFileMayOpen(char *url) /* Return a lineFile attached to url. http skips header.