capachehttpsapache-modules

How to determine if a connection used encryption/SSL from apache2 httpd module?


In the context of an Apache2 module written in C, how can I determine if a request (request_rec *r) is encrypted? I've seen code that seems to do that, but I either haven't been able to figure out how to implement it or it always return 'true', even on unencrypted connections.

In PHP, $_SERVER['HTTPS'] gets set to 'on' if HTTPS is used.


Solution

  • In your own module, define

    #include <mod_ssl.h>
    
    static int is_https(conn_rec *c)
    {
        int (*is_https_conn)(conn_rec *c);
        is_https_conn = APR_RETRIEVE_OPTIONAL_FN(ssl_is_https);
        if (is_https_conn)
            return is_https_conn(c);
        return 0;
    }
    

    so you can test if request request_rec *r uses an SSL/TLS connection, using

    if (is_https(r->connection)) {
       /* Yes, request is via an SSL/TLS-encrypted connection */
    } else {
       /* No, the request is not via an encrypted connection */
    }
    

    The logic is based on the fact that the SSL/TLS module uses APR_REGISTER_OPTIONAL_FN(ssl_is_https) to register the function ssl_is_https() in modules/ssl/ssl_engine_vars.c:ssl_var_register(). This function takes a connection (conn_rec *), and returns nonzero if the connection uses SSL/TLS encryption (HTTPS).

    We use APR_RETRIEVE_OPTIONAL_FN(ssl_is_https) to retrieve the pointer to said function. If it is not registered, this returns NULL (and obviously no connection can then be encrypted). If it returns a non-NULL pointer, we call the function. It will return nonzero if the connection is HTTPS.