Compile with gcc -o request request.c -lssl -lcrypto

#include <stdio.h>
#include <string.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>

#define HOST "www.python.org"
#define PORT "443"
#define REQUEST "GET / HTTP/1.1\\r\\nHost: www.python.org\\r\\nConnection: close\\r\\n\\r\\n"

void handle_openssl_error() {
    ERR_print_errors_fp(stderr);
    exit(EXIT_FAILURE);
}

int main() {
    SSL_CTX *ctx;
    SSL *ssl;
    int sock;
    struct addrinfo hints, *res;
    char buffer[4096];
    ssize_t bytes;

    // Initialize OpenSSL
    SSL_library_init();
    SSL_load_error_strings();
    OpenSSL_add_ssl_algorithms();

    // Create SSL context
    ctx = SSL_CTX_new(TLS_client_method());
    if (!ctx) {
        handle_openssl_error();
    }

    // Set up kTLS
    if (!SSL_CTX_set_options(ctx, SSL_OP_ENABLE_KTLS)) {
        fprintf(stderr, "Failed to enable kTLS.\\n");
        handle_openssl_error();
    }

    // Resolve the host
    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    if (getaddrinfo(HOST, PORT, &hints, &res) != 0) {
        perror("getaddrinfo");
        exit(EXIT_FAILURE);
    }

    // Create a socket
    sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
    if (sock < 0) {
        perror("socket");
        exit(EXIT_FAILURE);
    }

    // Create an SSL object
    ssl = SSL_new(ctx);
    if (!ssl) {
        handle_openssl_error();
    }

    // Bind the socket to SSL
    SSL_set_fd(ssl, sock);

    // Connect to the server
    if (connect(sock, res->ai_addr, res->ai_addrlen) < 0) {
        perror("connect");
        exit(EXIT_FAILURE);
    }
    freeaddrinfo(res);

    // Establish TLS connection
    if (SSL_connect(ssl) <= 0) {
        handle_openssl_error();
    }
    printf("kTLS used: %d\\n", BIO_get_ktls_send(SSL_get_wbio(ssl)));
    printf("Connected with %s encryption\\n\\n\\n", SSL_get_cipher(ssl));

    // Send HTTP request
    if (SSL_write(ssl, REQUEST, strlen(REQUEST)) <= 0) {
        handle_openssl_error();
    }

    // Read the response
    while ((bytes = SSL_read(ssl, buffer, sizeof(buffer) - 1)) > 0) {
        buffer[bytes] = '\\0';
        printf("%s", buffer);
        break;
    }

    // Clean up
    SSL_shutdown(ssl);
    SSL_free(ssl);
    close(sock);
    SSL_CTX_free(ctx);
    EVP_cleanup();
    return 0;
}