// File: /workspace/github_c_makefile_star2_O3/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, %rbx
movq %rdi, %r14
leaq 0x54fe1(%rip), %rsi     # 0x94bd8
movl $0x4, %edi
movq %r14, %rdx
xorl %eax, %eax
callq 0x427e5
xorl %edi, %edi
movl $0x1, %esi
callq 0x294ea
movq %rax, %r12
movq %rax, 0x8(%rsp)
movq %r14, %rdi
movq %rax, %rsi
callq 0x2feb6
movl %eax, %r15d
leaq 0x51953(%rip), %r13     # 0x91582
movq %r12, %rdi
movq %r13, %rsi
callq 0x293d9
cmpl $0xc8, %r15d
sete %cl
testq %rax, %rax
setne %al
testb %al, %cl
jne 0x3fd52
movl $0x6, %r12d
leaq 0x8(%rsp), %r13
leaq 0x5191e(%rip), %rbp     # 0x91582
cmpl $0xc8, %r15d
setne %cl
cmpl $0x193, %r15d           # imm = 0x193
je 0x3fc7e
orb %al, %cl
testb $0x1, %cl
jne 0x3fcb0
movq %r13, %rdi
callq 0x298bd
xorl %edi, %edi
movl $0x1, %esi
callq 0x294ea
movq %rax, 0x8(%rsp)
movq %r14, %rdi
movq %rax, %rsi
callq 0x2fec5
movl %eax, %r15d
cmpl $0xce, %eax
je 0x3fe37
leal -0x12f(%r15), %eax
cmpl $-0x2, %eax
jb 0x3fe1b
decl %r12d
je 0x3fe1f
movq 0x8(%rsp), %rdi
leaq 0x54f59(%rip), %rsi     # 0x94c2e
callq 0x293d9
movq %rax, %r15
movq %rax, %rdi
callq 0x1feba
movq %rax, 0x28(%rbx)
movq %r14, %rdi
movq %r15, %rsi
callq 0x30a18
movq %rax, %r14
movq %r13, %rdi
callq 0x298bd
xorl %edi, %edi
movl $0x1, %esi
callq 0x294ea
movq %rax, 0x8(%rsp)
movq %r14, %rdi
movq %rax, %rsi
callq 0x2feb6
movl %eax, %r15d
movq 0x8(%rsp), %rdi
movq %rbp, %rsi
callq 0x293d9
cmpl $0xc8, %r15d
sete %cl
testq %rax, %rax
setne %al
andb %al, %cl
cmpb $0x1, %cl
jne 0x3fc64
movq 0x8(%rsp), %r12
leaq 0x51830(%rip), %r13     # 0x91582
movq %r12, %rdi
movq %r13, %rsi
callq 0x293d9
testq %rax, %rax
je 0x3fe72
movl $0xc8, %ebp
movq %rax, %rdi
callq 0x6520
movq %rax, 0x8(%rbx)
movq 0x8(%rsp), %rdi
leaq 0x54f32(%rip), %rsi     # 0x94cb5
callq 0x293d9
testq %rax, %rax
jne 0x3fda7
movq 0x8(%rsp), %rdi
leaq 0x54f2b(%rip), %rsi     # 0x94cc4
callq 0x293d9
testq %rax, %rax
je 0x3fe99
movq %rax, %r15
leaq 0x54f64(%rip), %rsi     # 0x94d15
leaq 0x10(%rsp), %rdx
movq %r15, %rdi
callq 0x60e0
testq %rax, %rax
jne 0x3fdde
leaq 0x8(%rsp), %rdi
callq 0x298bd
leaq 0x54f5a(%rip), %rdi     # 0x94d2e
movq %r15, %rsi
xorl %eax, %eax
callq 0x26e94
leaq 0x10(%rsp), %rdi
callq 0x2449f
movq %rax, %r14
cmpq $-0x1, %rax
jne 0x3fe0c
leaq 0x8(%rsp), %rdi
callq 0x298bd
leaq 0x54f56(%rip), %rdi     # 0x94d58
movq %r15, %rsi
xorl %eax, %eax
callq 0x26e94
movq %r14, (%rbx)
leaq 0x8(%rsp), %rdi
callq 0x298bd
jmp 0x3fe88
xorl %ebp, %ebp
jmp 0x3fe88
leaq 0x54dd3(%rip), %rdi     # 0x94bf9
xorl %ebp, %ebp
movl %r15d, %esi
movq %r14, %rdx
xorl %eax, %eax
callq 0x26bea
jmp 0x3fe88
movq 0x8(%rsp), %rdi
leaq 0x54df5(%rip), %r13     # 0x94c38
movq %r13, %rsi
callq 0x293d9
testq %rax, %rax
je 0x3fe72
movq %rax, %r15
movq %rax, %rdi
movl $0x2f, %esi
callq 0x6270
testq %rax, %rax
je 0x3febc
incq %rax
movl $0xce, %ebp
jmp 0x3fd6b
leaq 0x54e0a(%rip), %rdi     # 0x94c83
xorl %ebp, %ebp
movq %r13, %rsi
movq %r14, %rdx
xorl %eax, %eax
callq 0x26bea
movl %ebp, %eax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x8(%rsp), %rdi
callq 0x298bd
leaq 0x54e20(%rip), %rdi     # 0x94cca
xorl %r15d, %r15d
movq %r14, %rsi
xorl %eax, %eax
callq 0x26e94
jmp 0x3fdaa
leaq 0x54d84(%rip), %rdi     # 0x94c47
leaq 0x54d6e(%rip), %rdx     # 0x94c38
xorl %ebp, %ebp
movq %r15, %rsi
movq %r14, %rcx
xorl %eax, %eax
callq 0x26bea
jmp 0x3fe88