// File: /workspace/github_c_makefile_star2_O0/TimeToogo[P]ff-proxy/src/http.c
// Function: ff_http_send_request_tls
bool ff_http_send_request_tls(struct ff_request *request, char *host_name)
{
    bool ret;
    long res = 1;

    SSL_CTX *ctx = NULL;
    BIO *web = NULL;
    SSL *ssl = NULL;
    char error_string[256] = {0};

    int chunk = 0;
    int sent = 0;
    int received = 0;
    char response[FF_HTTP_RESPONSE_BUFF_SIZE] = {0};

    const SSL_METHOD *method = SSLv23_method();
    if (method == NULL)
    {
        ff_log(FF_ERROR, "Failed to initialise OpenSSL method");
        goto error;
    }

    ctx = SSL_CTX_new(method);
    if (ctx == NULL)
    {
        ff_log(FF_ERROR, "Failed to initialise OpenSSL context");
        goto error;
    }

    SSL_CTX_set_default_verify_paths(ctx);

    web = BIO_new_ssl_connect(ctx);

    if (web == NULL)
    {
        ff_log(FF_ERROR, "Failed to initialise OpenSSL connection");
        goto error;
    }

    res = BIO_set_conn_hostname(web, host_name);
    res = BIO_set_conn_port(web, "443");
    if (res != 1)
    {
        ff_log(FF_ERROR, "Failed to set OpenSSL connection host name");
        goto error;
    }

    BIO_get_ssl(web, &ssl);
    if (ssl == NULL)
    {
        ff_log(FF_ERROR, "Failed to set OpenSSL ssl");
        goto error;
    }

    const char *const PREFERRED_CIPHERS = "HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4";
    res = SSL_set_cipher_list(ssl, PREFERRED_CIPHERS);
    if (res != 1)
    {
        ff_log(FF_ERROR, "Failed to set OpenSSL preferred ciphers");
        goto error;
    }

    res = SSL_set_tlsext_host_name(ssl, host_name);
    if (res != 1)
    {
        ff_log(FF_ERROR, "Failed to set OpenSSL TLS host name");
        goto error;
    }

#ifndef OPENSSL_SKIP_HOST_VALIDATION
    {
        X509_VERIFY_PARAM *param = SSL_get0_param(ssl);

        res = X509_VERIFY_PARAM_set1_host(param, host_name, strlen(host_name));
        if (res != 1)
        {
            ff_log(FF_ERROR, "Failed to set OpenSSL param host name");
            goto error;
        }
    }
#endif

    SSL_set_verify(ssl, SSL_VERIFY_PEER, NULL);

    res = BIO_do_connect(web);
    if (res != 1)
    {
        ERR_error_string(ERR_get_error(), error_string);
        ff_log(FF_WARNING, "Failed to perform OpenSSL request connection: %s", error_string);
        goto error;
    }

    res = BIO_do_handshake(web);
    if (res != 1)
    {
        ERR_error_string(ERR_get_error(), error_string);
        ff_log(FF_WARNING, "Failed to perform OpenSSL request handshake: %s", error_string);
        goto error;
    }

    X509 *cert = SSL_get_peer_certificate(ssl);
    if (cert)
    {
        X509_free(cert);
    }
    if (cert == NULL)
    {
        ff_log(FF_WARNING, "Server did not present a certificate");
        goto error;
    }

    res = SSL_get_verify_result(ssl);
    if (res != X509_V_OK)
    {
        ERR_error_string(ERR_get_error(), error_string);
        ff_log(FF_WARNING, "Server certificate could not be validated against CA: %s", error_string);
        goto error;
    }

    do
    {
        chunk = BIO_write(web, request->payload->value + sent, request->payload_length - sent);
        sent += chunk;
    } while (chunk > 0);

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

    do
    {
        chunk = BIO_read(web, response + received, sizeof(response) - received);

        received += chunk;

        if (received > 5 && strncasecmp(response, "http/", 5) == 0)
        {
            break;
        }
    } while (chunk > 0 || BIO_should_retry(web));

    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 : response_header_length, response);
    goto done;

error:
    ret = false;
    goto cleanup;

done:
    ret = true;
    goto cleanup;

cleanup:
    if (web != NULL)
    {
        BIO_free_all(web);
    }

    if (ctx != NULL)
    {
        SSL_CTX_free(ctx);
    }

    return ret;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x11a0, %rsp           # imm = 0x11A0
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq $0x1, -0x20(%rbp)
movq $0x0, -0x28(%rbp)
movq $0x0, -0x30(%rbp)
movq $0x0, -0x38(%rbp)
leaq -0x140(%rbp), %rdi
xorl %esi, %esi
movl $0x100, %edx            # imm = 0x100
callq 0x21a0
movl $0x0, -0x144(%rbp)
movl $0x0, -0x148(%rbp)
movl $0x0, -0x14c(%rbp)
leaq -0x1150(%rbp), %rdi
xorl %esi, %esi
movl $0x1000, %edx           # imm = 0x1000
callq 0x21a0
callq 0x24b0
movq %rax, -0x1158(%rbp)
cmpq $0x0, -0x1158(%rbp)
jne 0x43e5
movl $0x4, %edi
leaq 0x35c4(%rip), %rsi      # 0x799d
movb $0x0, %al
callq 0x4d70
jmp 0x48a6
movq -0x1158(%rbp), %rdi
callq 0x23f0
movq %rax, -0x28(%rbp)
cmpq $0x0, -0x28(%rbp)
jne 0x4414
movl $0x4, %edi
leaq 0x35b9(%rip), %rsi      # 0x79c1
movb $0x0, %al
callq 0x4d70
jmp 0x48a6
movq -0x28(%rbp), %rdi
callq 0x2300
movq -0x28(%rbp), %rdi
callq 0x2310
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
jne 0x4449
movl $0x4, %edi
leaq 0x35a9(%rip), %rsi      # 0x79e6
movb $0x0, %al
callq 0x4d70
jmp 0x48a6
movq -0x30(%rbp), %rdi
movq -0x10(%rbp), %rcx
movl $0x64, %esi
xorl %eax, %eax
movl %eax, %edx
callq 0x20b0
movq %rax, -0x20(%rbp)
movq -0x30(%rbp), %rdi
movl $0x64, %esi
movl $0x1, %edx
leaq 0x3596(%rip), %rcx      # 0x7a0e
callq 0x20b0
movq %rax, -0x20(%rbp)
cmpq $0x1, -0x20(%rbp)
je 0x44a0
movl $0x4, %edi
leaq 0x357e(%rip), %rsi      # 0x7a12
movb $0x0, %al
callq 0x4d70
jmp 0x48a6
movq -0x30(%rbp), %rdi
movl $0x6e, %esi
xorl %eax, %eax
movl %eax, %edx
leaq -0x38(%rbp), %rcx
callq 0x20b0
cmpq $0x0, -0x38(%rbp)
jne 0x44d5
movl $0x4, %edi
leaq 0x3574(%rip), %rsi      # 0x7a3d
movb $0x0, %al
callq 0x4d70
jmp 0x48a6
leaq 0x357b(%rip), %rax      # 0x7a57
movq %rax, -0x1160(%rbp)
movq -0x38(%rbp), %rdi
leaq 0x3569(%rip), %rsi      # 0x7a57
callq 0x21e0
cltq
movq %rax, -0x20(%rbp)
cmpq $0x1, -0x20(%rbp)
je 0x4518
movl $0x4, %edi
leaq 0x3571(%rip), %rsi      # 0x7a7d
movb $0x0, %al
callq 0x4d70
jmp 0x48a6
movq -0x38(%rbp), %rdi
movq -0x10(%rbp), %rcx
movl $0x37, %esi
xorl %eax, %eax
movl %eax, %edx
callq 0x2120
movq %rax, -0x20(%rbp)
cmpq $0x1, -0x20(%rbp)
je 0x4551
movl $0x4, %edi
leaq 0x3560(%rip), %rsi      # 0x7aa5
movb $0x0, %al
callq 0x4d70
jmp 0x48a6
movq -0x38(%rbp), %rdi
callq 0x2030
movq %rax, -0x1168(%rbp)
movq -0x1168(%rbp), %rax
movq %rax, -0x1188(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x1180(%rbp)
movq -0x10(%rbp), %rdi
callq 0x2140
movq -0x1188(%rbp), %rdi
movq -0x1180(%rbp), %rsi
movq %rax, %rdx
callq 0x2500
cltq
movq %rax, -0x20(%rbp)
cmpq $0x1, -0x20(%rbp)
je 0x45be
movl $0x4, %edi
leaq 0x3517(%rip), %rsi      # 0x7ac9
movb $0x0, %al
callq 0x4d70
jmp 0x48a6
movq -0x38(%rbp), %rdi
movl $0x1, %esi
xorl %eax, %eax
movl %eax, %edx
callq 0x2210
movq -0x30(%rbp), %rdi
movl $0x65, %esi
xorl %eax, %eax
movl %eax, %ecx
movq %rcx, %rdx
callq 0x20b0
movq %rax, -0x20(%rbp)
cmpq $0x1, -0x20(%rbp)
je 0x4623
callq 0x23d0
movq %rax, %rdi
leaq -0x140(%rbp), %rsi
callq 0x20c0
leaq -0x140(%rbp), %rdx
movl $0x3, %edi
leaq 0x34d8(%rip), %rsi      # 0x7aef
movb $0x0, %al
callq 0x4d70
jmp 0x48a6
movq -0x30(%rbp), %rdi
movl $0x65, %esi
xorl %eax, %eax
movl %eax, %ecx
movq %rcx, %rdx
callq 0x20b0
movq %rax, -0x20(%rbp)
cmpq $0x1, -0x20(%rbp)
je 0x4676
callq 0x23d0
movq %rax, %rdi
leaq -0x140(%rbp), %rsi
callq 0x20c0
leaq -0x140(%rbp), %rdx
movl $0x3, %edi
leaq 0x34b6(%rip), %rsi      # 0x7b20
movb $0x0, %al
callq 0x4d70
jmp 0x48a6
movq -0x38(%rbp), %rdi
callq 0x24e0
movq %rax, -0x1170(%rbp)
cmpq $0x0, -0x1170(%rbp)
je 0x469c
movq -0x1170(%rbp), %rdi
callq 0x2190
cmpq $0x0, -0x1170(%rbp)
jne 0x46be
movl $0x3, %edi
leaq 0x349e(%rip), %rsi      # 0x7b50
movb $0x0, %al
callq 0x4d70
jmp 0x48a6
movq -0x38(%rbp), %rdi
callq 0x2110
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x20(%rbp)
je 0x4705
callq 0x23d0
movq %rax, %rdi
leaq -0x140(%rbp), %rsi
callq 0x20c0
leaq -0x140(%rbp), %rdx
movl $0x3, %edi
leaq 0x347c(%rip), %rsi      # 0x7b75
movb $0x0, %al
callq 0x4d70
jmp 0x48a6
jmp 0x4707
movq -0x30(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x50(%rax), %rax
movq 0x8(%rax), %rsi
movslq -0x148(%rbp), %rax
addq %rax, %rsi
movq -0x8(%rbp), %rax
movq 0x40(%rax), %rax
movslq -0x148(%rbp), %rcx
subq %rcx, %rax
movl %eax, %edx
callq 0x22f0
movl %eax, -0x144(%rbp)
movl -0x144(%rbp), %eax
addl -0x148(%rbp), %eax
movl %eax, -0x148(%rbp)
cmpl $0x0, -0x144(%rbp)
jg 0x4707
movq -0x10(%rbp), %rdx
movl -0x148(%rbp), %ecx
movl $0x1, %edi
leaq 0x343d(%rip), %rsi      # 0x7bae
movb $0x0, %al
callq 0x4d70
movq -0x30(%rbp), %rdi
leaq -0x1150(%rbp), %rsi
movslq -0x14c(%rbp), %rax
addq %rax, %rsi
movslq -0x14c(%rbp), %rcx
movl $0x1000, %eax           # imm = 0x1000
subq %rcx, %rax
movl %eax, %edx
callq 0x2330
movl %eax, -0x144(%rbp)
movl -0x144(%rbp), %eax
addl -0x14c(%rbp), %eax
movl %eax, -0x14c(%rbp)
cmpl $0x5, -0x14c(%rbp)
jle 0x47e3
leaq -0x1150(%rbp), %rdi
leaq 0x3416(%rip), %rsi      # 0x7be8
movl $0x5, %edx
callq 0x2390
cmpl $0x0, %eax
jne 0x47e3
jmp 0x481e
jmp 0x47e5
movb $0x1, %al
cmpl $0x0, -0x144(%rbp)
movb %al, -0x1189(%rbp)
jg 0x4810
movq -0x30(%rbp), %rdi
movl $0x8, %esi
callq 0x2410
cmpl $0x0, %eax
setne %al
movb %al, -0x1189(%rbp)
movb -0x1189(%rbp), %al
testb $0x1, %al
jne 0x4778
movq -0x10(%rbp), %rdx
movl -0x14c(%rbp), %ecx
movl $0x1, %edi
leaq 0x3122(%rip), %rsi      # 0x7956
movb $0x0, %al
callq 0x4d70
leaq -0x1150(%rbp), %rdi
movl $0xa, %esi
callq 0x2100
leaq -0x1150(%rbp), %rcx
subq %rcx, %rax
movq %rax, -0x1178(%rbp)
cmpq $0x64, -0x1178(%rbp)
jbe 0x4875
movl $0x64, %eax
movq %rax, -0x1198(%rbp)
jmp 0x4883
movq -0x1178(%rbp), %rax
movq %rax, -0x1198(%rbp)
movq -0x1198(%rbp), %rdx
leaq -0x1150(%rbp), %rcx
movl $0x1, %edi
leaq 0x30f1(%rip), %rsi      # 0x798e
movb $0x0, %al
callq 0x4d70
jmp 0x48ac
movb $0x0, -0x11(%rbp)
jmp 0x48b0
movb $0x1, -0x11(%rbp)
cmpq $0x0, -0x30(%rbp)
je 0x48c0
movq -0x30(%rbp), %rdi
callq 0x2130
cmpq $0x0, -0x28(%rbp)
je 0x48d0
movq -0x28(%rbp), %rdi
callq 0x2060
movb -0x11(%rbp), %al
andb $0x1, %al
addq $0x11a0, %rsp           # imm = 0x11A0
popq %rbp
retq
nop