Filter tin-canny-learndash-reporting

uo_tincanny_protection_headers

Filters the HTTP headers used for Tincanny protection, allowing modification before they are sent.

add_filter( 'uo_tincanny_protection_headers', $callback, 10, 1 );

Description

Filters the HTTP headers used for Tincanny protection. Developers can modify or add headers to control caching or robot indexing for protected content. This hook fires just before headers are sent, so any modifications affect the final output.


Usage

add_filter( 'uo_tincanny_protection_headers', 'your_function_name', 10, 1 );

Parameters

$headers (mixed)
This parameter contains an array of HTTP headers that are being filtered to modify or add to the security headers for Tin Can API protection.

Return Value

The filtered value.


Examples

/**
 * Add a custom header to the Tincanny protection headers.
 *
 * This example adds a 'X-Content-Security-Policy' header to enhance security.
 *
 * @param array $headers The existing headers array.
 * @return array The modified headers array with the new header added.
 */
add_filter( 'uo_tincanny_protection_headers', function( $headers ) {
	// Define a more restrictive Content Security Policy.
	// This example blocks inline scripts and styles, and only allows content
	// from the same origin. Adjust as needed for your specific site requirements.
	$csp_policy = "default-src 'self'; script-src 'self'; object-src 'none'; style-src 'self';";

	// Add the CSP header. Note that modern browsers prefer 'Content-Security-Policy',
	// but 'X-Content-Security-Policy' provides broader compatibility.
	// You might choose to include both or just the modern one depending on your target audience.
	$headers['Content-Security-Policy'] = 'Content-Security-Policy: ' . $csp_policy;
	$headers['X-Content-Security-Policy'] = 'X-Content-Security-Policy: ' . $csp_policy;

	return $headers;
}, 10, 1 );

Placement

This code should be placed in the functions.php file of your active theme, a custom plugin, or using a code snippets plugin.


Source Code

src/core/tin-canny-protection.php:140

private function set_headers() {

		$headers = array(
			// Set content type
			'Content-Type' => 'Content-Type: ' . $this->get_content_type(),
			// Set X-Robots-Tag
			'X-Robots-Tag' => 'X-Robots-Tag: none',
		);

		// Set content length
		if ( strpos( $_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS' ) === false ) {
			$headers['Content-Length'] = 'Content-Length: ' . filesize( $this->content_data->complete_path );
		}

		// Set Cache control
		$headers['Cache-Control'] = 'Cache-Control: no-store, no-cache, must-revalidate';
		$headers['Pragma']        = 'Pragma: no-cache';
		$headers['Expires']       = 'Expires: ' . gmdate( 'D, d M Y H:i:s', time() + 100000000 ) . ' GMT';

		// Get and set last modified date
		$last_modified            = gmdate( 'D, d M Y H:i:s', filemtime( $this->content_data->complete_path ) );
		$headers['Last-Modified'] = 'Last-Modified: ' . $last_modified . ' GMT';

		// Create eTag using a md5 hash of the last modified date
		$etag            = '"' . md5( $last_modified ) . '"';
		$headers['ETag'] = 'ETag: ' . $etag;

		// Check if it supports xsendfile
		if ( $this->supports_mod_xsendfile() ) {
			$headers['X-Sendfile'] = 'X-Sendfile: ' . $this->content_data->complete_path;
		}

		$headers = apply_filters( 'uo_tincanny_protection_headers', $headers );

		if ( is_array( $headers ) && ! empty( $headers ) ) {
			foreach ( $headers as $header ) {
				if ( ! empty( $header ) ) {
					header( $header );
				}
			}
		}

		// Get client eTag
		$client_etag = isset( $_SERVER['HTTP_IF_NONE_MATCH'] ) ? stripslashes( $_SERVER['HTTP_IF_NONE_MATCH'] ) : false;

		if ( ! isset( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) ) {
			$_SERVER['HTTP_IF_MODIFIED_SINCE'] = false;
		}

		// Get client last modified
		$client_last_modified = trim( $_SERVER['HTTP_IF_MODIFIED_SINCE'] );
		// Get the timestamp
		$client_modified_timestamp = $client_last_modified ? strtotime( $client_last_modified ) : 0;

		// Make a timestamp for our most recent modification
		$modified_timestamp = strtotime( $last_modified );

		// Check if the client data is defined
		$is_client_data_defined = $client_last_modified && $client_etag;
		// Check if the client has a more recent change to the file than the file in the server
		$client_has_more_recent_modification = $client_modified_timestamp >= $modified_timestamp;
		// Check if the client has the same eTag
		$client_has_same_etag = $client_etag == $etag;
		// Compare last modified from the file with the last modified from the client
		if ( $is_client_data_defined ? ( $client_has_more_recent_modification && $client_has_same_etag ) : ( $client_has_more_recent_modification || $client_has_same_etag ) ) {
			status_header( apply_filters( 'uo_tincanny_file_motified_http_status_code', 304 ) );
			exit;
		}
	}

Scroll to Top