// File: /workspace/github_c_makefile_star2_O3/TimeToogo[P]ff-proxy/src/http.c
// Function: ff_http_get_destination_host
char *ff_http_get_destination_host(struct ff_request *request)
{
    // @see https://stackoverflow.com/questions/8724954/what-is-the-maximum-number-of-characters-for-a-host-name-in-unix
    char *host_name = malloc(_POSIX_HOST_NAME_MAX + 1);
    char *http_request = (char *)request->payload->value;
    char *line = http_request;
    uint64_t payload_len = request->payload_length;
    uint64_t i = 0;

#define FF_HTTP_DESTINATION_CONSUME_CHAR(x)                                                          \
    line += (x);                                                                                     \
    i += (x);                                                                                        \
    if (i > payload_len || *line == '\0')                                                            \
    {                                                                                                \
        ff_log(FF_WARNING, "Encountered end of request payload before finding Host header");         \
        goto error;                                                                                  \
    }                                                                                                \
    if (i >= FF_HTTP_HOST_HEADER_MAX_SEARCH_LENGTH)                                                  \
    {                                                                                                \
        ff_log(FF_WARNING, "Reached char limit of request payload while searching for host header"); \
        goto error;                                                                                  \
    }

    if (payload_len == 0)
    {
        FF_HTTP_DESTINATION_CONSUME_CHAR(1); // Force error
    }

    while (1)
    {
        if (payload_len - i > 2 && line != http_request && (*line == '\n' || (*line == '\r' && *(line + 1) == '\n')))
        {
            // Subsequent new lines indicate request headers have finished
            ff_log(FF_WARNING, "Encountered end of request headers before finding Host header");
            goto error;
        }

        if (payload_len - i > 5 && strncasecmp(line, "host:", 5) == 0)
        {
            FF_HTTP_DESTINATION_CONSUME_CHAR(5);

            while (*line == ' ')
            {
                FF_HTTP_DESTINATION_CONSUME_CHAR(1);
            }

            int host_len = 0;

            // http://man7.org/linux/man-pages/man7/hostname.7.html
            while (i <= payload_len && (*line == '.' || *line == '-' || isalnum(*line)) && host_len <= 255)
            {
                *(host_name + host_len) = *line;
                line++;
                i++;
                host_len++;
            }

            *(host_name + host_len) = '\0';
            goto done;
        }

        // Advance to next line
        while (*line != '\n')
        {
            FF_HTTP_DESTINATION_CONSUME_CHAR(1);
        }

        FF_HTTP_DESTINATION_CONSUME_CHAR(1);
    }

error:
    FREE(host_name);
    return NULL;

done:
    ff_log(FF_DEBUG, "Found destination host: %s", host_name);
    return host_name;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rdi, %r15
movl $0x100, %edi            # imm = 0x100
callq 0x23c0
movq %rax, %rbx
movq 0x40(%r15), %r13
leaq 0x350c(%rip), %rsi      # 0x6bbe
testq %r13, %r13
je 0x37ad
movq 0x50(%r15), %rax
movq 0x8(%rax), %rdx
xorl %r12d, %r12d
leaq 0x35b3(%rip), %r14      # 0x6c80
leaq 0x3528(%rip), %rdi      # 0x6bfc
movq %rdx, %r15
movq %r13, %rax
subq %r12, %rax
cmpq $0x3, %rax
jb 0x3706
cmpq %rdx, %r15
je 0x3706
movzbl (%r15), %ecx
cmpl $0xd, %ecx
je 0x36fb
cmpl $0xa, %ecx
jne 0x3706
jmp 0x3786
cmpb $0xa, 0x1(%r15)
je 0x3786
cmpq $0x6, %rax
jb 0x373d
movq %rdx, -0x30(%rbp)
movl $0x5, %edx
movq %r15, %rdi
movq %rbx, -0x48(%rbp)
movq %rsi, %rbx
movq %r14, %rsi
callq 0x2380
movq -0x30(%rbp), %rdx
leaq 0x34ca(%rip), %rdi      # 0x6bfc
movq %rbx, %rsi
movq -0x48(%rbp), %rbx
testl %eax, %eax
je 0x378f
movb (%r15), %al
incq %r15
cmpb $0xa, %al
je 0x3764
incq %r12
cmpq %r13, %r12
ja 0x37ad
movb (%r15), %al
testb %al, %al
je 0x37ad
incq %r15
cmpq $0x1f9f, %r12           # imm = 0x1F9F
jbe 0x3743
jmp 0x37aa
cmpq %r13, %r12
jae 0x37ad
cmpb $0x0, (%r15)
je 0x37ad
leaq 0x1(%r12), %rax
cmpq $0x1f9f, %r12           # imm = 0x1F9F
movq %rax, %r12
jb 0x36d7
jmp 0x37aa
leaq 0x34b5(%rip), %rsi      # 0x6c42
jmp 0x37ad
leaq 0x5(%r12), %rax
cmpq %r13, %rax
ja 0x37ad
movb 0x5(%r15), %cl
testb %cl, %cl
je 0x37ad
cmpq $0x1f9a, %r12           # imm = 0x1F9A
jbe 0x37d5
movq %rdi, %rsi
movl $0x3, %edi
xorl %eax, %eax
callq 0x3fa4
movq %rbx, %rdi
callq 0x2340
xorl %ebx, %ebx
movq %rbx, %rax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %r12, %rax
subq %r13, %rax
addq $0x5, %rax
xorl %r14d, %r14d
cmpb $0x20, %cl
jne 0x380d
movq %rax, %rcx
addq %r14, %rcx
je 0x37ad
movb 0x6(%r15,%r14), %cl
testb %cl, %cl
je 0x37ad
leaq (%r12,%r14), %rdx
incq %rdx
incq %r14
cmpq $0x1f9b, %rdx           # imm = 0x1F9B
jne 0x37e2
jmp 0x37aa
leaq (%r12,%r14), %rax
addq $0x5, %rax
cmpq %r13, %rax
jbe 0x381e
xorl %eax, %eax
jmp 0x388c
addq %r14, %r12
xorl %ecx, %ecx
leaq (%r15,%rcx), %rax
movb 0x5(%r14,%rax), %dl
leal -0x2d(%rdx), %eax
cmpb $0x2, %al
jae 0x383e
cmpq $0xff, %rcx
jbe 0x3871
jmp 0x388a
movq %rcx, -0x30(%rbp)
movq %rdx, -0x38(%rbp)
movsbq %dl, %rax
movq %rax, -0x40(%rbp)
callq 0x22b0
movq (%rax), %rax
movq -0x40(%rbp), %rcx
testb $0x8, (%rax,%rcx,2)
je 0x3886
movq -0x30(%rbp), %rcx
cmpq $0x100, %rcx            # imm = 0x100
movq -0x38(%rbp), %rdx
jae 0x388a
movb %dl, (%rbx,%rcx)
leaq (%r12,%rcx), %rax
addq $0x6, %rax
incq %rcx
cmpq %r13, %rax
jbe 0x3823
jmp 0x388a
movq -0x30(%rbp), %rcx
movl %ecx, %eax
movb $0x0, (%rbx,%rax)
leaq 0x33ef(%rip), %rsi      # 0x6c86
movl $0x1, %edi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x3fa4
jmp 0x37c3