// File: /workspace/github_c_makefile_star2_O2/icebert[P]pblat/lib/udc.c
// Function: udcInfoViaHttp
boolean udcInfoViaHttp(char *url, struct udcRemoteFileInfo *retInfo)
/* Gets size and last modified time of URL
 * and returns status of HEAD or GET byterange 0-0. */
{
verbose(4, "checking http remote info on %s\n", url);
// URLs passed into here should not have byterange clause.
int redirectCount = 0;
struct hash *hash;
int status;
char *sizeString = NULL;
/*
 For caching, sites should support byte-range and last-modified.
 However, several groups including ENCODE have made sites that use CGIs to 
 dynamically generate hub text files such as hub.txt, genome.txt, trackDb.txt.
 Byte-range and last-modified are difficult to support for this case,
 so they do without them, effectively defeat caching. Every 5 minutes (udcTimeout),
 they get re-downloaded, even when the data has not changed.  
*/
while (TRUE)
    {
    hash = newHash(0);
    status = netUrlHead(url, hash);
    sizeString = hashFindValUpperCase(hash, "Content-Length:");
    if (status == 200 && sizeString)
	break;
    /*
    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 != 301 && status != 302)
	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);
    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
    }

sizeString = hashFindValUpperCase(hash, sizeHeader);
if (sizeString)
    {
    char *parseString = sizeString;
    if (status == 206)
	{
	parseString = strchr(sizeString, '/');
	if (!parseString)
	    {
	    warn("Header value %s is missing '/' in %s in response for url %s", 
		sizeString, sizeHeader, url);
	    return FALSE;
	    }
	++parseString; // skip past slash
	}
    if (parseString)
	{
	retInfo->size = atoll(parseString);
	}
    else
	{
	warn("Header value %s is missing or invalid in %s in response for url %s", 
	    sizeString, sizeHeader, url);
	return FALSE;
	}
    }
else
    {
    warn("Response is missing required header %s for url %s", sizeHeader, url);
    return FALSE;
    }

char *lastModString = hashFindValUpperCase(hash, "Last-Modified:");
if (lastModString == NULL)
    {
    // Date is a poor substitute!  It will always appear that the cache is stale.
    // But at least we can read files from dropbox.com.
    lastModString = hashFindValUpperCase(hash, "Date:");
    if (lastModString == NULL)
	{
	hashFree(&hash);
	errAbort("No Last-Modified: or Date: returned in header for %s, can't proceed, sorry", url);
	}
    }

struct tm tm;
time_t t;
// Last-Modified: Wed, 15 Nov 1995 04:58:08 GMT
// This will always be GMT
if (strptime(lastModString, "%a, %d %b %Y %H:%M:%S %Z", &tm) == NULL)
    { /* Handle error */;
    hashFree(&hash);
    errAbort("unable to parse last-modified string [%s]", lastModString);
    }
t = mktimeFromUtc(&tm);
if (t == -1)
    { /* Handle error */;
    hashFree(&hash);
    errAbort("mktimeFromUtc failed while converting last-modified string [%s] from UTC time", lastModString);
    }
retInfo->updateTime = t;

hashFree(&hash);
return status;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movq %rsi, 0x8(%rsp)
movq %rdi, %r14
leaq 0x49f85(%rip), %rsi     # 0x83ad8
pushq $0x4
popq %rdi
movq %r14, %rdx
xorl %eax, %eax
callq 0x3c521
pushq $0x5
popq %r12
pushq $0x1
popq %rbp
leaq 0x46914(%rip), %r15     # 0x80482
xorl %edi, %edi
movl %ebp, %esi
callq 0x245c9
movq %rax, (%rsp)
movq %r14, %rdi
movq %rax, %rsi
callq 0x2a8fc
movl %eax, %ebx
movq (%rsp), %rdi
movq %r15, %rsi
callq 0x244f2
cmpl $0xc8, %ebx
sete %cl
testq %rax, %rax
setne %r13b
andb %cl, %r13b
jne 0x39c41
testq %rax, %rax
setne %al
cmpl $0xc8, %ebx
setne %cl
cmpl $0x193, %ebx            # imm = 0x193
je 0x39bc8
orb %al, %cl
jne 0x39bf1
movq %rsp, %rdi
callq 0x2494c
xorl %edi, %edi
movl %ebp, %esi
callq 0x245c9
movq %rax, (%rsp)
movq %r14, %rdi
movq %rax, %rsi
callq 0x2a90b
cmpl $0xce, %eax
je 0x39c69
movl %eax, %ebx
leal -0x12f(%rbx), %eax
cmpl $-0x2, %eax
jb 0x39c48
subl $0x1, %r12d
jb 0x39c4f
movq (%rsp), %rdi
leaq 0x49f21(%rip), %rsi     # 0x83b2e
callq 0x244f2
movq %rax, %rbx
movq %rax, %rdi
callq 0x1c306
movq 0x8(%rsp), %rcx
movq %rax, 0x28(%rcx)
movq %r14, %rdi
movq %rbx, %rsi
callq 0x2b481
movq %rax, %r14
movq %rsp, %rdi
callq 0x2494c
jmp 0x39b6e
movl $0xc8, %ebp
jmp 0x39c75
xorl %ebp, %ebp
jmp 0x39d8f
leaq 0x49ea3(%rip), %rdi     # 0x83af9
xorl %ebp, %ebp
movl %ebx, %esi
movq %r14, %rdx
xorl %eax, %eax
callq 0x22186
jmp 0x39d8f
movl $0xce, %ebp
leaq 0x49ec3(%rip), %r15     # 0x83b38
movq (%rsp), %rdi
movq %r15, %rsi
callq 0x244f2
testq %rax, %rax
je 0x39d5e
movq %rax, %rbx
testb %r13b, %r13b
jne 0x39cac
pushq $0x2f
popq %rsi
movq %rbx, %rdi
callq 0x6270
testq %rax, %rax
je 0x39d76
incq %rax
movq %rax, %rbx
movq %rbx, %rdi
callq 0x6520
movq 0x8(%rsp), %rcx
movq %rax, 0x8(%rcx)
movq (%rsp), %rdi
leaq 0x49eed(%rip), %rsi     # 0x83bb5
callq 0x244f2
testq %rax, %rax
jne 0x39ceb
movq (%rsp), %rdi
leaq 0x49ee7(%rip), %rsi     # 0x83bc4
callq 0x244f2
testq %rax, %rax
je 0x39da0
movq %rax, %r15
leaq 0x49f20(%rip), %rsi     # 0x83c15
leaq 0x10(%rsp), %rdx
movq %r15, %rdi
callq 0x60e0
testq %rax, %rax
jne 0x39d20
movq %rsp, %rdi
callq 0x2494c
leaq 0x49f18(%rip), %rdi     # 0x83c2e
movq %r15, %rsi
xorl %eax, %eax
callq 0x223fb
leaq 0x10(%rsp), %rdi
callq 0x1ffbe
movq %rax, %rbx
cmpq $-0x1, %rax
jne 0x39d4c
movq %rsp, %rdi
callq 0x2494c
leaq 0x49f16(%rip), %rdi     # 0x83c58
movq %r15, %rsi
xorl %eax, %eax
callq 0x223fb
movq 0x8(%rsp), %rax
movq %rbx, (%rax)
movq %rsp, %rdi
callq 0x2494c
jmp 0x39d8f
leaq 0x49e1e(%rip), %rdi     # 0x83b83
xorl %ebp, %ebp
movq %r15, %rsi
movq %r14, %rdx
xorl %eax, %eax
callq 0x22186
jmp 0x39d8f
leaq 0x49dca(%rip), %rdi     # 0x83b47
xorl %ebp, %ebp
movq %rbx, %rsi
movq %r15, %rdx
movq %r14, %rcx
xorl %eax, %eax
callq 0x22186
movl %ebp, %eax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rsp, %rdi
callq 0x2494c
leaq 0x49e1b(%rip), %rdi     # 0x83bca
xorl %r15d, %r15d
movq %r14, %rsi
xorl %eax, %eax
callq 0x223fb
jmp 0x39cee