OFFLINE-GmbH / oc-responsive-images-plugin

Adds reponsive images capabilities to October CMS
MIT License
45 stars 26 forks source link

Error 404 after plugin's .htaccess modification #74

Closed 01Kuzma closed 3 years ago

01Kuzma commented 3 years ago

Hello! After installation plugin modifies the .htaccess files. After it all images are unavailable, the 404 is thrown. Removing one line RewriteRule ^/?(.*)$ plugins/offline/responsiveimages/webp.php?path=$1 [NC,END] makes everything working, except plugin.

How should the .htaccess properly looks like? Thank you!

Here is mine with modifications once plug-in is installed, they are appended above:

## START OFFLINE.ResponsiveImages - webp-rewrite
#  DO NOT REMOVE THESE LINES
<IfModule mod_setenvif.c>
    # Vary: Accept for all the requests to jpeg and png
    SetEnvIf Request_URI "\.(jpe?g|png)$" REQUEST_image
</IfModule>
<ifModule mod_rewrite.c>
    RewriteEngine On

    # If the Browser supports WebP images, and the .webp file exists, use it.
    RewriteCond %{HTTP_ACCEPT} image/webp
    RewriteCond %{REQUEST_URI} ^/?storage/.*\.(jpe?g|png)
    RewriteCond %{REQUEST_FILENAME}.webp -f
    RewriteRule ^/?(.*)$ $1.webp [NC,T=image/webp,END]

    # If the Browser supports WebP images, and the .webp file does not exist, generate it.
    RewriteCond %{HTTP_ACCEPT} image/webp
    RewriteCond %{REQUEST_URI} ^/?storage/.*\.(jpe?g|png)
    RewriteCond %{REQUEST_FILENAME}\.webp !-f
    RewriteRule ^/?(.*)$ plugins/offline/responsiveimages/webp.php?path=$1 [NC,END]
</ifModule>
<IfModule mod_headers.c>
    Header append Vary Accept env=REQUEST_image
</IfModule>

<IfModule mod_mime.c>
    AddType image/webp .webp
</IfModule>

## END OFFLINE.ResponsiveImages - webp-rewrite

<IfModule mod_rewrite.c>

    <IfModule mod_negotiation.c>
        Options -MultiViews
    </IfModule>

    RewriteEngine On

    ##
    ## You may need to uncomment the following line for some hosting environments,
    ## if you have installed to a subdirectory, enter the name here also.
    ##
     RewriteBase /

    ##
    ## Uncomment following lines to force HTTPS.
    ##
     RewriteCond %{HTTPS} off
     RewriteRule (.*) https://%{SERVER_NAME}/$1 [L,R=301]

    ##
    ## Black listed folders
    ##
    RewriteRule ^bootstrap/.* index.php [L,NC]
    RewriteRule ^config/.* index.php [L,NC]
    RewriteRule ^vendor/.* index.php [L,NC]
    RewriteRule ^storage/cms/.* index.php [L,NC]
    RewriteRule ^storage/logs/.* index.php [L,NC]
    RewriteRule ^storage/framework/.* index.php [L,NC]
    RewriteRule ^storage/temp/protected/.* index.php [L,NC]
    RewriteRule ^storage/app/uploads/protected/.* index.php [L,NC]

    ##
    ## White listed folders
    ##
    RewriteCond %{REQUEST_FILENAME} -f
    RewriteCond %{REQUEST_URI} !^/plugins/vdlp/phast/phast\.php*    
    RewriteCond %{REQUEST_FILENAME} !/.well-known/*
    RewriteCond %{REQUEST_FILENAME} !/storage/app/uploads/.*
    RewriteCond %{REQUEST_FILENAME} !/storage/app/media/.*
    RewriteCond %{REQUEST_FILENAME} !/storage/temp/public/.*
    RewriteCond %{REQUEST_FILENAME} !/themes/.*/(assets|resources)/.*
    RewriteCond %{REQUEST_FILENAME} !/plugins/.*/(assets|resources)/.*
    RewriteCond %{REQUEST_FILENAME} !/modules/.*/(assets|resources)/.*
    RewriteRule !^index.php index.php [L,NC]    

    ##
    ## Block all PHP files, except index
    ##
    RewriteCond %{REQUEST_FILENAME} -f
    RewriteCond %{REQUEST_URI} !^/plugins/vdlp/phast/phast\.php*
    RewriteCond %{REQUEST_FILENAME} \.php$
    RewriteRule !^index.php index.php [L,NC]

    ##
    ## Standard routes
    ##
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L] 

</IfModule>

UPDATE

Here is a link to a live example https://www.filmustudija.lt/ Is seems that only a few images are working from non homepage. At the home page the "hero" doesn't generate images, the No input file specified. error is specified if I try to access the images directly. system.log is empty. And that's with other pages too. Once I clear the .htaccess - images start displaying. If it make sense, the URL in app.php is seto to 'url' => 'https://filmustudija',

After checking all repo, I've revised .htaccess to this, but it still not working:

<IfModule mod_rewrite.c>

    <IfModule mod_negotiation.c>
        Options -MultiViews
    </IfModule>

    RewriteEngine On

    ##
    ## You may need to uncomment the following line for some hosting environments,
    ## if you have installed to a subdirectory, enter the name here also.
    ##
     RewriteBase /

    ##
    ## Uncomment following lines to force HTTPS.
    ##
     RewriteCond %{HTTPS} off
     RewriteRule (.*) https://%{SERVER_NAME}/$1 [L,R=301]

    <IfModule mod_setenvif.c>
        # Vary: Accept for all the requests to jpeg and png
        SetEnvIf Request_URI "\.(jpe?g|png)$" REQUEST_image
    </IfModule>

    # If the Browser supports WebP images, and the .webp file exists, use it.
    RewriteCond %{HTTP_ACCEPT} image/webp
    RewriteCond %{REQUEST_URI} ^/?storage/.*\.(jpe?g|png)
    RewriteCond %{REQUEST_FILENAME}.webp -f
    RewriteRule ^/?(.*)$ $1.webp [NC,T=image/webp,END]

    # If the Browser supports WebP images, and the .webp file does not exist, generate it.
    RewriteCond %{HTTP_ACCEPT} image/webp
    RewriteCond %{REQUEST_URI} ^/?storage/.*\.(jpe?g|png)
    RewriteCond %{REQUEST_FILENAME}\.webp !-f
    RewriteRule ^/?(.*)$ plugins/offline/responsiveimages/webp.php?path=$1 [NC,END]

    <IfModule mod_headers.c>
        Header append Vary Accept env=REQUEST_image
    </IfModule>

    <IfModule mod_mime.c>
        AddType image/webp .webp
    </IfModule> 

    ##
    ## White listed folders
    ##
    RewriteCond %{REQUEST_FILENAME} -f
    RewriteCond %{REQUEST_URI} !^/plugins/vdlp/phast/phast\.php*    
    RewriteCond %{REQUEST_FILENAME} !/.well-known/*
    RewriteCond %{REQUEST_FILENAME} !/storage/app/uploads/.*
    RewriteCond %{REQUEST_FILENAME} !/storage/app/media/.*
    RewriteCond %{REQUEST_FILENAME} !/storage/temp/public/.*
    RewriteCond %{REQUEST_FILENAME} !/themes/.*/(assets|resources)/.*
    RewriteCond %{REQUEST_FILENAME} !/plugins/.*/(assets|resources)/.*
    RewriteCond %{REQUEST_FILENAME} !/modules/.*/(assets|resources)/.*
    RewriteRule !^index.php index.php [L,NC]    

    ##
    ## Block all PHP files, except index
    ##
    RewriteCond %{REQUEST_FILENAME} -f
    RewriteCond %{REQUEST_URI} !^/plugins/vdlp/phast/phast\.php*
    RewriteCond %{REQUEST_FILENAME} \.php$
    RewriteRule !^index.php index.php [L,NC]

    ##
    ## Standard routes
    ##
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L] 

</IfModule>
01Kuzma commented 3 years ago

Any help??

tobias-kuendig commented 3 years ago

What version of Apache are you using? The plugin does generate code that works in most cases, but depending on your server setup it is possible that the generated htaccess rules are not compatible.

In this case you'll have to debug this on your own as I don't know the details of your setup.

These two blocks are relevant:

    # If the Browser supports WebP images, and the .webp file exists, use it.
    RewriteCond %{HTTP_ACCEPT} image/webp
    RewriteCond %{REQUEST_URI} ^/?storage/.*\.(jpe?g|png)
    RewriteCond %{REQUEST_FILENAME}.webp -f
    RewriteRule ^/?(.*)$ $1.webp [NC,T=image/webp,END]

    # If the Browser supports WebP images, and the .webp file does not exist, generate it.
    RewriteCond %{HTTP_ACCEPT} image/webp
    RewriteCond %{REQUEST_URI} ^/?storage/.*\.(jpe?g|png)
    RewriteCond %{REQUEST_FILENAME}\.webp !-f
    RewriteRule ^/?(.*)$ plugins/offline/responsiveimages/webp.php?path=$1 [NC,END]

You can also add a debug statement like die(var_dump($_GET['path'])); to the webp.php file to see if it gets called.

01Kuzma commented 3 years ago

Apache version is 2.0 It's on a standard shared web hosting, the all settings are provided here

die(var_dump($_GET['path'])); does not give any results. And as I wrote earlier it affects the backend too. The front end could be seen here

tobias-kuendig commented 3 years ago

Apache 2.0 is very old (the last update was released 7 years ago). I don't think it supports all the added rewrite flags (for example END was only added in 2.3).

You either have to rewrite the rule to work with Apache 2.0 or look for a web host that is a bit more up-to-date with its software!

01Kuzma commented 3 years ago

My apologize, the Apache version is 2.4.41. It's up-to-date

By the way, on localhost with XAMPP server running the plug-in is ignored at all.

tobias-kuendig commented 3 years ago

After googling around a bit, it looks like this is some non-standard PHP configuration. If you search for No input file specified a few results turn up. You could for example try this and see if it helps:

https://stackoverflow.com/a/18964139

01Kuzma commented 3 years ago

I had a conversation with hosting support. They said that on shared hosting the cgi us turned off by default and it's not related to this.

Also, they have pointed that after removing temporary the .htaccess, file for a test purpose, the No input file specified error will gone. So, probably in .htaccess there is a not foreseen error...

UPDATE with this .htaccess rules some of images are working and no error are provided. But webp are not created

01Kuzma commented 3 years ago

Within img attributes the srcset are created, but webp is not. Is it also the .htaccess issue? webp.php is not called, checked it with die(var_dump($_GET['path']));.

On Windows XAMPP localhost the srcset is not even created. But, perhaps, it's October's core "feature" on windows machines.

01Kuzma commented 3 years ago

Making further investigations with all default .htaccess settings and virtual host enabled:

## START OFFLINE.ResponsiveImages - webp-rewrite
#  DO NOT REMOVE THESE LINES
<IfModule mod_setenvif.c>
    # Vary: Accept for all the requests to jpeg and png
    SetEnvIf Request_URI "\.(jpe?g|png)$" REQUEST_image
</IfModule>
<ifModule mod_rewrite.c>
    RewriteEngine On

    # If the Browser supports WebP images, and the .webp file exists, use it.
    RewriteCond %{HTTP_ACCEPT} image/webp
    RewriteCond %{REQUEST_URI} ^/?storage/.*\.(jpe?g|png)
    RewriteCond %{REQUEST_FILENAME}.webp -f
    RewriteRule ^/?(.*)$ $1.webp [NC,T=image/webp,END]

    # If the Browser supports WebP images, and the .webp file does not exist, generate it.
    RewriteCond %{HTTP_ACCEPT} image/webp
    RewriteCond %{REQUEST_URI} ^/?storage/.*\.(jpe?g|png)
    RewriteCond %{REQUEST_FILENAME}\.webp !-f
    RewriteRule ^/?(.*)$ plugins/offline/responsiveimages/webp.php?path=$1 [NC,END]
</ifModule>
<IfModule mod_headers.c>
    Header append Vary Accept env=REQUEST_image
</IfModule>
<IfModule mod_mime.c>
    AddType image/webp .webp
</IfModule>

## END OFFLINE.ResponsiveImages - webp-rewrite

<IfModule mod_rewrite.c>

    <IfModule mod_negotiation.c>
        Options -MultiViews
    </IfModule>

    RewriteEngine On

    ##
    ## You may need to uncomment the following line for some hosting environments,
    ## if you have installed to a subdirectory, enter the name here also.
    ##
    # RewriteBase /

    ##
    ## Uncomment following lines to force HTTPS.
    ##
    # RewriteCond %{HTTPS} off
    # RewriteRule (.*) https://%{SERVER_NAME}/$1 [L,R=301]

    ##
    ## White listed folders
    ##
    RewriteCond %{REQUEST_FILENAME} -f
    RewriteCond %{REQUEST_URI} !^/plugins/vdlp/phast/phast\.php*    
    RewriteCond %{REQUEST_FILENAME} !/.well-known/*
    RewriteCond %{REQUEST_FILENAME} !/storage/app/uploads/.*
    RewriteCond %{REQUEST_FILENAME} !/storage/app/media/.*
    RewriteCond %{REQUEST_FILENAME} !/storage/temp/public/.*
    RewriteCond %{REQUEST_FILENAME} !/themes/.*/(assets|resources)/.*
    RewriteCond %{REQUEST_FILENAME} !/plugins/.*/(assets|resources)/.*
    RewriteCond %{REQUEST_FILENAME} !/modules/.*/(assets|resources)/.*
    RewriteRule !^index.php index.php [L,NC]    

    ##
    ## Block all PHP files, except index
    ##
    RewriteCond %{REQUEST_FILENAME} -f
    RewriteCond %{REQUEST_URI} !^/plugins/vdlp/phast/phast\.php*
    RewriteCond %{REQUEST_FILENAME} \.php$
    RewriteRule !^index.php index.php [L,NC]

    ##
    ## Standard routes
    ##
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L] 

</IfModule>

I came to these problems:

1). enter any jpeg url in borwser, http://october.local/storage/app/uploads/public/5ff/33c/908/5ff33c908f7d3014612514.jpg

2). webp.php:

after:

    $baseDir     = env('RESPONSIVE_IMAGES_BASE_DIR', __DIR__ . '/../../..');
    $source      = realpath($baseDir . $source);
    $destination = $source . '.webp';

    $path = validatePath($source);

insert

    var_dump($baseDir);
    echo"<br />";
    var_dump($source);
    echo"<br />";
    var_dump($destination);
    echo"<br />";
    var_dump($path);
    echo"<br />";
       die(var_dump($_GET['path']));

As result I'm getting empty path!

string(71) "C:\xampp\htdocs\october.local\plugins\offline\responsiveimages/../../.."
string(95) "C:\xampp\htdocs\october.local\storage\app\uploads\public\5ff\33c\908\5ff33c908f7d3014612514.jpg"
string(100) "C:\xampp\htdocs\october.local\storage\app\uploads\public\5ff\33c\908\5ff33c908f7d3014612514.jpg.webp"
string(0) ""
string(65) "storage/app/uploads/public/5ff/33c/908/5ff33c908f7d3014612514.jpg"

It's on XAMPP local server. All required libraries are enabled. The same situation is on a shared hosting

tobias-kuendig commented 3 years ago

The validatePath function is returning an empty string. One of these checks fails: https://github.com/OFFLINE-GmbH/oc-responsive-images-plugin/blob/develop/webp.php#L71

I guess the problem here is that you are running under Windows and therefore have \ in your paths instead of /.

This line, for example, does not handle \: https://github.com/OFFLINE-GmbH/oc-responsive-images-plugin/blob/develop/webp.php#L91

Try and see if changing the replacement string to plugins\offline\responsiveimages fixes the issue. If so, we can see if the DIRECTORY_SEPARATOR constant makes sense here, which should return \ on Windows systems.

01Kuzma commented 3 years ago

Thank you! Yes, changing path to $basePath = str_replace('plugins\offline\responsiveimages', '', realpath(__DIR__)); solves the issue on Windows localhost. Now it's works the same as on shared hosting creating a srcset attributes. But one issue left: as not on localhost, and not on a shared hosting a webp files are not created. Log file is empty... What I could check in order to find out the bug/problem?

tobias-kuendig commented 3 years ago

The webp library we're using is returning some debug headers for each file. If you request a file in the browser that should be converted to webp, look at the file's response headers.

There are also other debugging features you can enable by editing our webp.php: https://github.com/rosell-dk/webp-convert/blob/master/docs/v2.0/serving/introduction-for-serving.md#introduction-to-serving-converted-webp-files-with-webpconvert (see show-report or fail)

01Kuzma commented 3 years ago

Thank you! Is it normal behavior, once headers displays webp type, while the extension is jpg? image

tobias-kuendig commented 3 years ago

Yes, the server is sending the webp image for a requested jpeg file. This is why the file extension and type no longer match. There is no way around this without explicitly linking the webp image in your markup (but that would defeat the purpose of this plugin).

Also, your browser does not care about the file extension, all that matters is the Content-Type response header.

01Kuzma commented 3 years ago

Great, thank you!