// File: /workspace/github_c_makefile_star2_O1/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 $0x18, %rsp
movq %rdi, %r15
movl $0x100, %edi            # imm = 0x100
callq 0x23c0
movq %rax, %rbx
movq 0x40(%r15), %r13
leaq 0x339e(%rip), %rsi      # 0x6bbe
testq %r13, %r13
je 0x3920
movq 0x50(%r15), %rax
movq 0x8(%rax), %rdi
xorl %r12d, %r12d
leaq 0x3445(%rip), %r14      # 0x6c80
leaq 0x33ba(%rip), %rdx      # 0x6bfc
movq %rdi, %r15
movq %r13, %rax
subq %r12, %rax
cmpq $0x3, %rax
jb 0x3874
cmpq %rdi, %r15
je 0x3874
movzbl (%r15), %ecx
cmpl $0xd, %ecx
je 0x3869
cmpl $0xa, %ecx
jne 0x3874
jmp 0x38f7
cmpb $0xa, 0x1(%r15)
je 0x38f7
cmpq $0x5, %rax
jbe 0x38ab
movl $0x5, %edx
movq %rdi, -0x30(%rbp)
movq %r15, %rdi
movq %rbx, -0x40(%rbp)
movq %rsi, %rbx
movq %r14, %rsi
callq 0x2380
movq -0x30(%rbp), %rdi
leaq 0x335c(%rip), %rdx      # 0x6bfc
movq %rbx, %rsi
movq -0x40(%rbp), %rbx
testl %eax, %eax
je 0x3900
incq %r15
cmpb $0xa, -0x1(%r15)
je 0x38d5
cmpq %r13, %r12
jae 0x3920
cmpb $0x0, (%r15)
je 0x3920
incq %r12
incq %r15
leaq -0x1(%r12), %rax
cmpq $0x1f9e, %rax           # imm = 0x1F9E
jbe 0x38ae
jmp 0x391d
cmpq %r13, %r12
jae 0x3920
cmpb $0x0, (%r15)
je 0x3920
leaq 0x1(%r12), %rax
cmpq $0x1f9f, %r12           # imm = 0x1F9F
movq %rax, %r12
jb 0x3845
jmp 0x391d
leaq 0x3344(%rip), %rsi      # 0x6c42
jmp 0x3920
leaq 0x5(%r12), %rax
cmpq %r13, %rax
ja 0x3920
addq $0x5, %r15
cmpb $0x0, (%r15)
je 0x3920
cmpq $0x1f9a, %r12           # imm = 0x1F9A
jbe 0x3948
movq %rdx, %rsi
movl $0x3, %edi
xorl %eax, %eax
callq 0x4100
movq %rbx, %rdi
callq 0x2340
xorl %ebx, %ebx
movq %rbx, %rax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq $-0x6, %r14
subq %r12, %r14
cmpb $0x20, (%r15)
jne 0x3977
cmpq %r13, %rax
jae 0x3920
incq %r15
cmpb $0x0, (%r15)
je 0x3920
decq %r14
incq %rax
cmpq $-0x1fa1, %r14          # imm = 0xE05F
jne 0x3952
jmp 0x391d
cmpq %r13, %rax
jbe 0x3980
xorl %eax, %eax
jmp 0x39da
negq %r14
xorl %r12d, %r12d
movb (%r15,%r12), %cl
leal -0x2d(%rcx), %eax
cmpb $0x2, %al
jae 0x399c
cmpq $0xff, %r12
jbe 0x39c7
jmp 0x39d7
movq %rcx, -0x38(%rbp)
movsbq %cl, %rax
movq %rax, -0x30(%rbp)
callq 0x22b0
movq (%rax), %rax
movq -0x30(%rbp), %rcx
testb $0x8, (%rax,%rcx,2)
je 0x39d7
cmpq $0x100, %r12            # imm = 0x100
movq -0x38(%rbp), %rcx
jae 0x39d7
movb %cl, (%rbx,%r12)
leaq (%r14,%r12), %rax
incq %r12
cmpq %r13, %rax
jbe 0x3986
movl %r12d, %eax
movb $0x0, (%rbx,%rax)
leaq 0x32a1(%rip), %rsi      # 0x6c86
movl $0x1, %edi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x4100
jmp 0x3936