Moodle 2.3 with Nginx vs slash argument rewrite - nginx

I'm trying to setup Moodle 2.3 (not 2.5) ver with nginx latest build. There was some advice on this site before. One of them: Moodle 2.0 with Nginx backend.
Apparently as anybody knows, Moodle is using path_info rules to post URL's like this: http://example.com/moodle/pluginfile.php/26/mod_scorm/content/1/index.html. To escape all this nightmare, Moodle is offering to disable "Slash arguments" in UI. Which is great. But not for SCORM player which is forcing "Slash argument" despite the previous option. So with disabled "Slash arguments" everything is working and normal. But my only goal is to use SCORM player.
I tried to use the rewrite rule from the link above:
rewrite ^(.*\.php)(/)(.*)$ $1?file=/$3 last;
which is not working in 2.3-2.5 ver. I assume it worked in 1.9.
Now Moodle is using different path:
http://example.com/moodle/pluginfile.php/26/mod_scorm/content/1/index.html
Some of nginx rules:
location ^~ /moodle {
location ~* ^.+\.(?:css|js|htc|xml|jpe?g|gif|png|ico|bmp|svg|swf|pdf|docx?|xlsx?|tiff?|txt|rtf|cgi|bat|pl|dll|aspx?|class|otf|ttf|woff|eot|less)$ {
add_header Access-Control-Allow-Origin *;
access_log off;
expires 30d;
tcp_nodelay off;
try_files $uri =404;
}
location ~* ^/moodle/.*\.php$ {
include includes/fastcgi_params.conf;
try_files $uri #dynamic;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
fastcgi_read_timeout 1200;
fastcgi_keep_conn on;
fastcgi_pass 127.0.0.1:9090;
}
rewrite (^.*\.php)(/.*) $1 last;
}
Please advise how to solve this.

(Answered by the OP in a question edit. Converted to a community wiki answer. See Question with no answers, but issue solved in the comments (or extended in chat) )
The OP wrote:
I solved this by putting rewrite directive in {server} not in {location} section. In my scenario moodle is installed under subfolder: example.com/moodle.
server {
server_name example.com www.example.com;
rewrite ^/moodle/(.*\.php)(/)(.*)$ /moodle/$1?file=/$3 last;
location ^~ /moodle {
try_files $uri $uri/ /index.php?q=$request_uri;
index index.php index.html index.htm;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass 127.0.0.1:9090;
include includes/fastcgi_params.conf;
}
}
}

Related

NGINX Cache Busting CSS JS URL Rewrite

I'm new to NGINX and trying to set up a portfolio. I've gotten my site working with the exception of a few errors that I noticed through Google Chrome DevTools.
I notice that javascript files aren't loading and have the incorrect path. For example, it tries to load http://site/assets/js/site.1617886701.js but the actual file is http://site/assets/js/site.js
Likewise with a css file I have: It tries to load http://site/assets/css/templates/home..css (for some reason it adds an extra .?) when it should be loading this file: http://site/assets/css/templates/home.css
This is my NGINX config file:
server {
listen 80;
listen [::]:80;
root /var/www/html/;
index index.php index.html index.htm;
server_name site wwww.site.com;
client_max_body_size 100M;
location / {
try_files $uri $uri/ /index.php?$uri&$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}
location /assets {
rewrite uikit.min.(\d+).js uikit.min.js permanent;
rewrite uikit-icons.min.(\d+).js uikit-icons.min.js permanent;
rewrite uikit.app.min.(\d+).css uikit.app.min.css permanent;
try_files $uri =404;
expires max;
access_log off;
add_header Pragma public;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
}
}
From my googling online it says something about cache busting. Some people have suggested matching the file names in the NGINX config file which I'm not sure how to do or to change the paths to match the hexadecimal versions which I also don't know where to begin.
I would really appreciate any help from the pros! Thanks so much
For example, it tries to load http://site/assets/js/site.1617886701.js but the actual file is http://site/assets/js/site.js
It is not NGINX, it's your web application, which constructs such cache-busting URLs, which expect extra configuration on the side of NGINX.
The way to deal with it, is a rewrite in NGINX:
rewrite ^(.+)\.(\d+)\.(css|js)$ $1.$3 last;
This will rewrite, e.g. any /some/<foo>.<digits>.js to /some/<foo>.js.
It tries to load http://site/assets/css/templates/home..css
Obviously, a bug in your web application's code. Shouldn't be attempted to be fixed in NGINX.

Redirect in nginx [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I know that there are a lot of similar questions but I tried several solutions and I can't find correct solution.
I have no idea about nginx. I have only simple task: redirect all addresses /backend.php/* to /backend.php in one concrete application/website. I used * to express anything. Now /backend.php/* path is redirected to /index.php.
This is my config file:
server {
server_name _;
rewrite ^ $scheme://mysite.com$request_uri redirect;
}
upstream md {
#this should match value of "listen" directive in php-fpm pool
server unix:/var/run/md.php5-fpm.sock;
}
server
{
server_name .mydomain.eu .mydomain.du;
access_log /var/log/nginx/mydomain.access.log;
error_log /var/log/nginx/mydomain.error.log;
root /home/md/;
include conf/restrictions.conf;
include conf/wordpress.conf;
# Pass all .php files onto a php-fpm/php-fcgi server.
location ~ \.php$ {
# Zero-day exploit defense.
# http://forum.nginx.org/read.php?2,88845,page=3
# Won't work properly (404 error) if the file is not stored on this server, which is entirely possible with php-fpm/php-fcgi.
# Comment the 'try_files' line out if you set up php-fpm/php-fcgi on another machine. And then cross your fingers that you won't get hacked.
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
#NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
include fastcgi_params;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# fastcgi_intercept_errors on;
fastcgi_pass md;
}
}
=======UPDATE===========
conf/wordpress.conf:
# WordPress single blog rules.
# Designed to be included in any server {} block.
# This order might seem weird - this is attempted to match last if rules below fail.
# http://wiki.nginx.org/HttpCoreModule
location / {
try_files $uri $uri/ /index.php?$args;
}
# Add trailing slash to */wp-admin requests.
rewrite /wp-admin$ $scheme://$host$uri/ permanent;
# Directives to send expires headers and turn off 404 error logging.
location ~* ^.+\.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
access_log off; log_not_found off; expires max;
}
# Uncomment one of the lines below for the appropriate caching plugin (if used).
#include global/wordpress-wp-super-cache.conf;
#include global/wordpress-w3-total-cache.conf;
## Pass all .php files onto a php-fpm/php-fcgi server.
#location ~ \.php$ {
# # Zero-day exploit defense.
# # http://forum.nginx.org/read.php?2,88845,page=3
# # Won't work properly (404 error) if the file is not stored on this server, which is entirely possible with php-fpm/php-fcgi.
# # Comment the 'try_files' line out if you set up php-fpm/php-fcgi on another machine. And then cross your fingers that you won't get hacked.
# try_files $uri =404;
#
# fastcgi_split_path_info ^(.+\.php)(/.+)$;
# #NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
#
# include fastcgi_params;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
## fastcgi_intercept_errors on;
## fastcgi_pass wp-php;
#}
Ok. Nginx request rules operate on the regular expressions first from more specific to less specific. Then operate on the non regular expression rules.
In your case I honestly don't know in what order is
rewrite /wp-admin$ $scheme://$host$uri/ permanent;
processed so please comment it out while we sort the other issue.
The following rule is the less specific and has no regex, so it will be processed last
location / {
try_files $uri $uri/ /index.php?$args;
}
which is fine. It's a fallback for any request that's not php or either not a real url (for example, wordpress nice urls).
The following rule has regex and is very specific, so it will be processed first than any other and as you see, it affects static files:
location ~* ^.+\.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
access_log off; log_not_found off; expires max;
}
And lastly, the php rule has regex and is less specific than the previous one, so it will be processed for requests that end in .php unless they have a static file extension (which won't happen because if they do, then they won't match the "end with php" thing).
location ~ \.php$ {
...
fastcgi_pass md;
}
So at this point, if you issue a request that points to /backend.php with or without query string, and there is a file with that name, it will fall under the .php rule and pass to your php-fpm backend.
If you issue a request that points to /backend.php/something and there isn't a folder with that name, it will fall under the first rule, and since there isn't a backend.php folder, it will be redirected (by the try_files directive) to index.php.
Long story short. If you need that urls that have backend.php be redirected to backend.php, you need to set another rule that's more specific than the .php one.
EDIT: just to discard possible errors, please comment out the line in which you're including conf/wordpress.conf. Instead, your second server block should read
server
{
server_name .mydomain.eu .mydomain.du;
access_log /var/log/nginx/mydomain.access.log;
error_log /var/log/nginx/mydomain.error.log;
root /home/md/;
include conf/restrictions.conf;
location / {
try_files $uri $uri/ /index.php?$args;
}
# Directives to send expires headers and turn off 404 error logging.
location ~* ^.+\.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
access_log off; log_not_found off; expires max;
}
location ~ ^/backend\.php/(.*)$ {
try_files $uri /backend.php?$1;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include fastcgi_params;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass md;
}
}

symfony2, wordpress and nginx configuration

I have symfony2 on the main page, now i tried to install WordPress on the sub directory called blog.
I'm using nginx as web server with fastcgi. I tried to configure the it but i got the error 500.
Does anyone know how to set it up properly on nginx?
Thanks
rewrite ^(.*) /app_dev.php last;
Should probably be something like
rewrite ^(.*) /web/app_dev.php last;
You also probably rather want to use try_files like so, else your images, css, js assets won't be found. Something like
location / {
# try to serve file directly, fallback to rewrite
try_files $uri /web/$uri #rewrite;
expires 30d; ## Assume all files are cachable
location ~ \.php {
expires off;
fastcgi_pass 127.0.0.1:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME
$document_root$fastcgi_script_name;
fastcgi_param HTTPS on;
add_header X-Frame-Options "ALLOW-FROM https://www.youtube.com/" ;
}
}
location #rewrite {
rewrite ^/(.*)$ /web/app.php/$1 last;
}
location /blog {
//Wordpress routing here
}
Anyway that is how I'm doing it with Magento instead of Wordpress.

Wordpress Permalink Issue - extra "index.php" in pretty permalink

I migrated my site from Apache to Nginx,the problem now is my permalinks have an extra index.php in the URL, I am not able to determine if this is a wordpress issue or my configuration issue.
Example when my post is rendered the original link: http://hs.com/2012/04/30/a-new-question/
is now being linked as http://hs.com/*index.php/*2012/04/30/a-new-question/
I tried the nginx compatibility plug in.. also tried the custom structure options with and without the plug in and I am just not able to understand what is going on. Wordpress says that the custom permalink structure is saved, even then all links in the site are rendered incorrectly.
Here is my nginx configuration for the site.
server {
server_name harshasagar.com www.harshasagar.com;
access_log /srv/www/harshasagar.com/logs/access.log;
error_log /srv/www/harshasagar.com/logs/error.log;
root /srv/www/harshasagar.com/public_html;
if ($host ~* www\.(.*)) {
set $host_without_www $1;
rewrite ^(.*)$ http://$host_without_www$1 permanent; # $1 contains '/foo', not 'www.mydomain.com/foo'
}
location / {
index index.html index.htm index.php;
try_files $uri $uri/ /index.php?q=$uri&$args;
}
location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /srv/www/harshasagar.com/public_html$fastcgi_script_name;
}
Replace line:
try_files $uri $uri/ /index.php?q=$uri&$args;
with
try_files $uri $uri/ /index.php?$args;
And install this plugin - http://wordpress.org/extend/plugins/nginx-helper/
If you face issue after that please let me know.

Nginx forward www and non-www requests to one directory?

I have a MediaTemple server from which I serve many websites. I use nginx and have the follow config file. I am correctly forwarding all non-www traffic (ie, http://example.com) to the appropriate directory. However, all the www traffic is returning 404 because my config file is looking for /directory-structure/www.sitename.com instead of /directory-structure/sitename.com
How can I have both www and non-www requests go to one directory? Thanks.
server {
listen 80;
server_name _;
root /var/www/vhosts/$host/httpdocs/;
error_page 404 /;
location / {
try_files $uri $uri/ /index.php;
}
location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_script_name;
#fastcgi_pass php;
fastcgi_pass 127.0.0.1:9000;
}
location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
expires max;
add_header Pragma public;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
}
# this prevents hidden files (beginning with a period) from being served
location ~ /\. { access_log off; log_not_found off; deny all; }
}
Starting with version 0.7.40 Nginx accepts regular expressions in server_name and captures. Thus it's possible to extract a domain name (without www) and use this variable in root directive:
server_name ~^(?:www\.)?(.+)$ ;
root /var/www/vhosts/$1/httpdocs;
Starting with 0.8.25 it is possible to use named captures:
server_name ~^(?:www\.)?(?P<domain>.+)$ ;
root /var/www/vhosts/$domain/httpdocs;
Another syntax to define named captures is (?<domain>.+) (PCRE version 7.0 and later). More on PCRE versions here
Try this and add the following in the above server config:
if ($host = "www.example.com") {
rewrite (.*) http://example.org$1;
}
What happens here, we are instructin nginx to serve the pages as http://example.com even though the browser URL reads http://www.example.com - I hope this works.
UPDATE
Try this for a generic version:
if ($host ~* "www.(.*)") {
rewrite ^ http://$1$request_uri?;
}
Given the potential issues with if as linked to in RakeshS's answer's comments, as well as the fact that RakashS's answer didn't work for me anyway, here's a solution that should be safer and worked for me with Nginx 1.0.14.
Add an additional server entry for each one of your server sections that does a rewrite:
server {
server_name www.yourwebsite.com;
rewrite ^ $scheme://yourwebsite.com$request_uri permanent;
}

Resources