// File: /workspace/github_c_makefile_star2_O2/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), %r12
leaq 0x2664(%rip), %rsi      # 0x5bbe
testq %r12, %r12
je 0x365c
movq 0x50(%r15), %rax
movq 0x8(%rax), %rdi
xorl %r13d, %r13d
leaq 0x270b(%rip), %r8       # 0x5c80
pushq $0x5
popq %r14
leaq 0x267c(%rip), %r9       # 0x5bfc
movq %rdi, %r15
movq %r12, %rax
subq %r13, %rax
cmpq $0x3, %rax
jb 0x35b2
cmpq %rdi, %r15
je 0x35b2
movzbl (%r15), %ecx
cmpl $0xd, %ecx
je 0x35a7
cmpl $0xa, %ecx
jne 0x35b2
jmp 0x3636
cmpb $0xa, 0x1(%r15)
je 0x3636
cmpq $0x6, %rax
jb 0x35ee
movq %rdi, -0x30(%rbp)
movq %r15, %rdi
movq %rbx, -0x40(%rbp)
movq %r8, %rsi
movq %r14, %rdx
movq %r8, %rbx
callq 0x2380
movq %rbx, %r8
movq -0x30(%rbp), %rdi
leaq 0x261d(%rip), %r9       # 0x5bfc
leaq 0x25d8(%rip), %rsi      # 0x5bbe
movq -0x40(%rbp), %rbx
testl %eax, %eax
je 0x363f
movb (%r15), %al
incq %r15
cmpb $0xa, %al
je 0x3615
incq %r13
cmpq %r12, %r13
ja 0x365c
movb (%r15), %al
testb %al, %al
je 0x365c
incq %r15
cmpq $0x1f9f, %r13           # imm = 0x1F9F
jbe 0x35f4
jmp 0x3659
cmpq %r12, %r13
jae 0x365c
cmpb $0x0, (%r15)
je 0x365c
leaq 0x1(%r13), %rax
cmpq $0x1f9f, %r13           # imm = 0x1F9F
movq %rax, %r13
jb 0x3583
jmp 0x3659
leaq 0x2605(%rip), %rsi      # 0x5c42
jmp 0x365c
leaq 0x5(%r13), %r14
cmpq %r12, %r14
ja 0x365c
movb 0x5(%r15), %al
testb %al, %al
je 0x365c
cmpq $0x1f9a, %r13           # imm = 0x1F9A
jbe 0x3682
movq %r9, %rsi
pushq $0x3
popq %rdi
xorl %eax, %eax
callq 0x3db4
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
addq $0x6, %r15
cmpb $0x20, %al
jne 0x36a7
cmpq %r12, %r14
jae 0x365c
movb (%r15), %al
testb %al, %al
je 0x365c
incq %r14
incq %r15
cmpq $0x1fa0, %r14           # imm = 0x1FA0
jne 0x3686
jmp 0x3659
xorl %r13d, %r13d
leaq (%r14,%r13), %rax
cmpq %r12, %rax
ja 0x36fe
movb -0x1(%r15,%r13), %cl
leal -0x2d(%rcx), %eax
cmpb $0x2, %al
jae 0x36ca
cmpq $0xff, %r13
jbe 0x36f5
jmp 0x36fe
movsbq %cl, %rax
movq %rax, -0x38(%rbp)
movq %rcx, -0x30(%rbp)
callq 0x22b0
movq -0x30(%rbp), %rcx
movq (%rax), %rax
movq -0x38(%rbp), %rdx
testb $0x8, (%rax,%rdx,2)
je 0x36fe
cmpq $0x100, %r13            # imm = 0x100
jae 0x36fe
movb %cl, (%rbx,%r13)
incq %r13
jmp 0x36aa
movl %r13d, %eax
movb $0x0, (%rbx,%rax)
leaq 0x257a(%rip), %rsi      # 0x5c86
pushq $0x1
popq %rdi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x3db4
jmp 0x3670