// File: /workspace/github_c_makefile_star2_O3/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
movq %rsi, %r14
movq %rdi, %r15
movq $0x0, -0x30(%rbp)
xorps %xmm0, %xmm0
movups %xmm0, -0x42(%rbp)
movaps %xmm0, -0x50(%rbp)
movaps %xmm0, -0x60(%rbp)
movups 0x2b13(%rip), %xmm0     # 0x67c0
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 0x3d2c
leaq 0x2afe(%rip), %rsi      # 0x67d0
xorl %ebx, %ebx
movl $0x1, %edi
movq %r14, %rdx
xorl %eax, %eax
callq 0x3fa4
leaq -0xa0(%rbp), %rdx
xorps %xmm0, %xmm0
movaps %xmm0, (%rdx)
movaps %xmm0, 0x20(%rdx)
movaps %xmm0, 0x10(%rdx)
movl $0x1, 0x8(%rdx)
leaq 0x2ae6(%rip), %rsi      # 0x67ec
leaq -0x30(%rbp), %rcx
movq %r14, %rdi
callq 0x2370
testl %eax, %eax
je 0x3d5d
leaq 0x2ad2(%rip), %rsi      # 0x67ef
movl $0x3, %edi
movq %r14, %rdx
xorl %eax, %eax
callq 0x3fa4
xorl %r12d, %r12d
movq -0x30(%rbp), %rdi
testq %rdi, %rdi
je 0x3d3d
callq 0x2390
testl %ebx, %ebx
je 0x3d48
movl %ebx, %edi
callq 0x24f0
movl %r12d, %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 0x3db2
leaq -0x70(%rbp), %rcx
movl %ebx, %edi
movl $0x1, %esi
movl $0x14, %edx
movl $0x10, %r8d
callq 0x2480
movq -0x30(%rbp), %rax
cmpl $0x2, 0x4(%rax)
movq 0x18(%rax), %rsi
jne 0x3dcd
addq $0x4, %rsi
leaq -0x60(%rbp), %rdx
movl $0x2, %edi
movl $0x10, %ecx
jmp 0x3ddf
leaq 0x2a60(%rip), %rsi      # 0x6819
xorl %r12d, %r12d
movl $0x4, %edi
xorl %eax, %eax
callq 0x3fa4
jmp 0x3d2f
addq $0x8, %rsi
leaq -0x60(%rbp), %rdx
movl $0xa, %edi
movl $0x2e, %ecx
callq 0x22a0
leaq 0x2a44(%rip), %rsi      # 0x682f
xorl %r12d, %r12d
leaq -0x60(%rbp), %rcx
movl $0x1, %edi
movq %r14, %rdx
xorl %eax, %eax
callq 0x3fa4
movq -0x30(%rbp), %rax
movq 0x18(%rax), %rsi
movl 0x10(%rax), %edx
movl %ebx, %edi
callq 0x2270
testl %eax, %eax
je 0x3e35
leaq 0x2a33(%rip), %rsi      # 0x6851
xorl %r12d, %r12d
movl $0x3, %edi
movq %r14, %rdx
xorl %eax, %eax
callq 0x3fa4
jmp 0x3d2f
movq 0x40(%r15), %rdx
movq 0x50(%r15), %rax
movl %r12d, %r13d
movq 0x8(%rax), %rsi
addq %r13, %rsi
subq %r13, %rdx
movl %ebx, %edi
callq 0x20e0
testq %rax, %rax
js 0x3f1f
je 0x3e68
addl %eax, %r12d
movq 0x40(%r15), %rdx
cmpq %r12, %rdx
ja 0x3e39
leaq 0x2a33(%rip), %rsi      # 0x68a2
xorl %r15d, %r15d
movl $0x1, %edi
movq %r14, %rdx
movl %r12d, %ecx
xorl %eax, %eax
callq 0x3fa4
leaq -0x10a0(%rbp), %rsi
movl $0xfff, %edx            # imm = 0xFFF
movl %ebx, %edi
xorl %ecx, %ecx
callq 0x20c0
testq %rax, %rax
js 0x3efe
xorl %r15d, %r15d
leaq 0x2a78(%rip), %r13      # 0x6920
leaq -0x10a0(%rbp), %r12
testq %rax, %rax
je 0x3f44
addl %eax, %r15d
je 0x3eda
movl $0x5, %edx
movq %r12, %rdi
movq %r13, %rsi
callq 0x2380
cmpl $0xffe, %r15d           # imm = 0xFFE
ja 0x3f44
testl %eax, %eax
je 0x3f44
movl %r15d, %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
jns 0x3eaf
leaq 0x29d6(%rip), %rsi      # 0x68db
xorl %r12d, %r12d
movl $0x3, %edi
movq %r14, %rdx
movl %r15d, %ecx
xorl %eax, %eax
callq 0x3fa4
jmp 0x3d2f
movq 0x40(%r15), %rcx
subq %r13, %rcx
leaq 0x2942(%rip), %rsi      # 0x686f
xorl %r12d, %r12d
movl $0x3, %edi
movq %r14, %rdx
xorl %eax, %eax
callq 0x3fa4
jmp 0x3d2f
leaq 0x29db(%rip), %rsi      # 0x6926
movl $0x1, %edi
movq %r14, %rdx
movl %r15d, %ecx
xorl %eax, %eax
callq 0x3fa4
movq %r12, %rdi
movl $0xa, %esi
callq 0x20f0
subq %r12, %rax
cmpq $0x64, %rax
movl $0x64, %edx
cmovbq %rax, %rdx
leaq 0x29dd(%rip), %rsi      # 0x695e
movl $0x1, %edi
movq %r12, %rcx
xorl %eax, %eax
callq 0x3fa4
movb $0x1, %r12b
jmp 0x3d2f