nginx rewrite rule php melody - .htaccess

I am using nginx. I want to rewrite urls. My code:
rewrite ^/([^/]*)_([a-zA-Z0-9]{9}).html$ /watch.php?vid=$2 last;
Example of url:
http://104.238.130.170/hudson-against-the-grain-video_14a4e06f8.html
But when I save file then restarts nginx server i got error:
[emerg] directive "rewrite" is not terminated by ";" in /etc/nginx/conf.d/default.conf:46
QUESTION: What is wrong on my rewrite rule?
rewrite ^/([^/]*)_([a-zA-Z0-9]{9}).html$ /watch.php?vid=$2 last;

The curly brackets {9}are most likely giving a problem in your regex. Surround the rule with quotes like below and try it.
rewrite "^/([^/]*)_([a-zA-Z0-9]{9}).html$" /watch.php?vid=$2 last;
Note: for curly braces( { and } ), as they are used both in regexes
and for block control, to avoid conflicts, regexes with curly braces
are to be enclosed with double quotes (or single quotes).
More info here

Related

nginx regex redirect gives extra slash

I plan to convert this address:
www.somewebsite.com/news/22915
To this address:
www.somewebsite.com/news/22915.html
And this is how I do it in my nginx configuration:
rewrite ^/news/(\d+)$ /news/$1\.html redirect;
But somehow, nginx will rewrite my address to:
www.somewebsite.com/news/22915/.html
Had no idea why / will go into the variable automatically, since (\d+) should only be matching pure numbers, need help.
Use rewrite ^/news/(\d+)$ /news/$1.html redirect;
The second part of the rewrite syntax is not a regex. So you should not try to escape the dot character.

.htaccess redirect; How to copy value?

I've the following in .htaccess:
RedirectMatch 301 /Search/[my_value]/m(.*) /Search?city=[my_value]
[my_value] is always the same in both URLs. How can I also copy [my_value] from the first URL to the other URL?
Just use the placeholder reference as documented in the alias module:
RedirectMatch 301 ^/?Search/([^/]+)/m(.*)$ /Search?city=$1
Or you can instead use a simple rewriting rule as offered by the rewriting module:
RewriteEngine on
RewriteRule ^/?Search/([^/]+)/m(.*)$ /Search?city=$1 [R=301]
Both approaches can be used in the http servers host configuration, or, if really required, in dynamic configuration files (.htaccess style files). You should however definitely prefer the first option.
You really should start to read the documentation of the tools you use. Your question is answered in there:
Alias module: https://httpd.apache.org/docs/current/mod/mod_alias.html#redirectmatch
Rewrite Module: http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewriterule
RedirectMatch uses Regular Expressions
This directive is equivalent to Redirect, but makes use of regular expressions, instead of simple prefix matching.
The supplied regular expression is matched against the URL-path, and if it matches, the server will substitute any parenthesized matches into the given string and use it as a filename.
This means, to capture part of the request, you must put it in parenthesis (...), and then use this as $1, $2, etc. in the target URL.
As #arkascha already has shown, to use [my_value], you capture it with (.+?) and add it in the target as city=$1. The second part m(.*)$ could be used as $2. But if you don't need it in the target, you can just remove the parenthesis and say m.*$, e.g.
RedirectMatch ^/Search/(.+?)/m.*$ /Search?city=$1
When everything works as it should, you may change the status code to 301. Never test with 301.

Nginx config rewrite rule combination

So I have these 2 rules for url rewrites.
location ~ /details {
rewrite ^/details/(.*)/(.*)/(.*)/(.*)_(.*).html$ /site/$4.$5.html permanent;
rewrite ^/details/(.*)/(.*)/(.*)/(.*)_(.*)_(.*).html$ /site/$4.$5.$6.html permanent;
}
But for some reason the first one on its own works just fine but the second one will not pick up.
Is there a way I could combine these 2 rules into 1?
Thanks for any suggestions.
Try switching the order:
location ~ /details {
rewrite ^/details/(.*)/(.*)/(.*)/(.*)_(.*)_(.*).html$ /site/$4.$5.$6.html permanent;
rewrite ^/details/(.*)/(.*)/(.*)/(.*)_(.*).html$ /site/$4.$5.html permanent;
}
Because (.*) matches everything, it'll gobble up everything including _ characters, so your first regex matches everything the second one does and thus the second rule never gets reached.

.htaccess rewrite /files/users/1/file.pdf to /view/?file=file.pdf

I am terrible with mod_rewrite however I need to rewrite any request to the folder /files/users/*/ (* is a wildcard) to /view/ and insert the filename into a query paramater like so:
/files/users/9/test.pdf becomes /view/?file=test.pdf
How would I go about this assuming that the .htaccess file will be located inside /files/users/?
I would really appreciate if you explained how your solution works as I am slowly trying to become familiar with mod_rewrite.
So, you wanna have all my trade secrets on a silver plate?
Well, I try my best. ;-)
First of all, you must know where the documentation is. Look here for the reference: mod_rewrite. Or mod_rewrite, if your Apache version is 2.2.
You will find an overview with lots of links at Apache mod_rewrite. There, you will find a nice introduction to rewriting URLs. Also look here for lots of standard examples.
Since mod_rewrite supports PCRE regular expressions, you might need perlre and/or regular-expression.info from time to time.
Now to your question
RewriteEngine On
RewriteRule ^(?:.+?)/(.*) /view/?file=$1
This might already be sufficient. It looks for a subdirectory (?:.+?) in /files/users and captures the name of a file (.*) in this subdirectory. If this pattern matches, it rewrites the URL to /view/?file= and appends the captured file with $1, which gives /view/?file=$1.
All untested, of course, have fun.
P.S. Additional info is here at SO at .htaccess info and .htaccess faq.
Put the directive below in your .htaccess file to rewrite /files/users/9/test.pdf to /view/?file=test.pdf. In practical terms this means that if you visit http://yourdomain.com/files/users/9/test.pdf then the visitor will be served the rewritten url which is http://yourdomain.com/view?file=test.pdf
RewriteRule ^[^/]+/(.*)$ /view/?file=$1 [L]
A RewriteRule directive is part of the Apache mod_rewrite module. It takes two arguments:
Pattern - a regular expression to match against the current URL path (note that the URL path is not the entire URL but eg. /my/path, but in a .htaccess context the leading slash / is stripped giving us my/path).
Substitution - the destination URL or path where the user will rewritten OR redirected to.
Explaining the rule
The pattern ^[^/]+/(.*)$:
^ - the regex must match from the start of the string
[^/] - match everything but forward slash
+ - repetition operator which means: match 1 or more characters
/ - matches a forward slash
(.*) - mathes any characters. The dot means match any character. The star operator means match ANY characters (0 or more). The parantheses means the match is grouped and can be used in backreferences.
$ - the regex must match until the end of the string
The substitution /view/?file=$1:
...means that we rewrite the URL path to the /view/ folder with the query parameter file. The query parameter file will contain our first grouped match from the pattern as we pass it the $1 value (which means the first match from our RewriteRule pattern).
The [L] flag:
...means that mod_rewrite will stop processing rewrite rules. This is handy to avoid unwanted behaviour and/or infinite loops.

Remove parameters within nginx rewrite

I'm rewriting URLs in nginx after a relaunch. In the old site I had query parameters in the URL to filter stuff e.g.
http://www.example.com/mypage.php?type=4
The new page doesn't have these kind of parameters. I want to remove them and rewrite the URLs to the main page, so that I get:
http://www.example.com/mypage/
My rewrite rule in nginx is:
location ^~ /mypage.php {
rewrite ^/mypage.php$ http://www.example.com/mypage permanent;
}
But with this rule the parameter is still appended. I thought the $ would stop nginx from processing further values... any ideas? All other questions deal with how to add parameters - I just want to remove mine :)
Had a similar problem, after a lot of searching the answer presented itself in the rewrite docs.
If you specify a ? at the end of a rewrite then Nginx will drop the original $args (arguments)
So for your example, this would do the trick:
location ^~ /mypage.php {
rewrite ^/mypage.php$ http://www.example.com/mypage? permanent;
}
To drop a parameter from a URL, in this case coupon=xxx:
if ($query_string ~ "^(.*)coupon=(.*)$") {
rewrite ^(.*)$ $uri? permanent;
}
Note that this will drop all parameters if the
statement matches. $uri is the original request without parameters.
Try setting the $args variable to empty inside the location.
set $args '';
If you want to remove a specified parameter from url,
# in location directive:
if ($request_uri ~ "([^\?]*)\?(.*)unwanted=([^&]*)&?(.*)") {
set $original_path $1;
set $args1 $2;
set $unwanted $3;
set $args2 $4;
set $args "";
rewrite ^ "${original_path}?${args1}${args2}" permanent;
}
then visit your_site.com/a=1&unwanted=2&c=3
step1. server gives an 302 response, indicating the url is match.
step2. client re-send a request with the new url ( with the parameter removed)
If we append a ? to the end of the destination it will prevent the query from being appended to the destination. :)
Example
Source
Args
Destination
Keep the arg appended
rewrite ^/mypage.php$
arg=something
https://example.com/new-page/
Do not preserve the arg
rewrite ^/mypage.php$
arg=something
https://example.com/new-page/?

Resources