PHP front controller in nginx - php

I have a wiki that hosts user-generated content with URLs like /wiki/view/pagename and /wiki/modify/pagename. I'm using an nginx configuration that goes something like:
location /wiki/ {
try_files $uri $uri/ /wiki/index.php?q=$uri&$args;
}
location ~ \.php$ {
try_files $uri =404;
#fastcgi stuff...
}
It's been working great and as far as i can tell, this is the recommended approach. However, today, a user created a page named "whatever.php", so it needs the URLs /wiki/view/whatever.php to be redirected to my /wiki/index.php... but it gets caught in the second location block and returns a 404 to the user-agent.
Does anyone have any suggestions? Can i add an extra location block to rewrite *.php to the main script somewhere in such a way that won't affect actually routing pages? I still want to use nginx to serve static content inside the /wiki/ directory and to preserve the behaviour of everything outside this directory.
Repost of this dead forum thread

Related

How to use .htaccess to switch content to display under maintenance message

I want to have /blog directory on my application to have an instance of WordPress installed there. Currently /blog does takes me there, but I do want to know and have control, instead of directory how to read from routes.php.
There can be many use cases for it as blog directory is under maintenance or its down, in that case a simple change so it starts reading /blog from routes.php.
I am not much expert of '.htaccess' file but can we do from it?
if your CI application use the default routes configuration, then /blog will make CI try to load blog controller and index action, if it can't find them. you'll get 404 page not found error.
try to config the /blog in your web server configuration. add /blog block then apply wordpress server config there. make sure that request will find /blog location block before the / location block.
in nginx:
location /blog {
# This is cool because no php is touched for static content.
# include the "?$args" part so non-default permalinks doesn't break when using query string
try_files $uri $uri/ /index.php?$args;
}
# then your ci / location
location / {
# Check if a file or directory index file exists, else route it to index.php.
try_files $uri $uri/ /index.php;
}

How to skip a directory in a URI using NGINX?

So I saw this answer, but it didn't seem related to this question.
My situation is, I have a directory on my website called mywebsite.com/indev/dist (since dist is the build folder). I want all the files in mywebsite.com/indev/dist to appear and work as if the dist folder didn't exist at all.
For example, if I requested mywebsite.com/indev/index45.php, the file would be located at /indev/dist/index45.php.
Here's what I've tried so far:
location ~ .*\/indev\/dist.* {
try_files $uri $uri/ =404;
}
location ~ .*\/indev.* {
rewrite ^\/indev\/(.*) /indev/dist/$1 break;
}
This works fine with one major drawback: php files don't run, they go to the original address which gives a 404 in return. Is there any way to do what I'm using using the NGINX config without any major drawbacks (or having to make unnecessary rules (ex. just to handle php files)?)

How do I get NGINX to properly rewrite and execute on a custom PHP application?

We have a custom PHP application that we wrote and runs on Apache with .htaccess files to handle the url rewrites. We are trying to convert it to work under NGINX with FPM under Plesk Onyx.
The application generates links like:
https://somedomain.com/mypage (same as index/mypage)
https://somedomain.com/index/sitemap
https://somedomain.com/blog/some-article-name
These URL's map to index.php files that take the request_uri and use it to render the page responses.
The structure of the application is nested as follows:
docroot (/)
./index.php //handler for the request in /
./blog/index.php //handler for any request to /blog
Each index.php expects to receive a ?path={request_uri} so that it can map the request to the controllers and actions.
I have tried multiple ways to get NGINX to do this using tryfiles and rewrite, but no luck. Using rewrite I can get / to work, but it wont render /mypage or /index/sitemap.
If I try to hit /index/sitemap it downloads the index.php instead of executing it, and if I try the blog the same thing happens. In fact the only path that works is /, all others just download the index.php file.
Here is my configuration as it is now, where am I going wrong?
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 30d;
add_header Pragma public;
add_header Cache-Control “public”;
try_files $uri #fallback;
}
location / {
#index index.php index.html index.html;
rewrite ^/([^?]*) /index.php?path=$1 break;
rewrite ^blog/([^?]*) /blog/index.php?path=$1 break;
#try_files $uri #fallback;
}
Your configuration has multiple issues. I will ignore the first location block as it seems to have nothing to do with your question.
The first rewrite will always match, so the second rewrite will never be consulted. The second rewrite will never match anyway, as nginx URIs always begin with a /. The [^?] is meaningless, because rewrite uses a normalised URI which does not include the ? or query string. Using rewrite...break means that the rewritten URI is processed within the same location, which is an error as this location is not equipped to process PHP files. See this document for more.
A solution using try_files might look like this:
location / {
try_files $uri $uri/ /index.php?path=$uri&$args;
}
location /blog {
try_files $uri $uri/ /blog/index.php?path=$uri&$args;
}
location ~ \.php$ { ... }
See this document for more.

Redirect /download URI to subdomain on same domain

I finished developed an app that features a downloading system that is hosted with NGINX at:
http://dashboard.myapp.com
The URL for downloads is:
http://dashboard.myapp.com/download/file-slug
This page is a regular PHP page that will require some user input and then PHP handles the actual file download, it's not the direct path for the file.
Since these download URLs will be made publicly available, I want to ditch that dashboard subdomain.
The default domain (myapp.com) is already working with a wordpress setup with this:
location / {
try_files $uri $uri/ /index.php?q=$uri&$args;
}
Is there an easy way to get the:
http://myapp.com/download/file-slug
to act as if:
http://dashboard.myapp.com/download/file-slug
was accessed, without actually redirecting?
Try this - Place in your server block for myapp.com, anywhere outside another location block. Set the root to the same root as the dashboard subdomain (if on the same server). The script would see itself as being hosed at myapp.com instead of dashboard.myapp.com, but it should retain the remainder of the framework rules. If this doesn't work, try the next option.
location /download/file-slug {
root /path/folder;
try_files $uri $uri/ /index.php?q=$uri&$args;
}
Another option is to proxy through Nginx. This option actually runs the script on the current location, accessing it like a client would through dashboard.myapp.com. See proxy_pass documentation on Nginx.org.
location /download/file-slug { proxy_pass http://dashboard.myapp.com/download/file-slug; }
I was able to work it out with Nginx only.
Inside the myapp.com config file I added:
location ~ /download/(.*) {
resolver 8.8.8.8;
proxy_pass http://dashboard.myapp.com/download/$1;
}
The resolver 8.8.8.8 is actually using Google DNS. Without this line I was getting a "no resolver defined to resolve" error.

How to get the right try_files $uri directive working with _GET parameters in nginx

I just migrated a site from apache to nginx, and am very pleased so far. However, the server doesn't seem to recognize a $_GET parameter.
I've read that the answer is to change the try_files directive to:
location / {
try_files $uri $uri/ /index.php?$query_string;
}
But this isn't working for me. I suspect it's because the query string I'm using is a few directories in, with the url something like:
http://www.mysite.com/thedirectory/thefile?sortby=director
I just can't tweak the try_files directive to work in that instance, and the documentation seems sparse or obsolete.
Any ideas? If I don't get this resolved, I'm going to have to go back to Apache.
I don't know where you got that answer from,but in the context of your problem I don't see the relevance. Let's first get something clarified:
Try_files looks to match the URI with a physical location on disk and allows you to control the fallback action.
The default fallback is to throw a 404.
$query_string is not relevant to the matching process. It is used for try_files constructs where something has to be added to the query string.
There are three possible causes and remedies for your problem:
The uri matches a real file, but without the file extension, which causes the php processing location to not get triggered. In this case your statement should be:
try_files $uri $uri/ $uri.php;
This is a virtual location and the router is in index.php, like it it's with many applications, like WordPress and Magento.
In this case the try_files should be:
try_files $uri $uri/ #appname;
Without more context providing a location block for #appname is not possible.
You are not including relevant fastcgi_param directives. In this case your try_files is noise. Fix the actual problem first, by including the provided example fastcgi_param, as mentioned in the comments.

Categories