// File: /workspace/github_c_makefile_star2_O2/TimeToogo[P]ff-proxy/src/http.c
// Function: ff_http_send_request_unencrypted
bool ff_http_send_request_unencrypted(struct ff_request *request, char *host_name)
{
    bool ret;
    struct addrinfo hints;
    struct addrinfo *res = NULL;
    char formatted_address[INET6_ADDRSTRLEN] = {0};
    struct timeval timeout = {.tv_sec = FF_HTTP_RESPONSE_MAX_WAIT_SECS, .tv_usec = 0};
    int err;
    int sockfd = 0;
    ssize_t chunk = 0;
    uint32_t sent = 0;
    uint32_t received = 0;
    char response[FF_HTTP_RESPONSE_BUFF_SIZE] = {0};

    if (host_name == NULL)
    {
        goto error;
    }

    ff_log(FF_DEBUG, "Performing DNS lookup of %s", host_name);
    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    err = getaddrinfo(host_name, "80", &hints, &res);
    if (err)
    {
        ff_log(FF_WARNING, "Failed to perform DNS lookup for host: %s", host_name);
        goto error;
    }

    // TODO: filter out private IP ranges

    sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
    if (sockfd < 0)
    {
        ff_log(FF_ERROR, "Failed to open socket");
        goto error;
    }

    setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (void *)&timeout, sizeof(timeout));

    if (res->ai_family == AF_INET)
    {
        inet_ntop(AF_INET, &((struct sockaddr_in *)res->ai_addr)->sin_addr, formatted_address, INET_ADDRSTRLEN);
    }
    else
    {
        inet_ntop(AF_INET6, &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, formatted_address, INET6_ADDRSTRLEN);
    }

    ff_log(FF_DEBUG, "Resolved host %s to ip address %s", host_name, formatted_address);

    err = connect(sockfd, res->ai_addr, res->ai_addrlen);
    if (err)
    {
        ff_log(FF_WARNING, "Failed to connect to host: %s", host_name);
        goto error;
    }

    do
    {
        chunk = write(sockfd, request->payload->value + sent, request->payload_length - sent);

        if (chunk < 0)
        {
            ff_log(FF_WARNING, "Failed to write to socket: %s (%d bytes remaining)", host_name, request->payload_length - sent);
            goto error;
        }

        if (chunk == 0)
        {
            break;
        }

        sent += (uint32_t)chunk;
    } while (sent < request->payload_length);

    ff_log(FF_DEBUG, "Finished sending request to %s over HTTP (%d bytes sent)", host_name, sent);

    do
    {
        chunk = recv(sockfd, response + received, sizeof(response) - received - 1, 0);

        if (chunk < 0)
        {
            ff_log(FF_WARNING, "Failed to read response from socket for host: %s (%d bytes received)", host_name, received);
            goto error;
        }

        if (chunk == 0)
        {
            break;
        }

        received += (uint32_t)chunk;

        if (received > 0 && strncasecmp(response, "HTTP/", 5) == 0)
        {
            break;
        }
    } while (received < sizeof(response) - 1);

    ff_log(FF_DEBUG, "Finished receiving response from %s (%d bytes received)", host_name, received);
    size_t response_header_length = strchr((char *)response, '\n') - response;
    ff_log(FF_DEBUG, "Response: %.*s", response_header_length > 100l ? 100 : (int)response_header_length, response);
    goto done;

error:
    ret = false;
    goto cleanup;

done:
    ret = true;
    goto cleanup;

cleanup:
    if (res != NULL)
    {
        freeaddrinfo(res);
    }

    if (sockfd != 0)
    {
        close(sockfd);
    }

    return ret;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1078, %rsp           # imm = 0x1078
andq $0x0, -0x30(%rbp)
movq %rsi, %r14
movq %rdi, %r15
xorps %xmm0, %xmm0
movups %xmm0, -0x42(%rbp)
movaps %xmm0, -0x50(%rbp)
movaps %xmm0, -0x60(%rbp)
movups 0x1cc7(%rip), %xmm0     # 0x57c0
movaps %xmm0, -0x70(%rbp)
leaq -0x10a0(%rbp), %rdi
xorl %ebx, %ebx
movl $0x1000, %edx           # imm = 0x1000
xorl %esi, %esi
callq 0x2190
testq %r14, %r14
je 0x3b74
leaq 0x1cb2(%rip), %rsi      # 0x57d0
xorl %ebx, %ebx
pushq $0x1
popq %rdi
movq %r14, %rdx
xorl %eax, %eax
callq 0x3db4
leaq -0xa0(%rbp), %rdx
xorps %xmm0, %xmm0
movaps %xmm0, (%rdx)
movaps %xmm0, 0x20(%rdx)
movaps %xmm0, 0x10(%rdx)
movl $0x1, 0x8(%rdx)
leaq 0x1c9c(%rip), %rsi      # 0x57ec
leaq -0x30(%rbp), %rcx
movq %r14, %rdi
callq 0x2370
testl %eax, %eax
je 0x3ba5
leaq 0x1c88(%rip), %rsi      # 0x57ef
pushq $0x3
popq %rdi
movq %r14, %rdx
xorl %eax, %eax
callq 0x3db4
xorl %r15d, %r15d
movq -0x30(%rbp), %rdi
testq %rdi, %rdi
je 0x3b85
callq 0x2390
testl %ebx, %ebx
je 0x3b90
movl %ebx, %edi
callq 0x24f0
movl %r15d, %eax
addq $0x1078, %rsp           # imm = 0x1078
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq -0x30(%rbp), %rax
movl 0x4(%rax), %edi
movl 0x8(%rax), %esi
movl 0xc(%rax), %edx
callq 0x2090
movl %eax, %ebx
testl %eax, %eax
js 0x3bef
pushq $0x1
popq %rsi
pushq $0x14
popq %rdx
leaq -0x70(%rbp), %rcx
pushq $0x10
popq %r8
movl %ebx, %edi
callq 0x2480
movq -0x30(%rbp), %rax
cmpl $0x2, 0x4(%rax)
movq 0x18(%rax), %rsi
jne 0x3c08
addq $0x4, %rsi
pushq $0x2
popq %rdi
leaq -0x60(%rbp), %rdx
pushq $0x10
jmp 0x3c15
leaq 0x1c23(%rip), %rsi      # 0x5819
xorl %r15d, %r15d
pushq $0x4
popq %rdi
xorl %eax, %eax
callq 0x3db4
jmp 0x3b77
addq $0x8, %rsi
pushq $0xa
popq %rdi
leaq -0x60(%rbp), %rdx
pushq $0x2e
popq %rcx
callq 0x22a0
leaq 0x1c0d(%rip), %rsi      # 0x582f
xorl %r13d, %r13d
pushq $0x1
popq %rdi
leaq -0x60(%rbp), %rcx
movq %r14, %rdx
xorl %eax, %eax
callq 0x3db4
movq -0x30(%rbp), %rax
movq 0x18(%rax), %rsi
movl 0x10(%rax), %edx
movl %ebx, %edi
callq 0x2270
testl %eax, %eax
je 0x3c68
leaq 0x1bfe(%rip), %rsi      # 0x5851
xorl %r15d, %r15d
pushq $0x3
popq %rdi
movq %r14, %rdx
xorl %eax, %eax
callq 0x3db4
jmp 0x3b77
movq 0x40(%r15), %rdx
movq 0x50(%r15), %rax
movl %r13d, %r12d
movq 0x8(%rax), %rsi
addq %r12, %rsi
subq %r12, %rdx
movl %ebx, %edi
callq 0x20e0
testq %rax, %rax
js 0x3d65
je 0x3c9b
addl %eax, %r13d
movq 0x40(%r15), %rdx
cmpq %r13, %rdx
ja 0x3c6c
leaq 0x1c00(%rip), %rsi      # 0x58a2
xorl %r12d, %r12d
pushq $0x1
popq %rdi
movq %r14, %rdx
movl %r13d, %ecx
xorl %eax, %eax
callq 0x3db4
leaq 0x1c64(%rip), %r13      # 0x5920
pushq $0x5
popq %r15
movl %r12d, %eax
leaq (%rax,%rbp), %rsi
addq $-0x10a0, %rsi          # imm = 0xEF60
movl $0xfff, %edx            # imm = 0xFFF
subq %rax, %rdx
movl %ebx, %edi
xorl %ecx, %ecx
callq 0x20c0
testq %rax, %rax
js 0x3d88
je 0x3d0e
addl %eax, %r12d
je 0x3cc0
leaq -0x10a0(%rbp), %rdi
movq %r13, %rsi
movq %r15, %rdx
callq 0x2380
cmpl $0xffe, %r12d           # imm = 0xFFE
ja 0x3d0e
testl %eax, %eax
jne 0x3cc0
leaq 0x1c11(%rip), %rsi      # 0x5926
pushq $0x1
popq %r15
movl %r15d, %edi
movq %r14, %rdx
movl %r12d, %ecx
xorl %eax, %eax
callq 0x3db4
pushq $0xa
popq %rsi
leaq -0x10a0(%rbp), %r14
movq %r14, %rdi
callq 0x20f0
subq %r14, %rax
cmpq $0x64, %rax
pushq $0x64
popq %rdx
cmovbq %rax, %rdx
leaq 0x1c0e(%rip), %rsi      # 0x595e
movl %r15d, %edi
movq %r14, %rcx
xorl %eax, %eax
callq 0x3db4
movb $0x1, %r15b
jmp 0x3b77
movq 0x40(%r15), %rcx
subq %r12, %rcx
leaq 0x1afc(%rip), %rsi      # 0x586f
xorl %r15d, %r15d
pushq $0x3
popq %rdi
movq %r14, %rdx
xorl %eax, %eax
callq 0x3db4
jmp 0x3b77
leaq 0x1b4c(%rip), %rsi      # 0x58db
xorl %r15d, %r15d
pushq $0x3
popq %rdi
movq %r14, %rdx
movl %r12d, %ecx
xorl %eax, %eax
callq 0x3db4
jmp 0x3b77
nop