Nginx Rewrite Short URL server in Subfolder URL's only - php

Nginx/Php aficionado's
I have a Yourls install running on Nginx which i've got working fine using the following .conf file. The redirects work, the database is copied over from an apache install and all is fine.
However on the old server I had another simple shortURL service running in a sub directory. It has lots of short URL's created with the style of url.com/p/0aexvibr
They all run in the subdirectory called "p" and all the links look like that, they are plain files with nothing but a URL on the top line.
What I need is for Nginx to redirect urls such as url.com/p/0aexvibr and ignore anything to main the URL that is being redirected by the Yourls rewrite rule below. Take them to a php script in /p/ which then opens and redirects the user the URL in the file linked (in this case 0aexvibr contains the url http://google.com) could someone help set this up?
Current conf
server {
listen 80;
server_name url.com;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
root /var/www/html/url;
charset utf-8;
}
location / {
try_files $uri $uri/ /yourls-loader.php;
index index.php;
include /etc/nginx/conf.d/php-fpm;
}
include /etc/nginx/drop;
}
Here is the contents of the show.php
<?php
if($_GET['id']){
$id = addslashes($_GET['id']);
if(file_exists("urls/$id"))
{
$url = file_get_contents("urls/$id");
header("location:".$url);
} else {
echo "Error : invalid hash";
}
} else {
echo "Error : no hash";
}
?>

I don't know how that conf file was working for you , when it comes for the YOURLS redirecting. Anyway, here is my suggestion for your question:
server {
listen 80;
server_name url.com;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
charset utf-8;
##the next two locations for the old service which calls the show.php
location ~ ^/p/(.+\.php)$ {
alias /var/www/html/url/$1;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $request_filename;
include fastcgi_params;
}
location /p {
alias /var/www/html/url/;
try_files $uri $uri/ /p/show.php;
}
##the next two locations for the yourls configuration, expecting it to be in the root directory
location ~ ^/(.+\.php)$ {
alias /var/www/html/url/$1;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $request_filename;
include fastcgi_params;
}
location / {
alias /var/www/html/url/;
index index.php;
try_files $uri $uri/ yourls-loader.php;
}
}

Related

NGINX rewrite configuration for another website in a sub directory triggers script download

This is my original nginx configuration
server {
listen 80;
server_name my-site.com;
return 301 http://www.my-site.com$request_uri;
}
server {
listen 80;
server_name www.my-site.com;
root /var/www/sites/mysite/public_html;
index index.php index.html index.html;
access_log /var/log/nginx/mysite.access.log;
error_log /var/log/nginx/mysite.error.log;
ssl off;
location / {
try_files $uri $uri/ index.php;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass unix:/var/run/php-fpm.sock;
fastcgi_read_timeout 180;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
Then I want to add another site in subfolder lets say "my-site.com/another_app" but this site requires rewriting url like:
my-site.com/another_app/api
my-site.com/another_app/home
becomes
my-site.com/another-app/api.php
my-site.com/another-app/index.php?mod=home
i already tried to add rewrite inside the "location /" like this
location / {
try_files $uri $uri/ index.php;
rewrite ^/another-app/api$ /another-app/api.php break;
rewrite ^/another-app/([A-Za-z0-9-|_]+)/?$ /another-app/index.php?mod=$1 break;
}
But every time I try to access "my-site.com/another-app/api" it triggers to download the php script
Did I missing something?
I can't comment yet so I answer this way.
I have had this problem only with static files like css and js:
I fixed it with indexing the files in the static folder:
location /static/ {
# My static files including the css reside inside my static
# folder e.g. /static/css/style.css
# autoindex on will index everything under the given location
autoindex on;
}
Also what #Richard Smith said, try using last.

PHP not executed when in subdirecory with nginx

When going on example.com, example.com/foo/ or example.com/foo/bar/, PHP was working great. Then I tried to modify Nginx conf to have foo.example.com pointing on example.com/foo/ (the DNS is already configured). It works, but now when I access to foo.example.com/bar/, I can download foo/bar/index.php instead of executing it.
Here is the Nginx configuration:
server {
listen 80;
server_name *.example.com;
root /var/www/html/;
location / {
index index.html;
}
}
server {
listen 80;
server_name foo.example.com;
root /var/www/html/foo/;
location / {
index index.php;
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
fastcgi_pass web_fpm:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
I know there are plenty of similar threads, but none of those I read worked.
The first server declaration catches the request and since you don't have a PHP location block in this server declaration, Nginx just outputs the file. You need to add a PHP location block to the first server declaration.

Nginx to serve static page before dynamic

I want to serve static HTML files with NGINX, but if the file is missing, it should load a PHP file instead and PHP should handle the content.
I've been testing several combinations of try_files, but I can't get my head around it. I have a dummy PHP app that looks like this:
./
../
dynamic.php
index.php
static/
static/static.html
Then I have a small PHP code on index like this:
<?php
$path = $_SERVER['REQUEST_URI'];
$pattern = '/^\/(.*)\.html$/';
$matches = [];
$results = preg_match($pattern, $path, $matches);
if (count($matches) > 0) {
if ($matches[1] == "dynamic") {
require 'dynamic.php';
} else {
echo "Not found!";
}
} else {
echo "Index page!";
}
The results of browsing to each page should be:
http://foo.bar/ - Loads index.php
http://foo.bar/static.html - Loads static/static.html
http://foo.bar/dynamic.html - Loads index.php & PHP requires dynamic.php
http://foo.bar/baz.html - Loads index.php with "not found" message
This is what I got in the NGINX config file:
server {
listen 80;
server_name .foo.bar *.foo.bar;
access_log /var/log/nginx/foo.access.log;
error_log /var/log/nginx/foo.error.log;
root /var/www/foo;
index index.php;
location / {
# Trying with 'try_files' here. No success.
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm-foo.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
I've been trying repeatedly and evidently utterly failing with this line:
try_files $uri $uri/static /index.php;
I am missing something. Help?
I would use your static directory as document root. This ensures that nobody can execute /dynamic.php directly, however, it will be forwarded to your index.php by the named location block #php.
This configuration example is untested!
server {
index index.php;
root /var/www/foo/static;
server_name foo.bar *.foo.bar;
location / {
try_files $uri #php;
}
location #php {
include fastcgi_params;
fastcgi_pass unix:/var/run/php5-fpm-foo.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/foo/index.php;
}
}
You don't need the listen directive if it only contains 80 since this is the default.
The server_names should not contain a leading dot.
The $uri always contains the requested URI including the leading slash (e.g. /static.html) and nginx will prefix them with the document root upon invocation of try_files (e.g. /var/www/foo/static.html). Hence, you need to set your static directory before the $uri (e.g. /static$uri becomes /var/www/foo/static/static.html).
You don't need fastcgi_split_path_info because you are not using that feature.
Your try_files in your PHP location makes it impossible for nginx to properly forward things. A request for /dynamic.html does not end on .php, hence, try_files always fails.
There are a number of ways of hiding the static directory from the URL. For example, manipulating root, clever use of try_files or a rewrite.
Possibly the most obvious is this:
root /var/www/foo;
location / {
root /var/www/foo/static;
try_files $uri /index.php;
}
location ~ \.php$ { ... }
so that nginx looks in the static folder for normal files, but the parent folder for .php files.
What you were trying to achieve was something like this:
root /var/www/foo;
location / {
try_files /static$uri /index.php;
}
location ~ \.php$ { ... }
which will prefix /static to any URI before testing for existence. The /index.php must be the last element as it required processing in a different location. See this document for more.
Based on the specific example case you have given, the configuration below will return the results you listed.
server {
listen 80;
server_name .foo.bar *.foo.bar;
access_log /var/log/nginx/foo.access.log;
error_log /var/log/nginx/foo.error.log;
root /var/www/foo;
index index.php;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm-foo.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /static {
rewrite ^/static\.html$ /static/ last;
index static.html;
}
location ~ / {
rewrite ^ /index.php last;
}
That is ...
http://foo.bar/ - Loads index.php
http://foo.bar/static.html - Loads static/static.html
http://foo.bar/dynamic.html - Loads index.php & PHP requires dynamic.php
http://foo.bar/baz.html - Loads index.php with "not found" message

Laravel 5 - Nginx/PHP config issue

I'm having an issue where when I go to the /public directory it shows the Laravel app as normal, but navigating away to any other page results in it saying
No input file specified.
I am using an Nginx server with PHP 5.5.9 FPM.
I've scoured google for the last 4 hours or so, looking at every tutorial and stackoverflow page for rewriting issues in Laravel however they all yield the same result.
I've even set all the files and folders to 777 so I could see if it was some sort of permissions issue. I've checked the Laravel config and it's all set, I've no idea what is wrong.
Can anyone point me in the right direction?
The last config I tried is below:
server {
listen 80 default_server;
root /usr/share/sites/base;
index index.php
server_name localhost;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
fastcgi_pass unix:/var/run/php5-fpm.sock;
include fastcgi_params;
}
}
I have also tried many others such as:
server {
listen 80;
server_name domain.com;
root /usr/share/sites/base;
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
if (!-d $request_filename) {
rewrite ^/(.+)/$ /$1 permanent;
}
location ~* \.php$ {
# Server PHP config.
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_split_path_info ^(.+\.php)(.*)$;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location ~ /\.ht {
deny all;
}
}
The error "No input files specified" will nearly always be related to the fact that the wrong path was sent to php.
Looking at your 'last config tried' I can see that fastcgi_param SCRIPT_FILENAMEis not defined in your php location. You should first begin by defining it in the location :
location ~ \.php$ {
fastcgi_pass unix:/var/run/php5-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name
}
Furthermore you say that you can reach the app so this means that index.php is working but not when you change page. So the problem should also come from /index.php?$args. Indeed, using this line if I try to reach yourserver.com/test and if 'test' is not a file in your root path nginx will then try request /index.php? (I had this probem). You should try only with /index.php.
EDIT : The solution was that root directive should point to the Laravel public folder, in that case /usr/share/sites/base/public.

Nginx alias and php-fastcgi: No input file specified

I have domain configured as followed:
server {
listen 80;
root /var/www/domains/somedomain/root;
location = /service/alias/ {
alias /var/www/service/alias/;
index index.php;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
I want to execute the index.php file in /var/www/service/alias/ when someone requests http://example.com/service/alias. I've tried many variations (putting the FastCGI parameters in the location and supply the full path for the index.php script), but i keep getting "No input file specified" errors from php-fastcgi.
Anyone an idea of what i'm doing wrong? Or at least how can Ii log the full errors of php-fastcgi?
index is better in a server scope because then all other locations will inheret that value, especially if they are multiple index that are equal, and I like my php block to be as minimal as possible because most other options are already included in fastcgi_params, and I also believe that fastcgi_pass should be passed to an http:// not IP directly, so try this version and tell me if it works for you.
server {
listen 80;
# added a server name, unless it's a catch all virtual host
# then you better use `default_server` with `listen`
server_name example.com;
root /var/www/domains/somedomain/root;
# index moved here
index index.php;
location = /service/alias/ {
# why `=` ? I would remove it unless there's a purpose
# index removed from here
alias /var/www/service/alias/;
}
location ~* \.php$ {
#removed all other options
include fastcgi_params;
# added `http` before `127.0.0.1`
fastcgi_pass http://127.0.0.1:9000;
}
}

Categories