WebP Express - Version 0.18.3

Version Description

(released: 5 Nov 2020) * Bugfix: WebP Express uses live tests to determine the capabilities of the server in respect to .htaccess files (using the htaccess-capability-tester library). The results are used for warnings and also for optimizing the rules in the .htaccess files. However, HTTP Requests can fail due to other reasons than the feature not working (ie timeout). Such failures should lead to an indeterminate result, but it was interpreted as if the feature was not working. * The Live test now displays a bit more information if the HTTP request failed. * Changed default value for "destination structure" to "Image roots", as "Document root" doesn't work on hosts that have defined DOCUMENT_ROOT in an unusual way. * Added possibility to change "%{DOCUMENT_ROOT}" part of RewriteCond by adding a line to wp-config.php. THIS IS A BETA FEATURE AND MIGHT BE REVOKED IF NOBODY ACTUALLY NEEDS IT. * Got rid of PHP notice Constant WEBPEXPRESS_MIGRATION_VERSION already defined * Fixed donation link. It now points to https://ko-fi.com/rosell again

For more info, see the closed issues on the 0.18.3 milestone on the github repository

Download this release

Release Info

Developer rosell.dk
Plugin Icon 128x128 WebP Express
Version 0.18.3
Comparing to
See all releases

Code changes from version 0.18.2 to 0.18.3

Files changed (34) hide show
  1. README.md +10 -193
  2. README.txt +26 -8
  3. changelog.txt +11 -0
  4. composer.json +1 -1
  5. composer.lock +6 -6
  6. lib/classes/AdminInit.php +6 -2
  7. lib/classes/Config.php +1 -1
  8. lib/classes/ConvertHelperIndependent.php +1 -1
  9. lib/classes/HTAccess.php +11 -0
  10. lib/classes/HTAccessCapabilityTestRunner.php +3 -0
  11. lib/classes/HTAccessRules.php +12 -5
  12. lib/classes/SelfTestHelper.php +4 -1
  13. lib/classes/SelfTestRedirectToExisting.php +7 -2
  14. lib/classes/WPHttpRequester.php +1 -1
  15. lib/options/options/general/destination-structure.inc +9 -5
  16. vendor/composer/installed.json +6 -6
  17. vendor/rosell-dk/htaccess-capability-tester/.github/FUNDING.yml +1 -1
  18. vendor/rosell-dk/htaccess-capability-tester/README.md +16 -99
  19. vendor/rosell-dk/htaccess-capability-tester/docs/Running your own custom tests.md +85 -0
  20. vendor/rosell-dk/htaccess-capability-tester/src/HttpRequesterInterface.php +3 -1
  21. vendor/rosell-dk/htaccess-capability-tester/src/HttpResponse.php +0 -1
  22. vendor/rosell-dk/htaccess-capability-tester/src/SimpleHttpRequester.php +5 -3
  23. vendor/rosell-dk/htaccess-capability-tester/src/Testers/CrashTester.php +2 -2
  24. vendor/rosell-dk/htaccess-capability-tester/src/Testers/CustomTester.php +2 -0
  25. vendor/rosell-dk/htaccess-capability-tester/src/Testers/Helpers/ResponseInterpreter.php +0 -1
  26. vendor/rosell-dk/htaccess-capability-tester/src/Testers/HtaccessEnabledTester.php +4 -4
  27. vendor/rosell-dk/htaccess-capability-tester/src/Testers/InnocentRequestTester.php +1 -0
  28. vendor/rosell-dk/htaccess-capability-tester/src/Testers/ModuleLoadedTester.php +1 -1
  29. vendor/rosell-dk/htaccess-capability-tester/tests/FakeServer.php +11 -0
  30. vendor/rosell-dk/htaccess-capability-tester/tests/Testers/ContentDigestTesterTest.php +8 -0
  31. vendor/rosell-dk/htaccess-capability-tester/tests/Testers/CrashTesterTest.php +8 -0
  32. vendor/rosell-dk/htaccess-capability-tester/tests/Testers/HtaccessEnabledTesterTest.php +8 -0
  33. vendor/rosell-dk/htaccess-capability-tester/tests/Testers/ModuleLoadedTesterTest.php +8 -0
  34. webp-express.php +1 -1
README.md CHANGED
@@ -92,7 +92,7 @@ If you do not have quality detection working, you can try one of the following:
92
  ### Verifying that it works (in "Varied image responses" mode)
93
  1. Make sure at least one of the conversion methods are working. It should have a green checkmark next to it.
94
  2. If you haven't saved yet, click "Save settings". This will put redirection rules into .htaccess files in the relevant directories (typically in uploads, themes and wp-content/webp-express/webp-images, depending on the "Scope" setting)
95
- 3. I assume that you checked at least one of the checkboxes in the .htaccess rules section - otherwise you might as well change to "CDN friendly" mode. The first
96
  4. Click the "Live test" buttons to see that the enabled rules actually are working. If they are not, it *could* be that the server needs a little time to recognize the changed rules.
97
 
98
  The live tests are quite thorough and I recommend them over a manual test. However, it doesn't hurt to do a manual inspection too.
@@ -677,199 +677,16 @@ Here are my current plans ahead: 0.18 will probably be a file manager-like inter
677
 
678
  If you wish to affect priorities, it is certainly possible. You can try to argue your case in the forum or you can simply let the money do the talking. By donating as little as a cup of coffee on [ko-fi.com/rosell](https://ko-fi.com/rosell), you can leave a wish. I shall take these wishes into account when prioritizing between new features.
679
 
680
- ## Changes in 0.18.1
681
- *(released: 24 Sep 2020)*
682
- * Bugfix: Bulk Convert failed to show list on systems that did not have the [utf8-encode()](https://www.php.net/manual/en/function.utf8-encode.php) function.
 
 
 
 
 
683
 
684
- ## Changes in 0.18.0
685
- *(released: 24 Sep 2020)*
686
- * You can now set cache control header in CDN friendly mode too
687
- * The code for testing what actually works in .htaccess files on the server setup has been moved to a new library: [htaccess-capability-tester](https://github.com/rosell-dk/htaccess-capability-tester). It has been strengthened in the process.
688
- * Improved diagnosing in the "Live test" buttons
689
- * Simplified the logic for adding "Vary header" in the .htaccess residing in the cache dir. The logic no longer depends on the Apache module "mod_envif" being installed. mod_envif has Apache "Base" status, which means it is very rarely missing, so I decided not to trigger automatically updating of the .htaccess rules. To apply the change, you must click the button that forces .htaccess regeneration
690
- * The plugin has a folder called "wod" which contains php scripts for converting an image to webp. This is used for the function that rely on redirect magic to trigger conversion ("Enable redirection to converter?" and "Create webp files upon request?"). The .htaccess file in the "wod" folder in the plugin dir contains directives for modifying access (in order to counterfight rules placed by security plugins for disallows scripts to be run directly). However if these directives has been disallowed in the server setup, any request to a file in the folder will result in a 500 internal server error. To circumvent this, a "wod2" folder has been added, which contains the same scripts, but without the .htaccess. Upon saving, WebP Express now automatically checks which one works, and points to that in the .htaccess rules.
691
- * Bugfix: webp mime type was not registred in .htaccess in "CDN friendly" mode. This is a minor fix so I decided not to update the .htaccess automatically. To apply it, you must click the button that forces .htaccess regeneration.
692
- * Bugfix: Bulk convert failed to load the list when there were filenames containing non-unicode characters
693
- * Added a new way to support me. I'm on [GitHub Sponsors](https://github.com/sponsors/rosell-dk)!
694
-
695
- For more info, see the closed issues on the 0.18.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/milestone/33?closed=1
696
-
697
-
698
- ## Changes in 0.17.5
699
- *(released: 11 Aug 2020)*
700
-
701
- * Fixed "Path is outside resolved document root" in a certain symlinked configuration. Thanks to @spiderPan for providing the fix.
702
- * Added content filtering hooks for several third party plugins including ACF and WooCommerce Product Images. With this change, the "Use content filtering hooks" in Alter HTML works in more scenarios, which means there are fewer scenarios where you have to resort to the slower "The complete page" option. Thanks to alextuan for providing the contribution
703
- * Fixed problems with Alter HTML when migrating: Absolute paths were cached in the database and the cache was only updated upon saving settings. The paths are not cached anymore (recalculating these on each page load is not a performance problem)
704
-
705
- For more info, see the closed issues on the 0.17.5 milestone on the github repository: https://github.com/rosell-dk/webp-express/milestone/30?closed=1
706
-
707
- ## Changes in 0.17.4
708
- *(released: 26 Jun 2020)*
709
-
710
- * Fixed bug: Configuration was repeatedly resetting for some users
711
- * Fixed "Path is outside resolved document root" on file conversion attempts in Windows. Thanks to @Ruzgfpegk from Japan for providing the fix.
712
- * Fix errors not caught in the selftest. Thanks to Benji Bilheimer from Germany providing the fix.
713
- * Fix errors not caught in the selftest with unverified certificates. Thanks to Rikesh Ramlochund from Mauritius for providing the fix.
714
- * Fixed errors with filenames containing encoded symbols. Thanks to Eddie Zhou from Canada for the fix.
715
-
716
- For more info, see the closed issues on the 0.17.4 milestone on the github repository: https://github.com/rosell-dk/webp-express/milestone/32?closed=1
717
-
718
- ## Changes in 0.17.3
719
- *(released: 3 Feb 2020)*
720
-
721
- * Fixed critical bug: Fatal error after updating plugin (if one had been postponing updating WebP Express for a while and then updated Wordpress and THEN updated WebP Express)
722
- * A critical bug was fixed in the webp-convert library (PHP 7.4 related)
723
- * A critical bug was fixed in dom-util-for-webp library (PHP 7.4 related)
724
- * Alter HTML now processes the "poster" attribute in Video tags. Thanks to @MikhailRoot from Russia for the PR on github.
725
- * On some Litespeed hosts, WebP Express reported that mod_headers was not available even though it was. Thanks to @lubieowoce from Poland for the PR on github)
726
-
727
- For more info, see the closed issues on the 0.17.3 milestone on the github repository: https://github.com/rosell-dk/webp-express/milestone/31?closed=1
728
-
729
- ## Changes in 0.17.2
730
- *(released: 5 Oct 2019)*
731
-
732
- * Fixed bug: Updating plugin failed on some systems (in the unzip phase). Problem was introduced in 0.17.0 with the updated binaries.
733
- * Fixed bug: Alter HTML used the protocol (http/https) for the site for generated links (rather than keeping the protocol for the link). Thanks to Jacob Gullberg from Sweden for discovering this bug.
734
-
735
- If you experienced update problems due to the update bug, you will probably be left with an incomplete installation. Some of the plugin files are there, but not all. Especially, the main plugin file (webp-express.php) is missing, which means that Wordpress don't "see" the plugin (it is missing from the list). Trying to install WebP Express again will probably not work, because the "webp-express" folder is already there. You will then have to remove the "webp-express" folder in "plugins" manually (via ftp or a plugin, such as File Manager).
736
-
737
- For more info, see the closed issues on the 0.17.2 milestone on the github repository: https://github.com/rosell-dk/webp-express/milestone/29?closed=1
738
-
739
- ## Changes in 0.17.1
740
- *(released: 3 Oct 2019)*
741
-
742
- - Fixed NGINX rules in FAQ (added xdestination for the create webp upon request functionality)
743
- - Fixed issue with Alter HTML. Thanks to @jonathanernst for discovering issue and supplying the patch.
744
- - WebP Express now works on WP Engine. Check out the new "I am on WP Engine" section in the FAQ
745
- - Miscellaneous bug fixes
746
-
747
- For more info, see the closed issues on the 0.17.1 milestone on the github repository: https://github.com/rosell-dk/webp-express/milestone/27?closed=1
748
-
749
- ## Changes in 0.17.0
750
- *(released: 27 sep 2019)*
751
-
752
- * Cwebp conversion method runs on more systems (not subject to open_basedir restrictions and also tries "pure" cwebp command). Thanks to cng11 for reaching out so I spotted this.
753
- * Ewww conversion method no longer does a remote api-key check for each conversion - so it is faster. If an ewww conversions fails due to a non-functional key, the key will not be tried again (until next time the options are saved)
754
- * Updated cwebp binaries to version 1.0.3
755
-
756
- ## Changes in 0.16.0
757
- *(released: 24 sep 2019)*
758
-
759
- - Added option to specify CDN urls in Alter HTML. Thanks to Gunnar Peipman from Estonia for suggesting this.
760
- - Direct Nginx users to Nginx FAQ section on welcome page
761
- - Fixed Bulk Conversion halting due to nonce expiry
762
- - Fixed unexpected output upon reactivation
763
- - Added affiliate link to [Optimole](https://optimole.pxf.io/20b0M) in the "Don't despair - You have options!" message
764
-
765
- ## Changes in 0.15.3
766
- *(released: 19 sep 2019)*
767
-
768
- * Fixed fatal error upon activation for systems which cannot use document root for structuring (rare)
769
-
770
- ## Changes in 0.15.2
771
-
772
- * Fixed the bug when File extension was set to "Set to .webp". It was buggy when file extension contained uppercase letters.
773
-
774
- ## Changes in 0.15.1
775
- *(released: 17 sep 2019)*
776
-
777
- - Bug alert: Added alert about a bug when destination folder is set to "mingled" and File extension is set to "Set to .webp"
778
- - Bugfix: Plugin URL pointed to webpexpress - it should point to parent. This gave trouble with images located in plugins. Thanks to Guillaume Meyer from Switzerland for discovering and reporting.
779
- - Bugfix: Images with uppercase chars in extension did not get Vary:Accept
780
- - Bugfix: There were issues with "All content" and destination:document-root when webp-realizer is activated
781
-
782
-
783
- ## Changes in 0.15.0
784
- *(released: 17 sep 2019)*
785
-
786
- - Provided test-buttons for checking if the redirects works.
787
- - You can now choose which folders WebP Express is active in. Ie "Uploads and Themes".
788
- - You can now choose an alternative file structure for the webps which does not rely on DOCUMENT_ROOT being available.
789
- - WebP Express can now handle when wp-content is symlinked.
790
- - The .htaccess rules are now divided across folders. Some rules are needed where the source files are located, some where the webp files are located.
791
- - Added option to convert only PNG files
792
- - And a couple of bugfixes.
793
-
794
- ## Changes in 0.14.12 - 0.14.15
795
- - Fixed errors with "redirect to conversion script" on systems with symlinked folders
796
- - Fixed errors with "redirect to conversion script" on systems where the filename cannot be passed through an environment variable
797
-
798
- ## Changes in 0.14.5 - 0.14.11
799
- The following security fixes has been applied in 0.14.0 - 0.14.11:
800
- It is urged that you upgrade all of you WebP Express installations!
801
-
802
- - Security fix: Closed a security hole that could be used to view the content of any file on the server (provided that the full path is known or guessed). This is a very serious flaw, which unfortunately has been around for quite a while.
803
- - Security fix: Added capability checks to options page.
804
- - Security fix: Sanitized user input.
805
- - Security fix: Added checks for file paths and directories.
806
- - Security fix: Nonces and capability checks for AJAX calls.
807
-
808
- ## Changes in 0.14.4
809
- - Now bundles with multiple cwebp binaries for linux for systems where 1.0.2 fails.
810
-
811
- ## Changes in 0.14.3
812
- - Fixed filename of supplied cwebp for linux (bug was introduced in 0.14.2)
813
-
814
- ## Changes in 0.14.2
815
- - Fixed problem with older versions of cwebp
816
- - Fixed that images was not deleted
817
- - Fixed cache problem on options page on systems that disables cache busting (it resulted in "SyntaxError: JSON.parse")
818
-
819
- ## Changes in 0.14.1
820
- - A little something
821
-
822
- ## Changes in 0.14.0
823
- - Security fix: Closed a security hole that could be used to view the content of any file on the server (provided that the full path is known or guessed). This is a very serious flaw, which has been around for quite a while. I urge you to upgrade to 0.14.0.
824
- - Added new "encoding" option, which can be set to auto. This can in some cases dramatically reduce the size of the webp. It is supported by all converters except ewww and gd.
825
- - Added new "near-lossless" option (only for cwebp and vips). Using this is a good idea for reducing size of lossless webps with an acceptable loss of quality
826
- - Added new "alpha-quality" option (all converters, except ewww and gd). Using this is a good idea when images with transparency are converted to lossy webp - it has the potential to reduce the size up to 50% (depending on the source material) while keeping an acceptable level of quality
827
- - Added new conversion methods: Vips and GraphicsMagick
828
- - Imagick conversion method now supports webp options (finally cracked it!)
829
- - Using MimeType detection instead of relying on file extensions
830
- - In "test" converter you now change options and also test PNG files
831
- - Added conversion logs
832
- - PNGs are now enabled by default (with the new conversion features especially PNGs are compressed much better)
833
-
834
- For more info, see the closed issues on the 0.14.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/milestone/9?closed=1
835
-
836
- ## Changes in 0.13.2
837
- - Fixed Fatal error on image upload in combination with the [Enable Media Replace](https://de.wordpress.org/plugins/enable-media-replace/) plugin. Thanks to Alexander Graef from Germany for reporting.
838
- - It seems we finally nailed the blank settings page bug. Thanks to all involved, especially Richard Spenceley from the UK
839
-
840
- ## Changes in 0.13.1
841
- - Fixed several bugs.
842
-
843
- ## Changes in 0.13.0
844
- - Bulk Conversion
845
- - Fixed problems with Gd converter and PNG
846
- - Optinally auto convert upon media upload
847
- - Windows fix (thanks, lwxbr!)
848
-
849
- ## Changes in 0.12.0
850
- - Multisite support (!)
851
- - A new operation mode: "No conversion", if you do not want to use WebP Express for converting. Replaces the old "Just redirect" mode
852
- - Added capability testing of .htaccess. The .htaccess rules are now tailored to the capabilities on the system. For example, on some platforms the filename of a requested image is passed to the converter script through the query string, but on platforms that supports passing it through an environment variable, that method is used instead
853
- - Picturefill.js is now optional (alter html, picture tag)
854
- - A great bunch more!
855
-
856
- For more info, see the closed issues on the 0.12.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/milestone/12?closed=1
857
-
858
- ## Changes in 0.11.0
859
- - Alter HTML to point to webp files (choose between picture tags or simply altering all image urls)
860
- - Convert non-existing webp-files upon request (means you can reference the converted webp files before they are actually converted!)
861
-
862
- ## Changes in 0.10.0
863
- - Introduced "Operation modes" in order to keep setting screens simple but still allow tweaking
864
- - WebP Express can now be used in conjunction with Cache Enabler and ShortPixel
865
- - Cache-Control header is now added in *.htaccess*, when redirecting directly to existing webp
866
-
867
- ## Changes in 0.9.0
868
- - Optionally make .htaccess redirect directly to existing webp (improves performance)
869
- - Optionally do not send filename from .htaccess to the PHP in Querystring, but use other means (improves security and reduces risks of problems due to firewall rules)
870
- - Fixed some bugs
871
-
872
- For more info, see the closed issues on the 0.9.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/issues?q=is%3Aclosed+milestone%3A0.9.0
873
 
874
  ## Supporting WebP Express
875
  Bread on the table don't come for free, even though this plugin does, and always will. I enjoy developing this, and supporting you guys, but I kind of need the bread too. Please make it possible for me to continue putting effort into this plugin:
92
  ### Verifying that it works (in "Varied image responses" mode)
93
  1. Make sure at least one of the conversion methods are working. It should have a green checkmark next to it.
94
  2. If you haven't saved yet, click "Save settings". This will put redirection rules into .htaccess files in the relevant directories (typically in uploads, themes and wp-content/webp-express/webp-images, depending on the "Scope" setting)
95
+ 3. I assume that you checked at least one of the two first checkboxes in the .htaccess rules section. Otherwise you aren't using "varied responses", and then the "CDN friendly" mode will be more appropriate.
96
  4. Click the "Live test" buttons to see that the enabled rules actually are working. If they are not, it *could* be that the server needs a little time to recognize the changed rules.
97
 
98
  The live tests are quite thorough and I recommend them over a manual test. However, it doesn't hurt to do a manual inspection too.
677
 
678
  If you wish to affect priorities, it is certainly possible. You can try to argue your case in the forum or you can simply let the money do the talking. By donating as little as a cup of coffee on [ko-fi.com/rosell](https://ko-fi.com/rosell), you can leave a wish. I shall take these wishes into account when prioritizing between new features.
679
 
680
+ ## Changes in 0.18.3
681
+ *(released: 5 Nov 2020)*
682
+ * Bugfix: WebP Express uses live tests to determine the capabilities of the server in respect to .htaccess files (using the htaccess-capability-tester library). The results are used for warnings and also for optimizing the rules in the .htaccess files. However, HTTP Requests can fail due to other reasons than the feature not working (ie timeout). Such failures should lead to an indeterminate result, but it was interpreted as if the feature was not working.
683
+ * The Live test now displays a bit more information if the HTTP request failed.
684
+ * Changed default value for "destination structure" to "Image roots", as "Document root" doesn't work on hosts that have defined DOCUMENT_ROOT in an unusual way.
685
+ * Added possibility to change "%{DOCUMENT_ROOT}" part of RewriteCond by adding a line to wp-config.php. THIS IS A BETA FEATURE AND MIGHT BE REVOKED IF NOBODY ACTUALLY NEEDS IT.
686
+ * Got rid of PHP notice Constant WEBPEXPRESS_MIGRATION_VERSION already defined
687
+ * Fixed donation link. It now points to https://ko-fi.com/rosell again
688
 
689
+ For more info, see the closed issues on the 0.18.3 milestone on the github repository: https://github.com/rosell-dk/webp-express/milestone/34?closed=1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
690
 
691
  ## Supporting WebP Express
692
  Bread on the table don't come for free, even though this plugin does, and always will. I enjoy developing this, and supporting you guys, but I kind of need the bread too. Please make it possible for me to continue putting effort into this plugin:
README.txt CHANGED
@@ -1,10 +1,10 @@
1
  === WebP Express ===
2
  Contributors: rosell.dk
3
- Donate link: https://wordpress.org/plugins/webp-express/#%0Ahow%20do%20i%20buy%20you%20a%20cup%20of%20coffee%3F%0A
4
  Tags: webp, images, performance
5
  Requires at least: 4.0
6
  Tested up to: 5.5
7
- Stable tag: 0.18.2
8
  Requires PHP: 5.6
9
  License: GPLv3
10
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
@@ -91,7 +91,7 @@ If you do not have quality detection working, you can try one of the following:
91
  ### Verifying that it works (in "Varied image responses" mode)
92
  1. Make sure at least one of the conversion methods are working. It should have a green checkmark next to it.
93
  2. If you haven't saved yet, click "Save settings". This will put redirection rules into .htaccess files in the relevant directories (typically in uploads, themes and wp-content/webp-express/webp-images, depending on the "Scope" setting)
94
- 3. I assume that you checked at least one of the checkboxes in the .htaccess rules section - otherwise you might as well change to "CDN friendly" mode. The first
95
  4. Click the "Live test" buttons to see that the enabled rules actually are working. If they are not, it *could* be that the server needs a little time to recognize the changed rules.
96
 
97
  The live tests are quite thorough and I recommend them over a manual test. However, it doesn't hurt to do a manual inspection too.
@@ -136,18 +136,18 @@ Bread on the table don't come for free, even though this plugin does, and always
136
  * [Mathieu Gollain-Dupont](https://www.linkedin.com/in/mathieu-gollain-dupont-9938a4a/)
137
  * Ruben Solvang
138
 
139
- **Persons who contributed with coffee within the last 30 days (updated biweekly) - Thanks! **
140
 
141
- * Katja
142
- * Devashish Datt Mamgain
143
- * RobMoore
144
 
145
  **Persons who contributed with extra generously amounts of coffee / lifetime backing (>30$) - thanks!:**
146
 
147
  * Justin - BigScoots ($105)
148
  * Sebastian ($99)
149
  * Tammy Lee ($90)
150
- * Max Kreminsky ($70)
151
  * Steven Sullivan ($51)
152
 
153
  == Frequently Asked Questions ==
@@ -733,6 +733,21 @@ If you want to make sure that my coffee supplies don't run dry, you can even buy
733
 
734
  == Changelog ==
735
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
736
  = 0.18.1 =
737
  *(released: 24 Sep 2020)*
738
  * Bugfix: Bulk Convert failed to show list on systems that did not have the [utf8-encode()](https://www.php.net/manual/en/function.utf8-encode.php) function.
@@ -1180,6 +1195,9 @@ For older releases, check out changelog.txt
1180
 
1181
  == Upgrade Notice ==
1182
 
 
 
 
1183
  = 0.18.2 =
1184
  * Fixed bug on settings page
1185
 
1
  === WebP Express ===
2
  Contributors: rosell.dk
3
+ Donate link: https://ko-fi.com/rosell
4
  Tags: webp, images, performance
5
  Requires at least: 4.0
6
  Tested up to: 5.5
7
+ Stable tag: 0.18.3
8
  Requires PHP: 5.6
9
  License: GPLv3
10
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
91
  ### Verifying that it works (in "Varied image responses" mode)
92
  1. Make sure at least one of the conversion methods are working. It should have a green checkmark next to it.
93
  2. If you haven't saved yet, click "Save settings". This will put redirection rules into .htaccess files in the relevant directories (typically in uploads, themes and wp-content/webp-express/webp-images, depending on the "Scope" setting)
94
+ 3. I assume that you checked at least one of the two first checkboxes in the .htaccess rules section. Otherwise you aren't using "varied responses", and then the "CDN friendly" mode will be more appropriate.
95
  4. Click the "Live test" buttons to see that the enabled rules actually are working. If they are not, it *could* be that the server needs a little time to recognize the changed rules.
96
 
97
  The live tests are quite thorough and I recommend them over a manual test. However, it doesn't hurt to do a manual inspection too.
136
  * [Mathieu Gollain-Dupont](https://www.linkedin.com/in/mathieu-gollain-dupont-9938a4a/)
137
  * Ruben Solvang
138
 
139
+ **Persons who contributed with ko-fi within the last 30 days (updated biweekly) - Thanks! **
140
 
141
+ * Mark from Portland, OR
142
+ * Pradeep Maheepala from Watford, UK
143
+ * jean
144
 
145
  **Persons who contributed with extra generously amounts of coffee / lifetime backing (>30$) - thanks!:**
146
 
147
  * Justin - BigScoots ($105)
148
  * Sebastian ($99)
149
  * Tammy Lee ($90)
150
+ * Max Kreminsky ($80)
151
  * Steven Sullivan ($51)
152
 
153
  == Frequently Asked Questions ==
733
 
734
  == Changelog ==
735
 
736
+ = 0.18.3 =
737
+ *(released: 5 Nov 2020)*
738
+ * Bugfix: WebP Express uses live tests to determine the capabilities of the server in respect to .htaccess files (using the htaccess-capability-tester library). The results are used for warnings and also for optimizing the rules in the .htaccess files. However, HTTP Requests can fail due to other reasons than the feature not working (ie timeout). Such failures should lead to an indeterminate result, but it was interpreted as if the feature was not working.
739
+ * The Live test now displays a bit more information if the HTTP request failed.
740
+ * Changed default value for "destination structure" to "Image roots", as "Document root" doesn't work on hosts that have defined DOCUMENT_ROOT in an unusual way.
741
+ * Added possibility to change "%{DOCUMENT_ROOT}" part of RewriteCond by adding a line to wp-config.php. THIS IS A BETA FEATURE AND MIGHT BE REVOKED IF NOBODY ACTUALLY NEEDS IT.
742
+ * Got rid of PHP notice Constant WEBPEXPRESS_MIGRATION_VERSION already defined
743
+ * Fixed donation link. It now points to https://ko-fi.com/rosell again
744
+
745
+ For more info, see the closed issues on the [0.18.3 milestone on the github repository](https://github.com/rosell-dk/webp-express/milestone/34?closed=1)
746
+
747
+ = 0.18.2 =
748
+ *(released: 28 Sep 2020)*
749
+ * Bugfix: Fixed error on the settings page on a handful of setups.
750
+
751
  = 0.18.1 =
752
  *(released: 24 Sep 2020)*
753
  * Bugfix: Bulk Convert failed to show list on systems that did not have the [utf8-encode()](https://www.php.net/manual/en/function.utf8-encode.php) function.
1195
 
1196
  == Upgrade Notice ==
1197
 
1198
+ = 0.18.3 =
1199
+ * Minor fixes (see changelog)
1200
+
1201
  = 0.18.2 =
1202
  * Fixed bug on settings page
1203
 
changelog.txt CHANGED
@@ -1,3 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
1
  = 0.18.2 =
2
  *(released: 28 Sep 2020)*
3
  * Bugfix: Fixed error on the settings page on a handful of setups.
1
+ = 0.18.3 =
2
+ *(released: 5 Nov 2020)*
3
+ * Bugfix: WebP Express uses live tests to determine the capabilities of the server in respect to .htaccess files (using the htaccess-capability-tester library). The results are used for warnings and also for optimizing the rules in the .htaccess files. However, HTTP Requests can fail due to other reasons than the feature not working (ie timeout). Such failures should lead to an indeterminate result, but it was interpreted as if the feature was not working.
4
+ * The Live test now displays a bit more information if the HTTP request failed.
5
+ * Changed default value for "destination structure" to "Image roots", as "Document root" doesn't work on hosts that have defined DOCUMENT_ROOT in an unusual way.
6
+ * Added possibility to change "%{DOCUMENT_ROOT}" part of RewriteCond by adding a line to wp-config.php. THIS IS A BETA FEATURE AND MIGHT BE REVOKED IF NOBODY ACTUALLY NEEDS IT.
7
+ * Got rid of PHP notice Constant WEBPEXPRESS_MIGRATION_VERSION already defined
8
+ * Fixed donation link. It now points to https://ko-fi.com/rosell again
9
+
10
+ For more info, see the closed issues on the [0.18.3 milestone on the github repository](https://github.com/rosell-dk/webp-express/milestone/34?closed=1)
11
+
12
  = 0.18.2 =
13
  *(released: 28 Sep 2020)*
14
  * Bugfix: Fixed error on the settings page on a handful of setups.
composer.json CHANGED
@@ -8,7 +8,7 @@
8
  "rosell-dk/webp-convert": "^2.3.1",
9
  "rosell-dk/webp-convert-cloud-service": "^2.0.0",
10
  "rosell-dk/dom-util-for-webp": "^0.4.0",
11
- "rosell-dk/htaccess-capability-tester": "^0.8.0"
12
  },
13
  "require-dev": {
14
  },
8
  "rosell-dk/webp-convert": "^2.3.1",
9
  "rosell-dk/webp-convert-cloud-service": "^2.0.0",
10
  "rosell-dk/dom-util-for-webp": "^0.4.0",
11
+ "rosell-dk/htaccess-capability-tester": "^0.9.0"
12
  },
13
  "require-dev": {
14
  },
composer.lock CHANGED
@@ -4,7 +4,7 @@
4
  "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
5
  "This file is @generated automatically"
6
  ],
7
- "content-hash": "b2a148dedbe8b5edc157f97c824af67f",
8
  "packages": [
9
  {
10
  "name": "composer/installers",
@@ -193,16 +193,16 @@
193
  },
194
  {
195
  "name": "rosell-dk/htaccess-capability-tester",
196
- "version": "0.8",
197
  "source": {
198
  "type": "git",
199
  "url": "https://github.com/rosell-dk/htaccess-capability-tester.git",
200
- "reference": "3556f664c5533643c0cb0beceaf1947abd7aed7a"
201
  },
202
  "dist": {
203
  "type": "zip",
204
- "url": "https://api.github.com/repos/rosell-dk/htaccess-capability-tester/zipball/3556f664c5533643c0cb0beceaf1947abd7aed7a",
205
- "reference": "3556f664c5533643c0cb0beceaf1947abd7aed7a",
206
  "shasum": ""
207
  },
208
  "require": {
@@ -249,7 +249,7 @@
249
  "apache",
250
  "litespeed"
251
  ],
252
- "time": "2020-09-23T10:46:34+00:00"
253
  },
254
  {
255
  "name": "rosell-dk/image-mime-type-guesser",
4
  "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
5
  "This file is @generated automatically"
6
  ],
7
+ "content-hash": "0a5dd30cdf271eb73acaef9d3c0519b2",
8
  "packages": [
9
  {
10
  "name": "composer/installers",
193
  },
194
  {
195
  "name": "rosell-dk/htaccess-capability-tester",
196
+ "version": "0.9",
197
  "source": {
198
  "type": "git",
199
  "url": "https://github.com/rosell-dk/htaccess-capability-tester.git",
200
+ "reference": "2eb2cf38a9f42fc3aa647d6e9c896e124bfebf4c"
201
  },
202
  "dist": {
203
  "type": "zip",
204
+ "url": "https://api.github.com/repos/rosell-dk/htaccess-capability-tester/zipball/2eb2cf38a9f42fc3aa647d6e9c896e124bfebf4c",
205
+ "reference": "2eb2cf38a9f42fc3aa647d6e9c896e124bfebf4c",
206
  "shasum": ""
207
  },
208
  "require": {
249
  "apache",
250
  "litespeed"
251
  ],
252
+ "time": "2020-11-04T10:29:38+00:00"
253
  },
254
  {
255
  "name": "rosell-dk/image-mime-type-guesser",
lib/classes/AdminInit.php CHANGED
@@ -29,8 +29,12 @@ class AdminInit
29
 
30
  public static function runMigrationIfNeeded()
31
  {
32
- // When an update requires a migration, the number should be increased
33
- define('WEBPEXPRESS_MIGRATION_VERSION', '12');
 
 
 
 
34
 
35
  if (WEBPEXPRESS_MIGRATION_VERSION != Option::getOption('webp-express-migration-version', 0)) {
36
  // run migration logic
29
 
30
  public static function runMigrationIfNeeded()
31
  {
32
+ // For reasons I have not been able to unravel, someone reported a notice that WEBPEXPRESS_MIGRATION_VERSION was already defined.
33
+ // So we added this "defined" check. #463
34
+ if (!defined('WEBPEXPRESS_MIGRATION_VERSION')) {
35
+ // When an update requires a migration, the number should be increased
36
+ define('WEBPEXPRESS_MIGRATION_VERSION', '12');
37
+ }
38
 
39
  if (WEBPEXPRESS_MIGRATION_VERSION != Option::getOption('webp-express-migration-version', 0)) {
40
  // run migration logic
lib/classes/Config.php CHANGED
@@ -30,7 +30,7 @@ class Config
30
  'image-types' => 3,
31
  'destination-folder' => 'separate',
32
  'destination-extension' => 'append',
33
- 'destination-structure' => (Paths::canUseDocRootForRelPaths() ? 'doc-root' : 'image-roots'),
34
  'cache-control' => 'no-header', /* can be "no-header", "set" or "custom" */
35
  'cache-control-custom' => 'public, max-age=31536000, stale-while-revalidate=604800, stale-if-error=604800',
36
  'cache-control-max-age' => 'one-week',
30
  'image-types' => 3,
31
  'destination-folder' => 'separate',
32
  'destination-extension' => 'append',
33
+ 'destination-structure' => (PlatformInfo::isNginx() ? 'doc-root' : 'image-roots'),
34
  'cache-control' => 'no-header', /* can be "no-header", "set" or "custom" */
35
  'cache-control-custom' => 'public, max-age=31536000, stale-while-revalidate=604800, stale-if-error=604800',
36
  'cache-control-max-age' => 'one-week',
lib/classes/ConvertHelperIndependent.php CHANGED
@@ -571,7 +571,7 @@ APACHE
571
  $text = preg_replace('#' . preg_quote($_SERVER["DOCUMENT_ROOT"]) . '#', '[doc-root]', $text);
572
 
573
  // TODO: Put version number somewhere else. Ie \WebPExpress\VersionNumber::version
574
- $text = 'WebP Express 0.18.2. ' . $msgTop . ', ' . date("Y-m-d H:i:s") . "\n\r\n\r" . $text;
575
 
576
  $logFile = self::getLogFilename($source, $logDir);
577
 
571
  $text = preg_replace('#' . preg_quote($_SERVER["DOCUMENT_ROOT"]) . '#', '[doc-root]', $text);
572
 
573
  // TODO: Put version number somewhere else. Ie \WebPExpress\VersionNumber::version
574
+ $text = 'WebP Express 0.18.3. ' . $msgTop . ', ' . date("Y-m-d H:i:s") . "\n\r\n\r" . $text;
575
 
576
  $logFile = self::getLogFilename($source, $logDir);
577
 
lib/classes/HTAccess.php CHANGED
@@ -11,6 +11,14 @@ use \WebPExpress\State;
11
  class HTAccess
12
  {
13
 
 
 
 
 
 
 
 
 
14
 
15
  /**
16
  * Must be parsed ie "wp-content", "index", etc. Not real dirs
@@ -160,6 +168,9 @@ class HTAccess
160
 
161
  // Convert to array, because string version has bugs in Wordpress 4.3
162
  $rules = explode("\n", $rules);
 
 
 
163
  $success = insert_with_markers($filename, 'WebP Express', $rules);
164
 
165
  // Revert file or dir permissions
11
  class HTAccess
12
  {
13
 
14
+ public static function inlineInstructions($instructions, $marker)
15
+ {
16
+ if ($marker == 'WebP Express') {
17
+ return [];
18
+ } else {
19
+ return $instructions;
20
+ }
21
+ }
22
 
23
  /**
24
  * Must be parsed ie "wp-content", "index", etc. Not real dirs
168
 
169
  // Convert to array, because string version has bugs in Wordpress 4.3
170
  $rules = explode("\n", $rules);
171
+
172
+ add_filter('insert_with_markers_inline_instructions', array('\WebPExpress\HTAccess', 'inlineInstructions'), 10, 2);
173
+
174
  $success = insert_with_markers($filename, 'WebP Express', $rules);
175
 
176
  // Revert file or dir permissions
lib/classes/HTAccessCapabilityTestRunner.php CHANGED
@@ -27,6 +27,9 @@ class HTAccessCapabilityTestRunner
27
  {
28
  $response = wp_remote_get($url, ['timeout' => 10]);
29
  //echo '<pre>' . print_r($response, true) . '</pre>';
 
 
 
30
  if (wp_remote_retrieve_response_code($response) != '200') {
31
  return false;
32
  }
27
  {
28
  $response = wp_remote_get($url, ['timeout' => 10]);
29
  //echo '<pre>' . print_r($response, true) . '</pre>';
30
+ if (is_wp_error($response)) {
31
+ return null;
32
+ }
33
  if (wp_remote_retrieve_response_code($response) != '200') {
34
  return false;
35
  }
lib/classes/HTAccessRules.php CHANGED
@@ -27,6 +27,7 @@ class HTAccessRules
27
  private static $dirContainsSourceImages;
28
  private static $dirContainsWebPImages;
29
  private static $alterHtmlEnabled;
 
30
 
31
  private static function trueFalseNullString($var)
32
  {
@@ -166,7 +167,9 @@ class HTAccessRules
166
  private static function infoRules()
167
  {
168
 
169
- return "# The rules below is a result of many parameters, including the following:\n" .
 
 
170
  "#\n# WebP Express options:\n" .
171
  "# - Operation mode: " . self::$config['operation-mode'] . "\n" .
172
  "# - Redirection to existing webp: " .
@@ -301,18 +304,18 @@ class HTAccessRules
301
  if (self::$useDocRootForStructuringCacheDir) {
302
  if (self::$config['destination-extension'] == 'append') {
303
  $rules .= " RewriteCond %{REQUEST_FILENAME}.webp -f\n";
304
- //$rules .= " RewriteCond %{DOCUMENT_ROOT}/" . self::$htaccessDirRelToDocRoot . "/$1.$2.webp -f\n";
305
  $rules .= " RewriteRule ^/?(.*)\.(" . self::$fileExt . ")$ $1.$2.webp [NC,T=image/webp,E=EXISTING:1," . (self::$setAddVaryEnvInRedirect ? 'E=ADDVARY:1,' : '') . "L]\n\n";
306
  } else {
307
  // extension: set to webp
308
 
309
- //$rules .= " RewriteCond %{DOCUMENT_ROOT}/" . self::$htaccessDirRelToDocRoot . "/$1.webp -f\n";
310
  //$rules .= " RewriteRule " . $rewriteRuleStart . "\.(" . self::$fileExt . ")$ $1.webp [T=image/webp,E=EXISTING:1," . (self::$setAddVaryEnvInRedirect ? 'E=ADDVARY:1,' : '') . "L]\n\n";
311
 
312
  // Got these new rules here: https://www.digitalocean.com/community/tutorials/how-to-create-and-serve-webp-images-to-speed-up-your-website
313
  // (but are they actually better than the ones we use for append?)
314
  $rules .= " RewriteCond %{REQUEST_URI} (?i)(.*)(" . self::$fileExtIncludingDot . ")$\n";
315
- $rules .= " RewriteCond %{DOCUMENT_ROOT}%1\.webp -f\n";
316
  $rules .= " RewriteRule (?i)(.*)(" . self::$fileExtIncludingDot . ")$ %1\.webp [T=image/webp,E=EXISTING:1," . (self::$setAddVaryEnvInRedirect ? 'E=ADDVARY:1,' : '') . "L]\n\n";
317
 
318
  // Instead of using REQUEST_URI, I can use REQUEST_FILENAME and remove DOCUMENT_ROOT
@@ -352,7 +355,7 @@ class HTAccessRules
352
  $cacheDirRel = Paths::getCacheDirRelToDocRoot() . '/doc-root';
353
 
354
  $rules .= " RewriteCond %{REQUEST_FILENAME} -f\n";
355
- $rules .= " RewriteCond %{DOCUMENT_ROOT}/" . $cacheDirRel . "/" . self::$htaccessDirRelToDocRoot . "/$1.$2.webp -f\n";
356
  $rules .= " RewriteRule ^/?(.+)\.(" . self::$fileExt . ")$ /" . $cacheDirRel . "/" . self::$htaccessDirRelToDocRoot .
357
  "/$1.$2.webp [NC,T=image/webp,E=EXISTING:1," . (self::$setAddVaryEnvInRedirect ? 'E=ADDVARY:1,' : '') . "L]\n\n";
358
 
@@ -838,6 +841,10 @@ class HTAccessRules
838
 
839
  $capTests = self::$config['base-htaccess-on-these-capability-tests'];
840
 
 
 
 
 
841
 
842
  self::$modHeaderDefinitelyUnavailable = ($capTests['modHeaderWorking'] === false);
843
  self::$passThroughHeaderDefinitelyUnavailable = ($capTests['passThroughHeaderWorking'] === false);
27
  private static $dirContainsSourceImages;
28
  private static $dirContainsWebPImages;
29
  private static $alterHtmlEnabled;
30
+ private static $docRootString;
31
 
32
  private static function trueFalseNullString($var)
33
  {
167
  private static function infoRules()
168
  {
169
 
170
+ return "# The rules below have been dynamically created by WebP Express in accordance with the plugin settings\n" .
171
+ "# DO NOT EDIT MANUALLY (unless you are prepared that your changes might be overridden by WebP Express)" . "\n" .
172
+ "# The following parameters have been in play to produce the rules:\n" .
173
  "#\n# WebP Express options:\n" .
174
  "# - Operation mode: " . self::$config['operation-mode'] . "\n" .
175
  "# - Redirection to existing webp: " .
304
  if (self::$useDocRootForStructuringCacheDir) {
305
  if (self::$config['destination-extension'] == 'append') {
306
  $rules .= " RewriteCond %{REQUEST_FILENAME}.webp -f\n";
307
+ //$rules .= " RewriteCond " . self::$docRootString . "/" . self::$htaccessDirRelToDocRoot . "/$1.$2.webp -f\n";
308
  $rules .= " RewriteRule ^/?(.*)\.(" . self::$fileExt . ")$ $1.$2.webp [NC,T=image/webp,E=EXISTING:1," . (self::$setAddVaryEnvInRedirect ? 'E=ADDVARY:1,' : '') . "L]\n\n";
309
  } else {
310
  // extension: set to webp
311
 
312
+ //$rules .= " RewriteCond " . self::$docRootString . "/" . self::$htaccessDirRelToDocRoot . "/$1.webp -f\n";
313
  //$rules .= " RewriteRule " . $rewriteRuleStart . "\.(" . self::$fileExt . ")$ $1.webp [T=image/webp,E=EXISTING:1," . (self::$setAddVaryEnvInRedirect ? 'E=ADDVARY:1,' : '') . "L]\n\n";
314
 
315
  // Got these new rules here: https://www.digitalocean.com/community/tutorials/how-to-create-and-serve-webp-images-to-speed-up-your-website
316
  // (but are they actually better than the ones we use for append?)
317
  $rules .= " RewriteCond %{REQUEST_URI} (?i)(.*)(" . self::$fileExtIncludingDot . ")$\n";
318
+ $rules .= " RewriteCond " . self::$docRootString . "%1\.webp -f\n";
319
  $rules .= " RewriteRule (?i)(.*)(" . self::$fileExtIncludingDot . ")$ %1\.webp [T=image/webp,E=EXISTING:1," . (self::$setAddVaryEnvInRedirect ? 'E=ADDVARY:1,' : '') . "L]\n\n";
320
 
321
  // Instead of using REQUEST_URI, I can use REQUEST_FILENAME and remove DOCUMENT_ROOT
355
  $cacheDirRel = Paths::getCacheDirRelToDocRoot() . '/doc-root';
356
 
357
  $rules .= " RewriteCond %{REQUEST_FILENAME} -f\n";
358
+ $rules .= " RewriteCond " . self::$docRootString . "/" . $cacheDirRel . "/" . self::$htaccessDirRelToDocRoot . "/$1.$2.webp -f\n";
359
  $rules .= " RewriteRule ^/?(.+)\.(" . self::$fileExt . ")$ /" . $cacheDirRel . "/" . self::$htaccessDirRelToDocRoot .
360
  "/$1.$2.webp [NC,T=image/webp,E=EXISTING:1," . (self::$setAddVaryEnvInRedirect ? 'E=ADDVARY:1,' : '') . "L]\n\n";
361
 
841
 
842
  $capTests = self::$config['base-htaccess-on-these-capability-tests'];
843
 
844
+ self::$docRootString = '%{DOCUMENT_ROOT}';
845
+ if (defined('WEBPEXPRESS_DOCUMENT_ROOT_IN_HTACCESS')) {
846
+ self::$docRootString = constant('WEBPEXPRESS_DOCUMENT_ROOT_IN_HTACCESS');
847
+ };
848
 
849
  self::$modHeaderDefinitelyUnavailable = ($capTests['modHeaderWorking'] === false);
850
  self::$passThroughHeaderDefinitelyUnavailable = ($capTests['passThroughHeaderWorking'] === false);
lib/classes/SelfTestHelper.php CHANGED
@@ -203,6 +203,8 @@ class SelfTestHelper
203
  $wpResult = wp_remote_get($requestUrl, $args);
204
  if (is_wp_error($wpResult)) {
205
  $log[] = 'The remote request errored';
 
 
206
  return [false, $log, $results];
207
  }
208
  if (!is_wp_error($wpResult) && !isset($wpResult['headers'])) {
@@ -549,7 +551,8 @@ class SelfTestHelper
549
  $log[] = '- mod_rewrite working?: ' . self::trueFalseNullString(HTAccessCapabilityTestRunner::modRewriteWorking());
550
  $log[] = '- mod_headers loaded?: ' . self::trueFalseNullString(HTAccessCapabilityTestRunner::modHeadersLoaded());
551
  $log[] = '- mod_headers working (header set): ' . self::trueFalseNullString(HTAccessCapabilityTestRunner::modHeaderWorking());
552
- $log[] = '- passing variables from *.htaccess* to PHP script through environment variable working?: ' . self::trueFalseNullString($capTests['passThroughEnvWorking']);
 
553
  $log[] = '- Can run php test file in plugins/webp-express/wod/ ?: ' . self::trueFalseNullString(HTAccessCapabilityTestRunner::canRunTestScriptInWOD());
554
  $log[] = '- Can run php test file in plugins/webp-express/wod2/ ?: ' . self::trueFalseNullString(HTAccessCapabilityTestRunner::canRunTestScriptInWOD2());
555
  $log[] = '- Directives for granting access like its done in wod/.htaccess allowed?: ' . self::trueFalseNullString(HTAccessCapabilityTestRunner::grantAllAllowed());
203
  $wpResult = wp_remote_get($requestUrl, $args);
204
  if (is_wp_error($wpResult)) {
205
  $log[] = 'The remote request errored';
206
+ $log[] = $wpResult->get_error_message();
207
+ //$log[] = print_r($wpResult, true);
208
  return [false, $log, $results];
209
  }
210
  if (!is_wp_error($wpResult) && !isset($wpResult['headers'])) {
551
  $log[] = '- mod_rewrite working?: ' . self::trueFalseNullString(HTAccessCapabilityTestRunner::modRewriteWorking());
552
  $log[] = '- mod_headers loaded?: ' . self::trueFalseNullString(HTAccessCapabilityTestRunner::modHeadersLoaded());
553
  $log[] = '- mod_headers working (header set): ' . self::trueFalseNullString(HTAccessCapabilityTestRunner::modHeaderWorking());
554
+ //$log[] = '- passing variables from *.htaccess* to PHP script through environment variable working?: ' . self::trueFalseNullString($capTests['passThroughEnvWorking']);
555
+ $log[] = '- passing variables from *.htaccess* to PHP script through environment variable working?: ' . self::trueFalseNullString(HTAccessCapabilityTestRunner::passThroughEnvWorking());
556
  $log[] = '- Can run php test file in plugins/webp-express/wod/ ?: ' . self::trueFalseNullString(HTAccessCapabilityTestRunner::canRunTestScriptInWOD());
557
  $log[] = '- Can run php test file in plugins/webp-express/wod2/ ?: ' . self::trueFalseNullString(HTAccessCapabilityTestRunner::canRunTestScriptInWOD2());
558
  $log[] = '- Directives for granting access like its done in wod/.htaccess allowed?: ' . self::trueFalseNullString(HTAccessCapabilityTestRunner::grantAllAllowed());
lib/classes/SelfTestRedirectToExisting.php CHANGED
@@ -59,8 +59,13 @@ class SelfTestRedirectToExisting extends SelfTestRedirectAbstract
59
  $log = array_merge($log, $remoteGetLog);
60
 
61
  if (!$success) {
62
- $log[] = 'The request FAILED';
63
- $log[] = 'The test cannot be completed';
 
 
 
 
 
64
  return [false, $log, $createdTestFiles];
65
  }
66
  //$log[count($log) - 1] .= '. ok!';
59
  $log = array_merge($log, $remoteGetLog);
60
 
61
  if (!$success) {
62
+ $log[] = 'The test cannot be completed, as the HTTP request failed. This does not neccesarily mean that the redirections ' .
63
+ "aren't" . ' working, but it means you will have to check it manually. Check out the FAQ on how to do this. ' .
64
+ 'You might also want to check out why a simple HTTP request could not be issued. WebP Express uses such requests ' .
65
+ 'for detecting system capabilities, which are used when generating .htaccess files. These tests are not essential, but ' .
66
+ 'it would be best to have them working. I can inform that the Wordpress function *wp_remote_get* was used for the HTTP request ' .
67
+ 'and the URL was: ' . $requestUrl;
68
+
69
  return [false, $log, $createdTestFiles];
70
  }
71
  //$log[count($log) - 1] .= '. ok!';
lib/classes/WPHttpRequester.php CHANGED
@@ -20,7 +20,7 @@ class WPHttpRequester implements HttpRequesterInterface
20
  //echo '<pre>' . print_r($response, true) . '</pre>';
21
 
22
  if (is_wp_error($response)) {
23
- return new HttpResponse('0','',[]);
24
  } else {
25
  $body = wp_remote_retrieve_body($response);
26
  $statusCode = wp_remote_retrieve_response_code($response);
20
  //echo '<pre>' . print_r($response, true) . '</pre>';
21
 
22
  if (is_wp_error($response)) {
23
+ return new HttpResponse($response->get_error_message(), '0', []);
24
  } else {
25
  $body = wp_remote_retrieve_body($response);
26
  $statusCode = wp_remote_retrieve_response_code($response);
lib/options/options/general/destination-structure.inc CHANGED
@@ -3,7 +3,7 @@
3
  <th scope="row">Destination structure<?php
4
  echo helpIcon(
5
  '<p>This setting determines how the converted files are structured within the folder that WebP Express ' .
6
- 'uses for storing webp images</p>' .
7
  '<p><span style="text-decoration:underline">"document root"</span><br>' .
8
  'When "document root" is selected, the webp images will be stored in:<br>' .
9
  '<span style="white-space:pre-wrap;font-family:monospace">[cache root]/doc-root/[relative path of source image, from document root].</span><br>' .
@@ -19,13 +19,17 @@
19
  '<span style="white-space:pre-wrap;font-family:monospace"">[cache root]/[image root]/[relative path of source image, from its image root].</span><br>' .
20
  '</p>' .
21
  '<p><span style="text-decoration:underline">Which option is best?</span><br>' .
22
- 'Well, in most cases it does not matter. However, as the "image roots" option is new, I would recommend staying with the ' .
23
- '"document root" setting. On Nginx, I recommend "document root", as it requires fewer rewrite rules.</p>' .
24
- '<p>The "image roots" option was added to make WebP Express work on systems where the document root is set up incorrectly or ' .
25
- 'is outside opendir restriction or an image root is located outside document root. WebP Express automatically detects this and will not allow you to select "document root" in those cases.</p>'
26
  );
27
  ?></th>
28
  <td>
 
 
 
 
 
29
  <select name="destination-structure" id="destination_structure">
30
  <?php
31
  webpexpress_selectBoxOptions($config['destination-structure'], [
3
  <th scope="row">Destination structure<?php
4
  echo helpIcon(
5
  '<p>This setting determines how the converted files are structured within the folder that WebP Express ' .
6
+ 'uses for storing webp images (from here on called "the cache root")</p>' .
7
  '<p><span style="text-decoration:underline">"document root"</span><br>' .
8
  'When "document root" is selected, the webp images will be stored in:<br>' .
9
  '<span style="white-space:pre-wrap;font-family:monospace">[cache root]/doc-root/[relative path of source image, from document root].</span><br>' .
19
  '<span style="white-space:pre-wrap;font-family:monospace"">[cache root]/[image root]/[relative path of source image, from its image root].</span><br>' .
20
  '</p>' .
21
  '<p><span style="text-decoration:underline">Which option is best?</span><br>' .
22
+ 'Well, in most cases it does not matter. However, there are hosts out there that have set the document root up incorrectly, ' .
23
+ 'so I would generally recommend "Image roots". ' .
24
+ 'On Nginx, I however recommend "Document root", as it requires fewer rewrite rules.</p>'
 
25
  );
26
  ?></th>
27
  <td>
28
+ <!--
29
+ The "image roots" option was added to make WebP Express work on systems where the document root is set up incorrectly or
30
+ is outside opendir restriction or an image root is located outside document root.
31
+ WebP Express automatically detects this and will not allow you to select "document root" in those cases.
32
+ -->
33
  <select name="destination-structure" id="destination_structure">
34
  <?php
35
  webpexpress_selectBoxOptions($config['destination-structure'], [
vendor/composer/installed.json CHANGED
@@ -190,17 +190,17 @@
190
  },
191
  {
192
  "name": "rosell-dk/htaccess-capability-tester",
193
- "version": "0.8",
194
- "version_normalized": "0.8.0.0",
195
  "source": {
196
  "type": "git",
197
  "url": "https://github.com/rosell-dk/htaccess-capability-tester.git",
198
- "reference": "3556f664c5533643c0cb0beceaf1947abd7aed7a"
199
  },
200
  "dist": {
201
  "type": "zip",
202
- "url": "https://api.github.com/repos/rosell-dk/htaccess-capability-tester/zipball/3556f664c5533643c0cb0beceaf1947abd7aed7a",
203
- "reference": "3556f664c5533643c0cb0beceaf1947abd7aed7a",
204
  "shasum": ""
205
  },
206
  "require": {
@@ -214,7 +214,7 @@
214
  "suggest": {
215
  "php-stan/php-stan": "Suggested for dev, in order to analyse code before committing"
216
  },
217
- "time": "2020-09-23T10:46:34+00:00",
218
  "type": "library",
219
  "extra": {
220
  "scripts-descriptions": {
190
  },
191
  {
192
  "name": "rosell-dk/htaccess-capability-tester",
193
+ "version": "0.9",
194
+ "version_normalized": "0.9.0.0",
195
  "source": {
196
  "type": "git",
197
  "url": "https://github.com/rosell-dk/htaccess-capability-tester.git",
198
+ "reference": "2eb2cf38a9f42fc3aa647d6e9c896e124bfebf4c"
199
  },
200
  "dist": {
201
  "type": "zip",
202
+ "url": "https://api.github.com/repos/rosell-dk/htaccess-capability-tester/zipball/2eb2cf38a9f42fc3aa647d6e9c896e124bfebf4c",
203
+ "reference": "2eb2cf38a9f42fc3aa647d6e9c896e124bfebf4c",
204
  "shasum": ""
205
  },
206
  "require": {
214
  "suggest": {
215
  "php-stan/php-stan": "Suggested for dev, in order to analyse code before committing"
216
  },
217
+ "time": "2020-11-04T10:29:38+00:00",
218
  "type": "library",
219
  "extra": {
220
  "scripts-descriptions": {
vendor/rosell-dk/htaccess-capability-tester/.github/FUNDING.yml CHANGED
@@ -1,2 +1,2 @@
 
1
  ko_fi: rosell
2
- patreon: rosell
1
+ github: rosell-dk
2
  ko_fi: rosell
 
vendor/rosell-dk/htaccess-capability-tester/README.md CHANGED
@@ -8,18 +8,18 @@
8
  [![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](https://github.com/rosell-dk/htaccess-capability-tester/blob/master/LICENSE)
9
 
10
 
11
- Detect `.htaccess` capabilities through live tests.
12
 
13
- There are cases where the only way to to learn if a given `.htaccess` capability is enabled / supported on a system is by examining it "from the outside" through a HTTP request. This library is build to handle such testing easily.
14
 
15
  This is what happens behind the scenes:
16
- 1. Some test files for a given test are put on the server (at least an `.htaccess` file)
17
  2. The test is triggered by doing a HTTP request
18
  3. The response is interpreted
19
 
20
  ## Usage
21
 
22
- To use the library, you must provide a path to where the test files are going to be put and an URL that they can be reached. Besides that, you just need to pick one of the tests that you want to run.
23
 
24
  ```php
25
  require 'vendor/autoload.php';
@@ -28,7 +28,7 @@ use HtaccessCapabilityTester\HtaccessCapabilityTester;
28
  $hct = new HtaccessCapabilityTester($baseDir, $baseUrl);
29
 
30
  if ($hct->moduleLoaded('headers')) {
31
- // mod_headers has been tested functional in a real .htaccess
32
  }
33
  if ($hct->rewriteWorks()) {
34
  // rewriting works
@@ -40,94 +40,7 @@ if ($hct->htaccessEnabled() === false) {
40
 
41
  // A bunch of other tests are available - see API
42
  ```
43
- While having a reliable `moduleLoaded` method is a great improvement over current state of affairs, beware that it is possible that the server has ie `mod_rewrite` enabled, but at the same time has disallowed using ie the "RewriteRule" directive in `.htaccess` files. This is why the library has the `rewriteWorks()` method and similar methods for testing various capabilites fully. Providing tests for all kinds of functionality, would however be too much for any library. Instead this library makes it a breeze to define a custom test and run it through the `customTest($def)` method.
44
-
45
-
46
- ## Running your own custom tests using the *customTest* method
47
-
48
- A typical test s mentioned, a test has three phases:
49
- 1. Writing the test files to the directory in question
50
- 2. Doing a request (in advanced cases, more)
51
- 3. Interpreting the request
52
-
53
- So, in order for `customTest()`, it needs to know. 1) What files are needed? 2) Which file should be requested? 3) How should the response be interpreted?
54
-
55
- Here is a definition which can be used for implementing the `headerSetWorks` functionality yourself. It's in YAML because it is more readable like this.
56
-
57
- <details><summary><u>Click here to see the PHP example</u></summary>
58
- <p><br>
59
- <b>PHP example</b>
60
-
61
- ```php
62
- <?php
63
- require 'vendor/autoload.php';
64
- use HtaccessCapabilityTester\HtaccessCapabilityTester;
65
-
66
- $hct = new HtaccessCapabilityTester($baseDir, $baseUrl);
67
-
68
- $htaccessFile = <<<'EOD'
69
- <IfModule mod_headers.c>
70
- Header set X-Response-Header-Test: test
71
- </IfModule>
72
- EOD;
73
-
74
- $test = [
75
- 'subdir' => 'header-set',
76
- 'files' => [
77
- ['.htaccess', $htaccessFile],
78
- ['request-me.txt', "hi"],
79
- ],
80
- 'request' => 'request-me.txt',
81
- 'interpretation' => [
82
- ['success', 'headers', 'contains-key-value', 'X-Response-Header-Test', 'test'],
83
-
84
- // the next three mappings are actually not necessary, as customTest() does standard
85
- // error handling automatically (can be turned off)
86
- ['failure', 'status-code', 'equals', '500'],
87
- ['inconclusive', 'status-code', 'equals', '403'],
88
- ['inconclusive', 'status-code', 'equals', '404'],
89
- ]
90
- ];
91
-
92
- if ($hct->customTest($test)) {
93
- // setting a header in the .htaccess works!
94
- }
95
- ```
96
-
97
- </p>
98
- </details>
99
-
100
- ```yaml
101
- subdir: header-set
102
- files:
103
- - filename: '.htaccess'
104
- content: |
105
- <IfModule mod_headers.c>
106
- Header set X-Response-Header-Test: test
107
- </IfModule>
108
- - filename: 'request-me.txt'
109
- content: 'hi'
110
-
111
- request:
112
- url: 'request-me.txt'
113
-
114
- interpretation:
115
- - [success, headers, contains-key-value, 'X-Response-Header-Test', 'test']
116
- - [failure, status-code, equals, '500'] # actually not needed (part of standard error handling)
117
- - [inconclusive, status-code, equals, '403'] # actually not needed (part of standard error handling)
118
- - [inconclusive, status-code, equals, '404'] # actually not needed (part of standard error handling)
119
- - [failure]
120
- ```
121
-
122
- In fact, this is more or less how this library implements it.
123
-
124
- The test definition has the following sub-definitions:
125
- - *subdir*: Defines which subdir the test files should reside in
126
- - *files*: Defines the files for the test (filename and content)
127
- - *request*: Defines which file that should be requested
128
- - *interpretation*: Defines how to interprete the response. It consists of a list of mappings is read from the top until one of the conditions is met. The first line for example translates to "Map to success if the body of the response equals '1'". If none of the conditions are met, the result is automatically mapped to 'inconclusive'.
129
-
130
- For more info, look in the API (below). For real examples, check out the classes in the "Testers" dir - most of them are defined in this "language"
131
 
132
  ## API overview
133
 
@@ -136,9 +49,12 @@ For more info, look in the API (below). For real examples, check out the classes
136
  All the test methods returns a test result, which is *true* for success, *false* for failure or *null* for inconclusive.
137
 
138
  The tests have the following in common:
139
- - If the server has been set up to ignore `.htaccess` files, the result will be *failure*.
140
  - If the server has been set up to disallow the directive being tested (AllowOverride), the result is *failure* (both when configured to ignore and when configured to go fatal)
141
  - A *403 Forbidden* results in *inconclusive*. Why? Because it could be that the server has been set up to forbid access to files matching a pattern that our test file unluckily matches. In most cases, this is unlikely, as most tests requests files with harmless-looking file extensions (often a "request-me.txt"). A few of the tests however requests a "test.php", which is more likely to be denied.
 
 
 
142
 
143
  Most tests are implemented as a definition such as the one accepted in *customTest()*. This means that if you want one of the tests provided by this library to work slightly differently, you can easily grab the code in the corresponding class in the *Testers* directory, make your modification and call *customTest()*.
144
 
@@ -343,12 +259,12 @@ interpretation:
343
 
344
  <details><summary><b>htaccessEnabled()</b></summary>
345
  <p><br>
346
- Apache can be configured to ignore `.htaccess` files altogether. This method tests if the `.htaccess` file is processed at all
347
 
348
  The method works by trying out a series of subtests until a conclusion is reached. It will never come out inconclusive.
349
 
350
  How does it work?
351
- - The first strategy is testing a series of features, such as `rewriteWorks()`. If any of them works, well, then the `.htaccess` must have been processed.
352
  - Secondly, the `serverSignatureWorks()` is tested. The "ServerSignature" directive is special because it is in core and cannot be disabled with AllowOverride. If this test comes out as a failure, it is so *highly likely* that the .htaccess has not been processed, that we conclude that it has not.
353
  - Lastly, if all other methods failed, we try calling `crashTest()` on an .htaccess file that we on purpose put syntax errors in. If it crashes, the .htaccess file must have been proccessed. If it does not crash, it has not. This last method is bulletproof - so why not do it first? Because it might generate an entry in the error log.
354
 
@@ -688,10 +604,11 @@ This allows you to use another object for lining up the test files than the stan
688
  </details>
689
 
690
  ## Stable API?
691
- The 0.8 release is just about right. I do not expect any changes in the part of the API that is mentioned above. So, if you stick to that, it should still work, when the 1.0 release comes.
692
 
693
- Changes in the new 0.8 release:
694
- - HttpResponse now takes a map of headers rather than a numeric array. If you have implemented your own HttpRequester rather than using the default, you need to update it.
 
695
 
696
  Expected changes in the 1.0 release:
697
  - TestResult class might be disposed off so the "internal" Tester classes also returns bool|null.
8
  [![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](https://github.com/rosell-dk/htaccess-capability-tester/blob/master/LICENSE)
9
 
10
 
11
+ Detect *.htaccess* capabilities through live tests.
12
 
13
+ There are cases where the only way to to learn if a given *.htaccess* capability is enabled / supported on a system is by examining it "from the outside" through a HTTP request. This library is build to handle such testing easily.
14
 
15
  This is what happens behind the scenes:
16
+ 1. Some test files for a given test are put on the server (at least an *.htaccess* file)
17
  2. The test is triggered by doing a HTTP request
18
  3. The response is interpreted
19
 
20
  ## Usage
21
 
22
+ To use the library, you must provide a path to where the test files are going to be put and the corresponding URL that they can be reached. Besides that, you just need to pick one of the tests that you want to run.
23
 
24
  ```php
25
  require 'vendor/autoload.php';
28
  $hct = new HtaccessCapabilityTester($baseDir, $baseUrl);
29
 
30
  if ($hct->moduleLoaded('headers')) {
31
+ // mod_headers is loaded (tested in a real .htaccess by using the "IfModule" directive)
32
  }
33
  if ($hct->rewriteWorks()) {
34
  // rewriting works
40
 
41
  // A bunch of other tests are available - see API
42
  ```
43
+ While having a reliable *moduleLoaded()* method is a great improvement over current state of affairs, beware that it is possible that the server has ie *mod_rewrite* enabled, but at the same time has disallowed using ie the "RewriteRule" directive in *.htaccess* files. This is why the library has the *rewriteWorks()* method and similar methods for testing various capabilites fully (check the API overview below). Providing tests for all kinds of functionality, would however be too much for any library. Instead this library makes it a breeze to define a custom test and run it through the *customTest($def)* method. To learn more, check out the [Running your own custom tests](https://github.com/rosell-dk/htaccess-capability-tester/blob/master/docs/Running%20your%20own%20custom%20tests.md) document.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
 
45
  ## API overview
46
 
49
  All the test methods returns a test result, which is *true* for success, *false* for failure or *null* for inconclusive.
50
 
51
  The tests have the following in common:
52
+ - If the server has been set up to ignore *.htaccess* files entirely, the result will be *failure*.
53
  - If the server has been set up to disallow the directive being tested (AllowOverride), the result is *failure* (both when configured to ignore and when configured to go fatal)
54
  - A *403 Forbidden* results in *inconclusive*. Why? Because it could be that the server has been set up to forbid access to files matching a pattern that our test file unluckily matches. In most cases, this is unlikely, as most tests requests files with harmless-looking file extensions (often a "request-me.txt"). A few of the tests however requests a "test.php", which is more likely to be denied.
55
+ - A *404 Not Found* results in *inconclusive*
56
+ - If the request fails completely (ie timeout), the result is *inconclusive*
57
+
58
 
59
  Most tests are implemented as a definition such as the one accepted in *customTest()*. This means that if you want one of the tests provided by this library to work slightly differently, you can easily grab the code in the corresponding class in the *Testers* directory, make your modification and call *customTest()*.
60
 
259
 
260
  <details><summary><b>htaccessEnabled()</b></summary>
261
  <p><br>
262
+ Apache can be configured to ignore *.htaccess* files altogether. This method tests if the *.htaccess* file is processed at all
263
 
264
  The method works by trying out a series of subtests until a conclusion is reached. It will never come out inconclusive.
265
 
266
  How does it work?
267
+ - The first strategy is testing a series of features, such as `rewriteWorks()`. If any of them works, well, then the *.htaccess* must have been processed.
268
  - Secondly, the `serverSignatureWorks()` is tested. The "ServerSignature" directive is special because it is in core and cannot be disabled with AllowOverride. If this test comes out as a failure, it is so *highly likely* that the .htaccess has not been processed, that we conclude that it has not.
269
  - Lastly, if all other methods failed, we try calling `crashTest()` on an .htaccess file that we on purpose put syntax errors in. If it crashes, the .htaccess file must have been proccessed. If it does not crash, it has not. This last method is bulletproof - so why not do it first? Because it might generate an entry in the error log.
270
 
604
  </details>
605
 
606
  ## Stable API?
607
+ The 0.9 release is just about right. I do not expect any changes in the part of the API that is mentioned above. So, if you stick to that, it should still work, when the 1.0 release comes.
608
 
609
+ Changes in the new 0.9 release:
610
+ - Request failures (such as timeout) results in *inconclusive*.
611
+ - If you have implemented your own HttpRequester rather than using the default, you need to update it. It must now return status code "0" if the request failed (ie timeout)
612
 
613
  Expected changes in the 1.0 release:
614
  - TestResult class might be disposed off so the "internal" Tester classes also returns bool|null.
vendor/rosell-dk/htaccess-capability-tester/docs/Running your own custom tests.md ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Running your own custom tests using the *customTest* method
2
+
3
+ A typical test s mentioned, a test has three phases:
4
+ 1. Writing the test files to the directory in question
5
+ 2. Doing a request (in advanced cases, more)
6
+ 3. Interpreting the request
7
+
8
+ So, in order for *customTest()*, it needs to know. 1) What files are needed? 2) Which file should be requested? 3) How should the response be interpreted?
9
+
10
+ Here is a definition which can be used for implementing the *headerSetWorks()* functionality yourself. It's in YAML because it is more readable like this.
11
+
12
+ <details><summary><u>Click here to see the PHP example</u></summary>
13
+ <p><br>
14
+ <b>PHP example</b>
15
+
16
+ ```php
17
+ <?php
18
+ require 'vendor/autoload.php';
19
+ use HtaccessCapabilityTester\HtaccessCapabilityTester;
20
+
21
+ $hct = new HtaccessCapabilityTester($baseDir, $baseUrl);
22
+
23
+ $htaccessFile = <<<'EOD'
24
+ <IfModule mod_headers.c>
25
+ Header set X-Response-Header-Test: test
26
+ </IfModule>
27
+ EOD;
28
+
29
+ $test = [
30
+ 'subdir' => 'header-set',
31
+ 'files' => [
32
+ ['.htaccess', $htaccessFile],
33
+ ['request-me.txt', "hi"],
34
+ ],
35
+ 'request' => 'request-me.txt',
36
+ 'interpretation' => [
37
+ ['success', 'headers', 'contains-key-value', 'X-Response-Header-Test', 'test'],
38
+
39
+ // the next three mappings are actually not necessary, as customTest() does standard
40
+ // error handling automatically (can be turned off)
41
+ ['failure', 'status-code', 'equals', '500'],
42
+ ['inconclusive', 'status-code', 'equals', '403'],
43
+ ['inconclusive', 'status-code', 'equals', '404'],
44
+ ]
45
+ ];
46
+
47
+ if ($hct->customTest($test)) {
48
+ // setting a header in the .htaccess works!
49
+ }
50
+ ```
51
+
52
+ </p>
53
+ </details>
54
+
55
+ ```yaml
56
+ subdir: header-set
57
+ files:
58
+ - filename: '.htaccess'
59
+ content: |
60
+ <IfModule mod_headers.c>
61
+ Header set X-Response-Header-Test: test
62
+ </IfModule>
63
+ - filename: 'request-me.txt'
64
+ content: 'hi'
65
+
66
+ request:
67
+ url: 'request-me.txt'
68
+
69
+ interpretation:
70
+ - [success, headers, contains-key-value, 'X-Response-Header-Test', 'test']
71
+ - [failure, status-code, equals, '500'] # actually not needed (part of standard error handling)
72
+ - [inconclusive, status-code, equals, '403'] # actually not needed (part of standard error handling)
73
+ - [inconclusive, status-code, equals, '404'] # actually not needed (part of standard error handling)
74
+ - [failure]
75
+ ```
76
+
77
+ In fact, this is more or less how this library implements it.
78
+
79
+ The test definition has the following sub-definitions:
80
+ - *subdir*: Defines which subdir the test files should reside in
81
+ - *files*: Defines the files for the test (filename and content)
82
+ - *request*: Defines which file that should be requested
83
+ - *interpretation*: Defines how to interprete the response. It consists of a list of mappings is read from the top until one of the conditions is met. The first line for example translates to "Map to success if the body of the response equals '1'". If none of the conditions are met, the result is automatically mapped to 'inconclusive'.
84
+
85
+ For more info, look in the API (below). For real examples, check out the classes in the "Testers" dir - most of them are defined in this "language"
vendor/rosell-dk/htaccess-capability-tester/src/HttpRequesterInterface.php CHANGED
@@ -7,7 +7,9 @@ interface HttpRequesterInterface
7
  /**
8
  * Make a HTTP request to a URL.
9
  *
10
- * @return HttpResponse A HttpResponse object, which simply contains body and status code.
 
 
11
  */
12
  public function makeHttpRequest($url);
13
  }
7
  /**
8
  * Make a HTTP request to a URL.
9
  *
10
+ * @return HttpResponse A HttpResponse object, which simply contains body, status code and response headers.
11
+ * In case the request itself fails, the status code is "0" and the body should contain
12
+ * error description (if available)
13
  */
14
  public function makeHttpRequest($url);
15
  }
vendor/rosell-dk/htaccess-capability-tester/src/HttpResponse.php CHANGED
@@ -72,5 +72,4 @@ class HttpResponse
72
  }
73
  return false;
74
  }
75
-
76
  }
72
  }
73
  return false;
74
  }
 
75
  }
vendor/rosell-dk/htaccess-capability-tester/src/SimpleHttpRequester.php CHANGED
@@ -9,15 +9,17 @@ class SimpleHttpRequester implements HttpRequesterInterface
9
  *
10
  * @param string $url The URL to make the HTTP request to
11
  *
12
- * @return HttpResponse A HttpResponse object, which simply contains body, status code
13
- * and response headers
 
14
  */
15
  public function makeHttpRequest($url)
16
  {
17
  // PS: We suppress the E_WARNING level error generated on failure
18
  $body = @file_get_contents($url);
19
  if ($body === false) {
20
- $body = '';
 
21
  }
22
 
23
  // $http_response_header materializes out of thin air when file_get_contents() is called
9
  *
10
  * @param string $url The URL to make the HTTP request to
11
  *
12
+ * @return HttpResponse A HttpResponse object, which simply contains body, status code and response headers.
13
+ * In case the request itself fails, the status code is "0" and the body should contain
14
+ * error description (if available)
15
  */
16
  public function makeHttpRequest($url)
17
  {
18
  // PS: We suppress the E_WARNING level error generated on failure
19
  $body = @file_get_contents($url);
20
  if ($body === false) {
21
+ //$body = '';
22
+ return new HttpResponse('The following request failed: file_get_contents(' . $url . ')', '0', []);
23
  }
24
 
25
  // $http_response_header materializes out of thin air when file_get_contents() is called
vendor/rosell-dk/htaccess-capability-tester/src/Testers/CrashTester.php CHANGED
@@ -43,7 +43,7 @@ class CrashTester extends CustomTester
43
  ],
44
  'request' => [
45
  'url' => 'request-me.txt',
46
- 'bypass-standard-error-handling' => ['all']
47
  ],
48
  'interpretation' => [
49
  ['success', 'status-code', 'not-equals', '500'],
@@ -58,7 +58,7 @@ class CrashTester extends CustomTester
58
  ],
59
  'request' => [
60
  'url' => 'request-me.txt',
61
- 'bypass-standard-error-handling' => ['all']
62
  ],
63
  'interpretation' => [
64
  // The suspect crashed. But if the innocent crashes too, we cannot judge
43
  ],
44
  'request' => [
45
  'url' => 'request-me.txt',
46
+ 'bypass-standard-error-handling' => ['403', '404', '500']
47
  ],
48
  'interpretation' => [
49
  ['success', 'status-code', 'not-equals', '500'],
58
  ],
59
  'request' => [
60
  'url' => 'request-me.txt',
61
+ 'bypass-standard-error-handling' => ['403', '404', '500']
62
  ],
63
  'interpretation' => [
64
  // The suspect crashed. But if the innocent crashes too, we cannot judge
vendor/rosell-dk/htaccess-capability-tester/src/Testers/CustomTester.php CHANGED
@@ -88,6 +88,8 @@ class CustomTester extends AbstractTester
88
  private function standardErrorHandling($response)
89
  {
90
  switch ($response->statusCode) {
 
 
91
  case '403':
92
  return new TestResult(null, '403 Forbidden');
93
  case '404':
88
  private function standardErrorHandling($response)
89
  {
90
  switch ($response->statusCode) {
91
+ case '0':
92
+ return new TestResult(null, $response->body);
93
  case '403':
94
  return new TestResult(null, '403 Forbidden');
95
  case '404':
vendor/rosell-dk/htaccess-capability-tester/src/Testers/Helpers/ResponseInterpreter.php CHANGED
@@ -97,7 +97,6 @@ class ResponseInterpreter
97
  return (strpos($val, $arg1) === 0);
98
  }
99
  return false;
100
-
101
  }
102
 
103
 
97
  return (strpos($val, $arg1) === 0);
98
  }
99
  return false;
 
100
  }
101
 
102
 
vendor/rosell-dk/htaccess-capability-tester/src/Testers/HtaccessEnabledTester.php CHANGED
@@ -86,11 +86,11 @@ class HtaccessEnabledTester extends AbstractTester
86
  // (we do this lastly because it may generate an entry in the error log)
87
  $crashTestResult = $hct->crashTest('aoeu', 'htaccess-enabled-malformed-htaccess');
88
  if (is_null($crashTestResult)) {
89
- // It did crash. But so did a request to an innocent text file in a directory
90
- // without a .htaccess file in it. Something is making all requests fail and
91
- // we cannot judge.
92
  $status = null;
93
- $info = 'all requests results in 500 Internal Server Error';
94
  } elseif ($crashTestResult === false) {
95
  // It crashed, - which means .htaccess is processed!
96
  $status = true;
86
  // (we do this lastly because it may generate an entry in the error log)
87
  $crashTestResult = $hct->crashTest('aoeu', 'htaccess-enabled-malformed-htaccess');
88
  if (is_null($crashTestResult)) {
89
+ // Two scenarios:
90
+ // 1: All requests fails (without response code)
91
+ // 2: The crash test could not figure it out (ie if even innocent requests crashes)
92
  $status = null;
93
+ $info = 'all requests fails (even innocent ones)';
94
  } elseif ($crashTestResult === false) {
95
  // It crashed, - which means .htaccess is processed!
96
  $status = true;
vendor/rosell-dk/htaccess-capability-tester/src/Testers/InnocentRequestTester.php CHANGED
@@ -27,6 +27,7 @@ class InnocentRequestTester extends CustomTester
27
  ],
28
  'interpretation' => [
29
  ['success', 'status-code', 'equals', '200'],
 
30
  ['inconclusive', 'status-code', 'equals', '403'],
31
  ['inconclusive', 'status-code', 'equals', '404'],
32
  ['failure'],
27
  ],
28
  'interpretation' => [
29
  ['success', 'status-code', 'equals', '200'],
30
+ ['inconclusive', 'status-code', 'equals', '0'],
31
  ['inconclusive', 'status-code', 'equals', '403'],
32
  ['inconclusive', 'status-code', 'equals', '404'],
33
  ['failure'],
vendor/rosell-dk/htaccess-capability-tester/src/Testers/ModuleLoadedTester.php CHANGED
@@ -355,7 +355,7 @@ EOD;
355
  return new TestResult(false, '.htaccess files are ignored');
356
  } elseif (is_null($htaccessEnabledTest)) {
357
  // We happen to know that if that test cannot establish anything,
358
- // then none of the usual weapons works - we can surrender
359
  return new TestResult(null, 'no methods available - we surrender early');
360
  }
361
 
355
  return new TestResult(false, '.htaccess files are ignored');
356
  } elseif (is_null($htaccessEnabledTest)) {
357
  // We happen to know that if that test cannot establish anything,
358
+ // then none of the usual weapons works - we can surrender right away
359
  return new TestResult(null, 'no methods available - we surrender early');
360
  }
361
 
vendor/rosell-dk/htaccess-capability-tester/tests/FakeServer.php CHANGED
@@ -36,6 +36,9 @@ class FakeServer implements TestFilesLineUpperInterface, HttpRequesterInterface
36
  /** @var bool Returns the php text file rather than "Sorry, this server cannot process PHP!" */
37
  private $handlePHPasText = false;
38
 
 
 
 
39
  /** @var array Predefined responses for certain urls */
40
  private $responses;
41
 
@@ -59,6 +62,10 @@ class FakeServer implements TestFilesLineUpperInterface, HttpRequesterInterface
59
  $statusCode = '200';
60
  $headers = [];
61
 
 
 
 
 
62
  //echo 'Fakeserver request:' . $url . "\n";
63
  if (isset($this->responses[$url])) {
64
  //echo 'predefined: ' . $url . "\n";
@@ -131,6 +138,10 @@ class FakeServer implements TestFilesLineUpperInterface, HttpRequesterInterface
131
  $this->crashAll = true;
132
  }
133
 
 
 
 
 
134
 
135
  public function handlePHPasText()
136
  {
36
  /** @var bool Returns the php text file rather than "Sorry, this server cannot process PHP!" */
37
  private $handlePHPasText = false;
38
 
39
+ /** @var bool If all requests fail (without response code) */
40
+ private $failAll = false;
41
+
42
  /** @var array Predefined responses for certain urls */
43
  private $responses;
44
 
62
  $statusCode = '200';
63
  $headers = [];
64
 
65
+ if ($this->failAll) {
66
+ return new HttpResponse('', '0', []);
67
+ }
68
+
69
  //echo 'Fakeserver request:' . $url . "\n";
70
  if (isset($this->responses[$url])) {
71
  //echo 'predefined: ' . $url . "\n";
138
  $this->crashAll = true;
139
  }
140
 
141
+ public function failAllRequests()
142
+ {
143
+ $this->failAll = true;
144
+ }
145
 
146
  public function handlePHPasText()
147
  {
vendor/rosell-dk/htaccess-capability-tester/tests/Testers/ContentDigestTesterTest.php CHANGED
@@ -124,4 +124,12 @@ class ContentDigestTesterTest extends BasisTestCase
124
  $this->assertSuccess($testResult);
125
  }
126
 
 
 
 
 
 
 
 
 
127
  }
124
  $this->assertSuccess($testResult);
125
  }
126
 
127
+ public function testRequestFailure()
128
+ {
129
+ $fakeServer = new FakeServer();
130
+ $fakeServer->failAllRequests();
131
+ $testResult = $fakeServer->runTester(new ContentDigestTester());
132
+ $this->assertInconclusive($testResult);
133
+
134
+ }
135
  }
vendor/rosell-dk/htaccess-capability-tester/tests/Testers/CrashTesterTest.php CHANGED
@@ -103,4 +103,12 @@ class CrashTesterTest extends BasisTestCase
103
  $this->assertFailure($testResult);
104
  }
105
 
 
 
 
 
 
 
 
 
106
  }
103
  $this->assertFailure($testResult);
104
  }
105
 
106
+ public function testRequestFailure()
107
+ {
108
+ $fakeServer = new FakeServer();
109
+ $fakeServer->failAllRequests();
110
+ $testResult = $fakeServer->runTester(new CrashTester('aoeu', 'test'));
111
+ $this->assertInconclusive($testResult);
112
+ }
113
+
114
  }
vendor/rosell-dk/htaccess-capability-tester/tests/Testers/HtaccessEnabledTesterTest.php CHANGED
@@ -113,4 +113,12 @@ class HtaccessEnabledTesterTest extends BasisTestCase
113
  $this->assertInconclusive($testResult);
114
  }
115
 
 
 
 
 
 
 
 
 
116
  }
113
  $this->assertInconclusive($testResult);
114
  }
115
 
116
+ public function testRequestFailure()
117
+ {
118
+ $fakeServer = new FakeServer();
119
+ $fakeServer->failAllRequests();
120
+ $testResult = $fakeServer->runTester(new HtaccessEnabledTester());
121
+ $this->assertInconclusive($testResult);
122
+ }
123
+
124
  }
vendor/rosell-dk/htaccess-capability-tester/tests/Testers/ModuleLoadedTesterTest.php CHANGED
@@ -246,4 +246,12 @@ class ModuleLoadedTesterTest extends BasisTestCase
246
  $this->assertFailure($testResult);
247
  }
248
 
 
 
 
 
 
 
 
 
249
  }
246
  $this->assertFailure($testResult);
247
  }
248
 
249
+ public function testRequestFailure()
250
+ {
251
+ $fakeServer = new FakeServer();
252
+ $fakeServer->failAllRequests();
253
+ $testResult = $fakeServer->runTester(new ModuleLoadedTester('setenvif'));
254
+ $this->assertInconclusive($testResult);
255
+ }
256
+
257
  }
webp-express.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: WebP Express
4
  * Plugin URI: https://github.com/rosell-dk/webp-express
5
  * Description: Serve autogenerated WebP images instead of jpeg/png to browsers that supports WebP. Works on anything (media library images, galleries, theme images etc).
6
- * Version: 0.18.2
7
  * Author: Bjørn Rosell
8
  * Author URI: https://www.bitwise-it.dk
9
  * License: GPL2
3
  * Plugin Name: WebP Express
4
  * Plugin URI: https://github.com/rosell-dk/webp-express
5
  * Description: Serve autogenerated WebP images instead of jpeg/png to browsers that supports WebP. Works on anything (media library images, galleries, theme images etc).
6
+ * Version: 0.18.3
7
  * Author: Bjørn Rosell
8
  * Author URI: https://www.bitwise-it.dk
9
  * License: GPL2