
Question:
Some time ago I developed a shortlink service (like goo.gl).
Shortlinks in the browsers addressbar are displayed as example.com/Lg1Q
Recently I migrated from Lighty to Nginx, due to performance benefits. In Lighttpd I used
url.rewrite-if-not-file = (
"^/(.*)(\?.*)?$" => "/index.php?fwd=$1"
)
to hand over the "Lg1Q" part from the URL to the index.php script.
The index.php script processes the not-file-part from the URL as follows:
if ( !empty( $myUrl ) && $_SERVER['REQUEST_URI'] !== '/index.php' && $_SERVER['REQUEST_URI'] !== '/index.html' && $_SERVER['REQUEST_URI'] !$
$query = htmlspecialchars( str_replace("fwd=","", $_SERVER['QUERY_STRING']) );
require_once 'src/clsForwardURL.class.php';
$myForward = new clsForwardURL();
$url = $myForward->fForwardURL( $query );
$url = ( $url[0]['su_longurl'] );
echo header( 'location:'.$url );
}//end if
I tried to rebuild the rewrite rule from Lighttpd to Nginx syntax like:
rewrite "^/(.*)(\?.*)?$" /index.php?fwd=$1;
After that, I inserted this rule subsequently in the location ~ \.php
block and the location /
block of the nginx host container in /etc/nginx/sites-available.
Unfortunally in both cases the browser showed a '404' or a '500' error.
My question is: How can I properly setup the rewrite rule for the 'shortlink' purpose?
Answer1:The rewrite
in the location /
block will rewrite everything - not just your short URIs. You could qualify the rewrite operation using a try_files
statement. See <a href="http://nginx.org/en/docs/http/ngx_http_core_module.html#try_files" rel="nofollow">this document</a> for more.
For example:
location / {
try_files $uri $uri/ @rewrite;
}
location @rewrite {
rewrite ^/(.*)$ /index.php?fwd=$1 last;
}
Notice that the query string component is not part of the normalised URI used by the rewrite
directive. See <a href="http://nginx.org/en/docs/http/ngx_http_rewrite_module.html#rewrite" rel="nofollow">this document</a> for more.
You can simplify the above further, if you modify the PHP code to accept a leading /
in the fwd
parameter, in which case you could use:
location / {
try_files $uri $uri/ /index.php?fwd=$uri;
}
Answer2:You don't need a rewrite, the whole capture logic can be in the root location itself, e.g:
location ~ \.php$ {
...
}
# using a name variable instead of $1
location ~ ^/(?<short_url>.*)$ {
try_files $uri $uri/ /index.php?fwd=$short_url;
}