basic-captcha not showing image (404)
prismplex opened this issue · comments
Description of the issue:
Captcha image is not displayed using basic-captcha in a modular page.
Investigation:
Console throws: Failed to load resource: the server responded with a status of 404 ()
trying to reach captcha image via https://url.com/forms-basic-captcha-image.jpg?v=1663798282900
Current setup:
Modular page, reachable via https://url.com/de/contact
Working configuration before embedding basic captcha:
title: 'Contact form'
form:
action: /contact
name: contact-form
fields:
-
name: name
label: Name
placeholder: 'Your name'
autocomplete: 'on'
type: text
validate:
required: true
-
name: firstname
label: 'First Name'
placeholder: 'Ihr Vorname'
type: honeypot
-
name: email
label: Email
placeholder: 'Your email adress'
type: email
validate:
required: true
-
name: message
label: Message
placeholder: 'Your message'
type: textarea
validate:
required: true
-
name: terms
label: 'I have read, understood and accepted the privacy policy.'
type: checkbox
validate:
required: true
buttons:
-
type: submit
value: Submit
-
type: reset
value: Reset
process:
-
email:
from: '{{ config.plugins.email.from }}'
to:
- '{{ config.plugins.email.from }}'
- '{{ form.value.email }}'
subject: '[Contact] {{ form.value.name|e }}'
body: '{% include ''forms/data.html.twig'' %}'
-
save:
fileprefix: feedback-
dateformat: Ymd-His-u
extension: txt
body: '{% include ''forms/data.txt.twig'' %}'
-
message: 'Danke für Ihre Nachricht!'
-
display: thankyou
New configuration:
title: 'Contact form'
form:
action: /contact
name: contact-form
fields:
-
name: name
label: Name
placeholder: 'Your name'
autocomplete: 'on'
type: text
validate:
required: true
-
name: firstname
label: 'First Name'
placeholder: 'Ihr Vorname'
type: honeypot
-
name: email
label: Email
placeholder: 'Your email adress'
type: email
validate:
required: true
-
name: message
label: Message
placeholder: 'Your message'
type: textarea
validate:
required: true
-
name: terms
label: 'I have read, understood and accepted the privacy policy.'
type: checkbox
validate:
required: true
-
name: basic-captcha
type: basic-captcha
placeholder: 'Bitte kopieren Sie die 10 Zahlen oder Buchstaben'
label: 'Are you human?'
buttons:
-
type: submit
value: Submit
-
type: reset
value: Reset
process:
-
basic-captcha:
message: 'Humanity verification failed, please try again...'
-
email:
from: '{{ config.plugins.email.from }}'
to:
- '{{ config.plugins.email.from }}'
- '{{ form.value.email }}'
subject: '[Contact] {{ form.value.name|e }}'
body: '{% include ''forms/data.html.twig'' %}'
-
save:
fileprefix: feedback-
dateformat: Ymd-His-u
extension: txt
body: '{% include ''forms/data.txt.twig'' %}'
-
message: 'Danke für Ihre Nachricht!'
-
display: thankyou
Am I missing something?
I think its more likely an issue of the multilang config (/de)causing the route not to be found, i'll investigate.
well, i can't replicate this on my test environment with multi-language enabled, and with a modular form. Works fine for me. Is it possible for me to inspect your site in my browser and see the actual issue?
Image is neither reachable via https://url.com/contact/forms-basic-captcha-image.jpg?v=1663800272971
/https://url.com/_contact/forms-basic-captcha-image.jpg?v=1663800272971
nor https://url.com/de/forms-basic-captcha-image.jpg?v=1663800272971
or https://url.com/de/contact/forms-basic-captcha-image.jpg?v=1663800272971
/https://url.com/de/_contact/forms-basic-captcha-image.jpg?v=1663800272971
It should work fine as https://url.com/forms-basic-captcha-image.jpg?v=1663798282900
which is where it's expecting it, and what you originally had. That's why i need to see your site 'live' to inspect the request/response.
Take my username, add .io (switch to English) and go to the contact site.
Very strange, it's like you are missing some code. Can you confirm you have this at the bottom of your user/plugins/form/form.php
file:
protected function processBasicCaptchaImage(Uri $uri)
{
if ($uri->path() === '/forms-basic-captcha-image.jpg') {
$captcha = new BasicCaptcha();
$code = $captcha->getCaptchaCode();
$image = $captcha->createCaptchaImage($code);
$captcha->renderCaptchaImage($image);
exit;
}
}
Definitely seems like your webserver is handling errors for images independently from documents/pages, and that's causing this issue. any request for an arbitrary .jpg or .png (/foo.jpg) is getting this error, where any made up page gets the Grav error page (/foo).
Very strange, it's like you are missing some code. Can you confirm you have this at the bottom of your
user/plugins/form/form.php
file:protected function processBasicCaptchaImage(Uri $uri) { if ($uri->path() === '/forms-basic-captcha-image.jpg') { $captcha = new BasicCaptcha(); $code = $captcha->getCaptchaCode(); $image = $captcha->createCaptchaImage($code); $captcha->renderCaptchaImage($image); exit; } }
Did not have this code, added it at the end. Installed forms shows version v7.0.1
Actually did you create this 404 error page?
Is it grav that's outputting that? doesn't really look like it, it's like something is intercepting 404 and grav is not getting the chance to resolve that URL.
Yes, I created it, but removed it now to show that that is (in my opinion) not the problem, as the webserver only outputs 404 if the file is not found.
I am using the nginx config from the official GRAV documentation.
https://github.com/getgrav/grav-plugin-form/blob/7.0.1/form.php#L1279-L1288
If you have 7.0.1 you should have this method, see the link above. If you copy that in there does it work??
https://github.com/getgrav/grav-plugin-form/blob/7.0.1/form.php#L1279-L1288
If you have 7.0.1 you should have this method, see the link above. If you copy that in there does it work??
That is really strange... - Thinking about reinstalling GRAV.
Copied it, cleared full cache, still does not work.
Deleted full form folder under plugins, reinstalled, verified the existance function (it is there) - cleared full cache - still not working...
Frankly i would look at your nginx config, and if there's any error page stuff there, comment them out. I don't have any nginx test environments handy, but i've tested with Apache, Litespeed, and bulit-in PHP webserver and those are all fine.
My nginx config:
server {
listen 80;
listen [::]:80;
server_name url.com www.url.com;
return 301 https://url.com$request_uri;
}
server {
listen 127.0.0.1:443 ssl http2;
listen [::1]:443 ssl http2;
server_name url.com www.url.com;
ssl_certificate /home/user/.acme.sh/url.com/fullchain.pem;
ssl_certificate_key /home/user/.acme.sh/url.com/privkey.pem;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
include conf.d/grav-security.conf;
include conf.d/general.conf;
#include conf.d/error.conf;
#Logging accesses and errors - change to PATH according your needs
access_log /home/user/conf/nginx.log/access.url.com.log;
error_log /home/user/conf/nginx.log/error.url.com.log;
# Path to the root of your installation
root /home/user/nginx/grav-url.com;
index index.php index.html index.htm /_h5ai/public/index.php;
## Begin - Index
# for subfolders, simply adjust:
# `location /subfolder {`
# and the rewrite to use `/subfolder/index.php`
location / {
try_files $uri $uri/ /index.php?_url=$uri&$query_string;
}
## End - Index
## Begin - Security
# deny all direct access for these folders
location ~* /(.git|cache|bin|logs|backup|tests)/.*$ { return 403; }
# deny running scripts inside core system folders
location ~* /(system|vendor)/.*\.(txt|xml|md|html|yaml|php|pl|py|cgi|twig|sh|bat)$ { return 403; }
# deny running scripts inside user folder
location ~* /user/.*\.(txt|md|yaml|php|pl|py|cgi|twig|sh|bat)$ { return 403; }
# deny access to specific files in the root folder
location ~ /(LICENSE.txt|composer.lock|composer.json|nginx.conf|web.config|htaccess.txt|\.htaccess) { return 403; }
## End - Security
## Begin - PHP
location ~ \.php$ {
# Choose either a socket or TCP/IP address
# fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_pass 127.0.0.1:portnumber;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
}
## End - PHP
include conf.d/grav.conf;
}
general.conf
# favicon.ico
location = /favicon.ico {
log_not_found off;
access_log off;
}
# robots.txt
location = /robots.txt {
log_not_found off;
access_log off;
}
client_max_body_size 16G; # set max upload size depending on your desires
fastcgi_buffers 64 4K;
# gzip
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
#gzip_types text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;
gzip_types
application/atom+xml
application/javascript
application/json
application/ld+json
application/manifest+json
application/rss+xml
application/vnd.geo+json
application/vnd.ms-fontobject
application/x-font-ttf
application/x-web-app-manifest+json
application/xhtml+xml
application/xml
font/opentype
image/bmp
image/svg+xml
image/x-icon
text/cache-manifest
text/css
text/plain
text/vcard
text/vnd.rim.location.xloc
text/vtt
text/x-component
text/x-cross-domain-policy;
grav-security.conf
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Download-Options "noopen" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Permitted-Cross-Domain-Policies "none" always;
add_header X-Robots-Tag "none" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Permissions-Policy "interest-cohort=()" always;
fastcgi_hide_header X-Powered-By;
# force the latest IE version
add_header "X-UA-Compatible" "IE=Edge";
# Use a higher keepalive timeout to reduce the need for repeated handshakes
keepalive_timeout 300s; # up from 75 secs default
ssl_session_cache shared:SSL:10m; # a 1mb cache can hold about 4000 sessions, so we can hold 40000 sessions
ssl_session_timeout 24h;
# submit domain for preloading in browsers at: https://hstspreload.appspot.com
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
grav.conf
location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
expires 30d;
add_header Vary Accept-Encoding;
log_not_found off;
}
location ~* ^.+\.(?:css|cur|js|jpe?g|gif|htc|ico|png|html|xml|otf|ttf|eot|woff|woff2|svg)$ {
access_log off;
expires 30d;
add_header Cache-Control public;
## No need to bleed constant updates. Send the all shebang in one
## fell swoop.
tcp_nodelay off;
## Set the OS file cache.
open_file_cache max=3000 inactive=120s;
open_file_cache_valid 45s;
open_file_cache_min_uses 2;
open_file_cache_errors off;
}
I really don't know where the problem here could be, as it is basically all copoied from the official GRAV documentation...
After some testing I found the problem.
After disabling
grav.conf
location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
expires 30d;
add_header Vary Accept-Encoding;
log_not_found off;
}
location ~* ^.+\.(?:css|cur|js|jpe?g|gif|htc|ico|png|html|xml|otf|ttf|eot|woff|woff2|svg)$ {
access_log off;
expires 30d;
add_header Cache-Control public;
## No need to bleed constant updates. Send the all shebang in one
## fell swoop.
tcp_nodelay off;
## Set the OS file cache.
open_file_cache max=3000 inactive=120s;
open_file_cache_valid 45s;
open_file_cache_min_uses 2;
open_file_cache_errors off;
}
everything works as expected, captcha images are showing
I have the same problem when running Grav in docker with image lscr.io/linuxserver/grav:latest
.
I will check if the solution from @prismplex does also fix the issue for me.
EDIT: it appears that the same configuration also exists in this docker image (file config/nginx/site-confs/default.conf
) and by disabling these same lines the issue is fixed. Everything seems to work including the captcha image.
👍🏻
Why close this issue without an answer?
I had the same problem when using the official directives provided by Grav for Nginx.
I deleted jpe?g
from the regex lists, but I would like to put it back and find which parameter break basic-captcha.
Why close this issue without an answer?
I had the same problem when using the official directives provided by Grav for Nginx.
I deleted
jpe?g
from the regex lists, but I would like to put it back and find which parameter break basic-captcha.
I also would like to use the basic captcha, but I got same issue in case of GPDR. Sure, I could change the grav.conf file, but in case that I'm using lscr.io/linuxserver/grav:latest
in docker, that's no right solution.
It seems like adding:
location ~* ^/forms-basic-captcha-image.jpg$ {
try_files $uri $uri/ /index.php$is_args$args;
}
to the top of grav.conf
(or in the lsio conf, add it right below ## Begin - Caching
) resolves the issue. I will open PRs for this.
@nemchik you made my day! Thx for the fix, it works!