How can I match the following in Nginx - nginx

Dear StackOverflow Population,
I have been trying to get two simple things to work but I can't get but 1 of them to.
So I have nginx server block it looks like the following
server {
listen 443 default;
server_name secure.<domain>.com;
if ($host = $server_name) {
rewrite ^(.*) https://secure.<domain2>.com$request_uri?systpl=<template> permanent;
}
I have also tried since I know that IF is evil I have tried something like
return 301 https://secure.<domain2>.com$request_uri?systpl=<template>;
of course then I disable the if statement above, this works okay so when we goto
https://secure.domain.com => https://secure.domain2.com/?systpl=template
That works fine and when you enter a PHP ending such as
https://secure.domain.com/cart.php => https://secure.domain2.com/cart.php?systpl=template
This works both with IF and simple return, and I figure I need to get the other in a different server block or a statement but here is where the problem lies
Now if you goto
https://secure.domain.com/cart.php?id=7 => https://secure.domain2.com/cart.php?id=7?systpl=template
This of course doesn't work since it would have to be &systpl since it doesn't end with .php, how can I achieve this so it appends &systpl if it does not end with .php and ends with string and if not then append it with ?systpl if it ends with .php
I hope someone knows how this is done because I have crawled the first 6 pages of google results with various search strings.

If you are adding arguments, you should probably avoid using $request_uri and use $uri and $args instead.
The return statement could be rewritten as:
return 301 https://example.com$uri?systpl=template&$args;
The rewrite directive appends arguments by default, so this should work:
rewrite ^ https://example.com$uri?systpl=template permanent;
But as it is identical to the return statement, the return statement is preferred. See this document for details.

Related

Rename args in nginx redirect

I am trying to get an NGINX redirect to take me from:
https://example.com/ui/?outletID=123&setID=456
to:
https://example.com/ui/?outletId=123&setIds=456
So outletID -> outletId AND setID -> setIds
IMPORTANT: I don't know where these params appear inside the URL, so there might be other strings before or after these. I only care for this replacements: outletID -> outletId; setID -> setIds.
This works at first try:
if ($args ~* "^outletID=(\d+)&setID=(\d+)(.*)") {
set $outletid $1;
set $setid $2;
set $everythingelse $3;
set $args '';
rewrite ^.*$ /ui/?outletId=$outletid&setIds=$setid$everythingelse permanent;
}
But it looks like really bad practice and I particularly hate the $everythingelse ($3) solution I ended up with.
To cover all possibilities, you probably need to do this in two stages, one redirect if outletID is present, and another redirect if setID is present.
For example:
if ($args ~ ^(.+&|)outletID(=.*)$) {
return 301 "$uri?${1}outletId$2";
}
if ($args ~ ^(.+&|)setID(=.*)$) {
return 301 "$uri?${1}setIds$2";
}
Per Nginx documentation,
If a replacement string includes the new request arguments, the
previous request arguments are appended after them.
So, in case you don't mind having old outletID and setID hanging around, you could simply do:
rewrite (.*) $1?outletId=$arg_outletID&setIds=$arg_setID permanent;
This way, you'll get something like https://example.com/ui/?outletId=123&setIds=456&outletID=123&setID=456.
But if you would like to have the URLs clean after redirection, Nginx has you covered as well. The excerpt from the same documentation:
If this is undesired, putting a question mark at the end of a replacement string avoids having them appended
Which means, you have to enumerate all the parameters you need to pass. For example, if you have some another possible parameter in query string session, you'll need to include it:
rewrite (.*) $1?outletId=$arg_outletID&setIds=$arg_setID&session=$arg_session? permanent;
Note the ? in the end of replacement string.
Personally I would choose the first approach, because it is less error-prone and will not break your application unexpectedly at the time you added a new parameter.

How to block a specific URL in NGINX webserver

I want to block a specific URL but I am not able to do this.
The URL that should be blocked is example.com/clientarea/?dxx_g=dddd.
But the following url should still work - example.com/clientarea.
I tried the following:
location ^~ /clientarea/ {
return 444;
}
But if I do this it will block all connections to /clientarea.
I hope you can help me or advise me how to make this possible.
The location and rewrite statements test a normalized URI which does not include the ? and anything following it.
The $request_uri variable contains the entire URI. Test this variable using an if or map directive.
For example:
if ($request_uri = /clientarea/?dxx_g=dddd) {
return 444;
}
You can also use regular expressions. See this document for more. See this caution on the use of if.
If you have a number of URIs to block, you should consider using a map instead.

Rewrites in Nginx

I need to enter a bunch or rewrites in my conf file in Nginx. I am not very experienced so I copied what I found before, example.
location = /index.php/blog/blog/xxx/yyy/ {
return 301 /index.php/blog/xxx/yyy/;
}
However I was told that the best way is the following:
location ^~ /index.php/blog/blog/xxx/yyy/ {
rewrite ^/index.php/blog/xxx/yyy/;
}
Which one id the correct one?
The first one is more correct, both location as well as the return -wise, and it'll work faster.
FWIIW, your second snippet looks like it's missing a space in the rewrite after ^, and it's also less efficient, both location as well as rewrite-wise.
References:
http://nginx.org/r/location
http://nginx.org/r/return
http://nginx.org/r/rewrite

Nginx rewrite to css factory

I have a rule which is not working correctly.
I need it so that whenever URL xxx.com/forum/css.php is hit, it is re-written to xxx.com/forum/core/css.php.
I have written the following location block for it:
location ~^ /forum/css.php {
rewrite ^ /forum/core/css.php permanent;
}
Also needing to be taken into account is that the file is a factory so it accepts parameters, the url being hit actually looks like xxx.com/forum/css.php?x=123&y=string. Will this also be taken into account in the re-writes or does it need to be specified? Sorry if the question seems silly I am just beginning to work with servers! Thanks fellow coders!
To rewrite a single URI (with or without query string) you could use a location =:
location = /forum/css.php {
rewrite ^ /forum/core/css.php permanent;
}
The rewrite directive appends the query string (unless terminated with ?). See this and this for more.

Nginx Rewrite Issue to External link

I'm trying to set up a permanent redirect from
http://domain.com/member/blog_post_view.php?postId=1
to
http://blog.domain.com/friendly-url-here
The source URL contains both a ? and an = which I think might be the cause but am unsure.
I've tried all sorts of nginx suggestiosn including the one below but can't seem to get the redirection to work and hoped someone can point me in the right direction.
location /blog_post_view.php?postId=1 {
rewrite "/blog_post_view.php\?postId\=1" http://blog.domain.com/friendly-url-here permanent;
}
That part of request line starting from the question mark is called query string, while the location directive matches only path part of URI.
You should use $arg_* variable instead:
location =/blog_post_view.php {
if ($arg_postId = 1) {
return 301 http://blog.domain.com/friendly-url-here;
}
}
Reference:
http://nginx.org/r/location
http://nginx.org/r/if
Embedded Variables

Resources