really-simple-ssl
Last commit date
assets
10 months ago
languages
10 months ago
lets-encrypt
10 months ago
lib
10 months ago
mailer
10 months ago
modal
10 months ago
onboarding
10 months ago
placeholders
10 months ago
progress
10 months ago
security
10 months ago
settings
10 months ago
testssl
10 months ago
upgrade
10 months ago
.wp-env.json
10 months ago
class-admin.php
10 months ago
class-cache.php
10 months ago
class-certificate.php
10 months ago
class-front-end.php
10 months ago
class-installer.php
10 months ago
class-mixed-content-fixer.php
10 months ago
class-multisite.php
10 months ago
class-server.php
10 months ago
class-site-health.php
10 months ago
class-wp-cli.php
10 months ago
compatibility.php
10 months ago
force-deactivate.txt
10 months ago
functions.php
10 months ago
index.php
10 months ago
readme.txt
10 months ago
rector.php
10 months ago
rlrsssl-really-simple-ssl.php
10 months ago
rsssl-auto-loader.php
10 months ago
security.md
10 months ago
ssl-test-page.php
10 months ago
system-status.php
10 months ago
uninstall.php
10 months ago
upgrade.php
10 months ago
class-mixed-content-fixer.php
184 lines
| 1 | <?php |
| 2 | defined('ABSPATH') or die("you do not have access to this page!"); |
| 3 | |
| 4 | if (!class_exists('rsssl_admin_mixed_content_fixer')) { |
| 5 | class rsssl_mixed_content_fixer |
| 6 | { |
| 7 | private static $_this; |
| 8 | public $http_urls = array(); |
| 9 | public $mixed_content_fixer = false; |
| 10 | public $hide_wordpress_version = false; |
| 11 | |
| 12 | function __construct() |
| 13 | { |
| 14 | if (isset(self::$_this)) wp_die(); |
| 15 | |
| 16 | self::$_this = $this; |
| 17 | $this->mixed_content_fixer = is_ssl() && rsssl_get_option('mixed_content_fixer', true ); |
| 18 | $this->hide_wordpress_version = rsssl_get_option('hide_wordpress_version' ); |
| 19 | if ( !is_admin() && ($this->mixed_content_fixer || $this->hide_wordpress_version )) { |
| 20 | $this->handle_output_buffer(); |
| 21 | } else if ( is_admin() && is_ssl() && rsssl_get_option("admin_mixed_content_fixer") ) { |
| 22 | $this->mixed_content_fixer = true; |
| 23 | $this->handle_output_buffer(); |
| 24 | } |
| 25 | } |
| 26 | |
| 27 | static function this() |
| 28 | { |
| 29 | return self::$_this; |
| 30 | } |
| 31 | |
| 32 | /** |
| 33 | * |
| 34 | * add action hooks at the start and at the end of the WP process. |
| 35 | * |
| 36 | * @since 2.3 |
| 37 | * |
| 38 | * @access public |
| 39 | * |
| 40 | */ |
| 41 | |
| 42 | public function handle_output_buffer() |
| 43 | { |
| 44 | /* Do not fix mixed content when call is coming from wp_api or from xmlrpc */ |
| 45 | if (defined('JSON_REQUEST') && JSON_REQUEST) return; |
| 46 | if (defined('XMLRPC_REQUEST') && XMLRPC_REQUEST) return; |
| 47 | |
| 48 | $this->build_url_list(); |
| 49 | |
| 50 | if ( is_admin() ) { |
| 51 | add_action("admin_init", array($this, "start_buffer"), 100); |
| 52 | add_action("shutdown", array($this, "end_buffer"), 999); |
| 53 | } else { |
| 54 | if ( rsssl_get_option("switch_mixed_content_fixer_hook") || (defined('RSSSL_CONTENT_FIXER_ON_INIT') && RSSSL_CONTENT_FIXER_ON_INIT)) { |
| 55 | add_action("init", array($this, "start_buffer")); |
| 56 | } else { |
| 57 | add_action("template_redirect", array($this, "start_buffer")); |
| 58 | } |
| 59 | |
| 60 | add_action("shutdown", array($this, "end_buffer"), 999); |
| 61 | } |
| 62 | } |
| 63 | |
| 64 | |
| 65 | /** |
| 66 | * Apply the mixed content fixer. |
| 67 | * |
| 68 | * @since 2.3 |
| 69 | * |
| 70 | * @access public |
| 71 | * |
| 72 | */ |
| 73 | |
| 74 | public function filter_buffer($buffer) |
| 75 | { |
| 76 | if ( $this->mixed_content_fixer ) { |
| 77 | $buffer = $this->replace_insecure_links($buffer); |
| 78 | } |
| 79 | return apply_filters("rsssl_fixer_output", $buffer ); |
| 80 | } |
| 81 | |
| 82 | /** |
| 83 | * Start buffering the output |
| 84 | * |
| 85 | * @since 2.0 |
| 86 | * |
| 87 | * @access public |
| 88 | * |
| 89 | */ |
| 90 | |
| 91 | public function start_buffer() |
| 92 | { |
| 93 | ob_start(array($this, "filter_buffer")); |
| 94 | } |
| 95 | |
| 96 | /** |
| 97 | * Flush the output buffer |
| 98 | * |
| 99 | * @since 2.0 |
| 100 | * |
| 101 | * @access public |
| 102 | * |
| 103 | */ |
| 104 | |
| 105 | public function end_buffer() |
| 106 | { |
| 107 | if (ob_get_length()) ob_end_flush(); |
| 108 | } |
| 109 | |
| 110 | /** |
| 111 | * Creates an array of insecure links that should be https and an array of secure links to replace with |
| 112 | * |
| 113 | * @since 2.0 |
| 114 | * |
| 115 | * @access public |
| 116 | * |
| 117 | */ |
| 118 | |
| 119 | public function build_url_list() |
| 120 | { |
| 121 | $home = str_replace("https://", "http://", get_option('home') ); |
| 122 | $root = str_replace("://www.", "://", $home); |
| 123 | $www = str_replace("://", "://www.", $root); |
| 124 | |
| 125 | //for the escaped version, we only replace the home_url, not it's www or non www counterpart, as it is most likely not used |
| 126 | $escaped_home = str_replace("/", "\/", $home); |
| 127 | $this->http_urls = array( |
| 128 | $www, |
| 129 | $root, |
| 130 | $escaped_home, |
| 131 | "src='http://", |
| 132 | 'src="http://', |
| 133 | ); |
| 134 | } |
| 135 | |
| 136 | /** |
| 137 | * Just before the page is sent to the visitor's browser, all homeurl links are replaced with https. |
| 138 | * |
| 139 | * @since 1.0 |
| 140 | * |
| 141 | * @access public |
| 142 | * |
| 143 | */ |
| 144 | |
| 145 | public function replace_insecure_links($str) |
| 146 | { |
| 147 | //skip if file is xml |
| 148 | if ( strpos( $str, "<?xml" ) === 0 ) { |
| 149 | return $str; |
| 150 | } |
| 151 | |
| 152 | $search_array = apply_filters('rlrsssl_replace_url_args', $this->http_urls); |
| 153 | $ssl_array = str_replace(array("http://", "http:\/\/"), array("https://", "https:\/\/"), $search_array); |
| 154 | $str = str_replace($search_array, $ssl_array, $str); |
| 155 | |
| 156 | //replace all http links except hyperlinks |
| 157 | //all tags with src attr are already fixed by str_replace |
| 158 | $pattern = array( |
| 159 | '/url\([\'"]?\K(http:\/\/)(?=[^)]+)/i', |
| 160 | '/<link [^>]*?href=[\'"]\K(http:\/\/)(?=[^\'"]+)/i', |
| 161 | '/<meta property="og:image" [^>]*?content=[\'"]\K(http:\/\/)(?=[^\'"]+)/i', |
| 162 | '/<form [^>]*?action=[\'"]\K(http:\/\/)(?=[^\'"]+)/i', |
| 163 | ); |
| 164 | |
| 165 | $str = preg_replace($pattern, 'https://', $str); |
| 166 | |
| 167 | /* handle multiple images in srcset */ |
| 168 | $str = preg_replace_callback('/<img[^\>]*[^\>\S]+srcset=[\'"]\K((?:[^"\'\s,]+\s*(?:\s+\d+[wx])(?:,\s*)?)+)["\']/', array($this, 'replace_src_set'), $str); |
| 169 | return str_replace("<body", '<body data-rsssl=1', $str); |
| 170 | } |
| 171 | |
| 172 | /** |
| 173 | * Helper function |
| 174 | * |
| 175 | * */ |
| 176 | |
| 177 | public function replace_src_set($matches) { |
| 178 | return str_replace("http://", "https://", $matches[0]); |
| 179 | } |
| 180 | |
| 181 | } |
| 182 | } |
| 183 | |
| 184 |