diff --git a/force-https.php b/force-https.php new file mode 100644 index 0000000..6050173 --- /dev/null +++ b/force-https.php @@ -0,0 +1,231 @@ +]*\s*(?:href|src|action|content|formaction)=["\'])http://([^"\']+)#'; + + // match script and style content + static $script_style_pattern = '#(<(?i:script|style)\b[^>]*>)(.*?)#s'; + + // replace http with https in elements + $content = preg_replace_callback( + $element_pattern, + function ( $matches ) { + return $matches[1] . 'https://' . $matches[2]; + }, + $content + ); + + // replace http and escaped http in script and style blocks + return preg_replace_callback( + $script_style_pattern, + function ( $matches ) { + preg_match('/<\s*(script|style)/i', $matches[1], $tag_match); + return $matches[1] . str_replace( + ['http://', 'http:\/\/'], + ['https://', 'https:\/\/'], + $matches[2] + ) . ''; + }, + $content + ); +} + +// enforce https on wp resource hints to prevent mixed content issues +add_filter( 'wp_resource_hints', 'force_https_fix_resource_hints', 20 ); +function force_https_fix_resource_hints( $urls ) { + // return unchanged if not an array + if ( ! is_array( $urls ) ) { + return $urls; + } + + // loop through each url and enforce https where needed + foreach ( $urls as $key => $url ) { + if ( is_string( $url ) ) { + $urls[$key] = set_url_scheme( $url, 'https' ); + } elseif ( is_array( $url ) && isset( $url['href'] ) ) { + $urls[$key]['href'] = set_url_scheme( $url['href'], 'https' ); + } + } + + return $urls; +} + +// enforce https on image srcsets to prevent mixed content issues +add_filter( 'wp_calculate_image_srcset', 'force_https_fix_image_srcsets', 999 ); +function force_https_fix_image_srcsets( $sources ) { + // return unchanged if sources is not an array + if ( ! is_array( $sources ) ) { + return $sources; + } + + // loop through each source and enforce https on urls + foreach ( $sources as $key => $source ) { + // check if url is set and enforce https + if ( isset( $source['url'] ) ) { + $sources[$key]['url'] = set_url_scheme( $source['url'], 'https' ); + } + } + + return $sources; +} + +// enforce https on urls in the upload directory to avoid insecure media links +add_filter( 'upload_dir', 'force_https_fix_upload_dir', 999 ); +function force_https_fix_upload_dir( $uploads ) { + + // enforce https on the main upload url + if ( isset( $uploads['url'] ) ) { + $uploads['url'] = set_url_scheme( $uploads['url'], 'https' ); + } + + // enforce https on the base upload url + if ( isset( $uploads['baseurl'] ) ) { + $uploads['baseurl'] = set_url_scheme( $uploads['baseurl'], 'https' ); + } + + return $uploads; +} + +// Ref: ChatGPT diff --git a/LICENSE b/license similarity index 100% rename from LICENSE rename to license diff --git a/readme.md b/readme.md index c6b8e0d..95cc885 100755 --- a/readme.md +++ b/readme.md @@ -1,44 +1,120 @@ # Force HTTPS -Redirects all HTTP requests to the HTTPS version and fixes insecure links and resources without altering the database (also works with CloudFlare). - -* [Plugin Homepage](https://www.littlebizzy.com/plugins/force-https) -* [**Become A LittleBizzy.com Member Today!**](https://www.littlebizzy.com/members) - -### Defined Constants - - /* Plugin Meta */ - define('DISABLE_NAG_NOTICES', true); - - /* Force HTTPS Functions */ - define('FORCE_HTTPS', true); - define('FORCE_HTTPS_EXTERNAL_LINKS', false); - define('FORCE_HTTPS_EXTERNAL_RESOURCES', true); - define('FORCE_HTTPS_INTERNAL_LINKS', true); - define('FORCE_HTTPS_INTERNAL_RESOURCES', true); - -### Release Downloads (ZIP) - -[1.3.0](https://github.com/littlebizzy/force-https/archive/1.3.0.zip), [1.2.1](https://github.com/littlebizzy/force-https/archive/1.2.1.zip), [1.2.0](https://github.com/littlebizzy/force-https/archive/1.2.0.zip), [1.1.4](https://github.com/littlebizzy/force-https/archive/1.1.4.zip), [1.1.3](https://github.com/littlebizzy/force-https/archive/1.1.3.zip), [1.1.2](https://github.com/littlebizzy/force-https/archive/1.1.2.zip), [1.1.1](https://github.com/littlebizzy/force-https/archive/1.1.1.zip), [1.1.0](https://github.com/littlebizzy/force-https/archive/1.1.0.zip), [1.0.6](https://github.com/littlebizzy/force-https/archive/1.0.6.zip), [1.0.5](https://github.com/littlebizzy/force-https/archive/1.0.5.zip), [1.0.4](https://github.com/littlebizzy/force-https/archive/1.0.4.zip), [1.0.3](https://github.com/littlebizzy/force-https/archive/1.0.3.zip), [1.0.2](https://github.com/littlebizzy/force-https/archive/1.0.2.zip), [1.0.1](https://github.com/littlebizzy/force-https/archive/1.0.1.zip), [1.0.0](https://github.com/littlebizzy/force-https/archive/1.0.0.zip) - -### Our Philosophy - -> "Decisions, not options." — WordPress.org (originally) - -> "Everything should be made as simple as possible, but not simpler." — Albert Einstein, et al - -> "Write programs that do one thing and do it well... write programs to work together." — Doug McIlroy - -> "The innovation that this industry talks about so much is bullshit. Anybody can innovate... 99% of it is 'get the work done.' The real work is in the details." — Linus Torvalds - -### Compatibility - -This plugin has been designed for use on [SlickStack](https://slickstack.io) web servers with PHP 7.2 and MySQL 5.7 to achieve best performance. All of our plugins are meant for single site WordPress installations only; for both performance and usability reasons, we strongly recommend avoiding WordPress Multisite for the vast majority of your projects. - -Any of our WordPress plugins may also be loaded as "Must-Use" plugins (meaning that they load first, and cannot be deactivated) by using our free [Autoloader](https://github.com/littlebizzy/autoloader) script in the `mu-plugins` directory. - -### Support Issues - -*Please do not submit Pull Requests. Instead, kindly create a new Issue with relevant information if you are an experienced developer, otherwise post your comments in our free Facebook group.* - -***No emails, please! Thank you.*** +HTTPS enforcement for WordPress + +## Changelog + +## 3.0.1 +- improved WP-CLI and WP-Cron compatibility with home/siteurl filtering logic + +## 3.0.0 +- added `Tested up to` header +- added `Update URI` header +- added `Text Domain` header +- improved HTTPS redirection that skips WP-CLI, WP-Cron, and AJAX +- now leveraging `pre_option_home` and `pre_option_siteurl` to override WordPress sequence early +- several more `add_filter` being enforced +- refined regex in `the_content` to correctly process `