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/udc.c src/lib/udc.c index a67b1dc..746879d 100644 --- src/lib/udc.c +++ src/lib/udc.c @@ -22,30 +22,31 @@ * * The bitmap file contains time stamp and size data as well as an array with one bit * for each block of the file that has been fetched. Currently the block size is 8K. */ #include <sys/file.h> #include <sys/mman.h> #include "common.h" #include "hash.h" #include "obscure.h" #include "bits.h" #include "linefile.h" #include "portable.h" #include "sig.h" #include "net.h" #include "cheapcgi.h" +#include "htmlPage.h" #include "udc.h" #include "hex.h" #include <dirent.h> #include <openssl/sha.h> /* The stdio stream we'll use to output statistics on file i/o. Off by default. */ FILE *udcLogStream = NULL; void udcSetLog(FILE *fp) /* Turn on logging of file i/o. * For each UDC file two lines are written. One line for the open, and one line for the close. * The Open line just has the URL being opened. * The Close line has the the URL plus a bunch of counts of the number of seeks, reads, and writes * for the following four files: the udc bitmap, the udc sparse data, the incoming calls * to the UDC layer, and the network connection to the (possibly) remote file. @@ -517,41 +518,59 @@ Using HEAD with HIPPAA-compliant signed AmazonS3 URLs generates 403. The signed URL generated for GET cannot be used with HEAD. Instead call GET with byterange=0-0 in netUrlFakeHeadByGet(). This supplies both size via Content-Range response header, as well as Last-Modified header which is important for caching. There are also sites which support byte-ranges but they do not return Content-Length with HEAD. */ if (status == 403 || (status==200 && !sizeString)) { hashFree(&hash); hash = newHash(0); status = netUrlFakeHeadByGet(url, hash); if (status == 206) break; + if (status == 200) // helps get more info to user + break; } if (status != 301 && status != 302 && status != 307 && status != 308) return FALSE; ++redirectCount; if (redirectCount > 5) { warn("code %d redirects: exceeded limit of 5 redirects, %s", status, url); return FALSE; } char *newUrl = hashFindValUpperCase(hash, "Location:"); - retInfo->ci.redirUrl = cloneString(newUrl); + if (!newUrl) + { + warn("code %d redirects: redirect location missing, %s", status, url); + return FALSE; + } + + // path may be relative + if (hasProtocol(newUrl)) + { + newUrl = cloneString(newUrl); + } + else + { + newUrl = expandUrlOnBase(url, newUrl); + } + + retInfo->ci.redirUrl = newUrl; url = transferParamsToRedirectedUrl(url, newUrl); hashFree(&hash); } char *sizeHeader = NULL; if (status == 200) { sizeHeader = "Content-Length:"; // input pattern: Content-Length: 2738262 } if (status == 206) { sizeHeader = "Content-Range:"; // input pattern: Content-Range: bytes 0-99/2738262 }