// File: /workspace/github_c_makefile_star2_O2/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1108, %rsp           # imm = 0x1108
movq %rsi, %r15
movq %rdi, %r12
andq $0x0, -0x30(%rbp)
leaq -0x130(%rbp), %rdi
movl $0x100, %edx            # imm = 0x100
xorl %esi, %esi
callq 0x2190
leaq -0x1130(%rbp), %rdi
movl $0x1000, %edx           # imm = 0x1000
xorl %esi, %esi
callq 0x2190
callq 0x2490
testq %rax, %rax
je 0x38df
movq %rax, %rdi
callq 0x23d0
testq %rax, %rax
je 0x38e8
movq %rax, %rbx
movq %rax, %rdi
callq 0x22f0
movq %rbx, %rdi
callq 0x2300
testq %rax, %rax
je 0x38fe
movq %rax, %r14
pushq $0x64
popq %r13
movq %rax, %rdi
movl %r13d, %esi
xorl %edx, %edx
movq %r15, %rcx
callq 0x20a0
leaq 0x2222(%rip), %rcx      # 0x59de
pushq $0x1
popq %rdx
movq %r14, %rdi
movl %r13d, %esi
callq 0x20a0
cmpq $0x1, %rax
jne 0x3914
pushq $0x6e
popq %rsi
leaq -0x30(%rbp), %r13
movq %r14, %rdi
xorl %edx, %edx
movq %r13, %rcx
callq 0x20a0
movq (%r13), %rdi
testq %rdi, %rdi
je 0x391d
leaq 0x222b(%rip), %rsi      # 0x5a27
callq 0x21d0
cmpl $0x1, %eax
jne 0x3926
movq -0x30(%rbp), %rdi
pushq $0x37
popq %rsi
xorl %edx, %edx
movq %r15, %rcx
callq 0x2110
cmpq $0x1, %rax
jne 0x392f
movq -0x30(%rbp), %rdi
callq 0x2030
movq %rax, %r13
movq %r15, %rdi
callq 0x2130
movq %r13, %rdi
movq %r15, %rsi
movq %rax, %rdx
callq 0x24d0
cmpl $0x1, %eax
jne 0x3938
movq -0x30(%rbp), %rdi
pushq $0x1
popq %rsi
xorl %edx, %edx
callq 0x2200
pushq $0x65
popq %rsi
movq %r14, %rdi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x20a0
cmpq $0x1, %rax
jne 0x3971
pushq $0x65
popq %rsi
movq %r14, %rdi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x20a0
cmpq $0x1, %rax
jne 0x3991
movq -0x30(%rbp), %rdi
callq 0x24b0
testq %rax, %rax
je 0x39c1
movq %rax, %rdi
callq 0x2180
movq -0x30(%rbp), %rdi
callq 0x2100
testq %rax, %rax
je 0x39d2
callq 0x23b0
leaq -0x130(%rbp), %r12
movq %rax, %rdi
movq %r12, %rsi
callq 0x20b0
leaq 0x226b(%rip), %rsi      # 0x5b45
jmp 0x39af
leaq 0x2087(%rip), %rsi      # 0x596d
jmp 0x38ef
leaq 0x20a2(%rip), %rsi      # 0x5991
xorl %r15d, %r15d
pushq $0x4
popq %rdi
xorl %eax, %eax
callq 0x3db4
jmp 0x395c
leaq 0x20b1(%rip), %rsi      # 0x59b6
xorl %r15d, %r15d
pushq $0x4
popq %rdi
xorl %eax, %eax
callq 0x3db4
jmp 0x3954
leaq 0x20c7(%rip), %rsi      # 0x59e2
jmp 0x393f
leaq 0x20e9(%rip), %rsi      # 0x5a0d
jmp 0x393f
leaq 0x2120(%rip), %rsi      # 0x5a4d
jmp 0x393f
leaq 0x213f(%rip), %rsi      # 0x5a75
jmp 0x393f
leaq 0x215a(%rip), %rsi      # 0x5a99
xorl %r15d, %r15d
pushq $0x4
popq %rdi
xorl %eax, %eax
callq 0x3db4
movq %r14, %rdi
callq 0x2120
movq %rbx, %rdi
callq 0x2060
movl %r15d, %eax
addq $0x1108, %rsp           # imm = 0x1108
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
callq 0x23b0
leaq -0x130(%rbp), %r12
movq %rax, %rdi
movq %r12, %rsi
callq 0x20b0
leaq 0x2130(%rip), %rsi      # 0x5abf
jmp 0x39af
callq 0x23b0
leaq -0x130(%rbp), %r12
movq %rax, %rdi
movq %r12, %rsi
callq 0x20b0
leaq 0x2141(%rip), %rsi      # 0x5af0
xorl %r15d, %r15d
pushq $0x3
popq %rdi
movq %r12, %rdx
xorl %eax, %eax
callq 0x3db4
jmp 0x394c
leaq 0x2158(%rip), %rsi      # 0x5b20
xorl %r15d, %r15d
pushq $0x3
jmp 0x3944
xorl %r13d, %r13d
movq 0x50(%r12), %rax
movslq %r13d, %r13
movq 0x8(%rax), %rsi
addq %r13, %rsi
movl 0x40(%r12), %edx
subl %r13d, %edx
movq %r14, %rdi
callq 0x22e0
addl %eax, %r13d
testl %eax, %eax
jg 0x39d5
leaq 0x217c(%rip), %rsi      # 0x5b7e
xorl %r12d, %r12d
pushq $0x1
popq %rdi
movq %r15, %rdx
movl %r13d, %ecx
xorl %eax, %eax
callq 0x3db4
movslq %r12d, %r12
leaq (%r12,%rbp), %rsi
addq $-0x1130, %rsi          # imm = 0xEED0
movl $0x1000, %edx           # imm = 0x1000
subl %r12d, %edx
movq %r14, %rdi
callq 0x2320
movl %eax, %r13d
addl %eax, %r12d
cmpl $0x6, %r12d
jl 0x3a59
leaq -0x1130(%rbp), %rdi
leaq 0x216b(%rip), %rsi      # 0x5bb8
pushq $0x5
popq %rdx
callq 0x2380
testl %eax, %eax
je 0x3a6d
testl %r13d, %r13d
jg 0x3a15
movq %r14, %rdi
pushq $0x8
popq %rsi
callq 0x23f0
testl %eax, %eax
jne 0x3a15
leaq 0x1eb2(%rip), %rsi      # 0x5926
pushq $0x1
popq %r13
movl %r13d, %edi
movq %r15, %rdx
movl %r12d, %ecx
xorl %eax, %eax
callq 0x3db4
pushq $0xa
popq %rsi
leaq -0x1130(%rbp), %r15
movq %r15, %rdi
callq 0x20f0
subq %r15, %rax
cmpq $0x64, %rax
pushq $0x64
popq %rdx
cmovbq %rax, %rdx
leaq 0x1eaf(%rip), %rsi      # 0x595e
movl %r13d, %edi
movq %r15, %rcx
xorl %eax, %eax
callq 0x3db4
movb $0x1, %r15b
jmp 0x394c