I'm trying to get rid of parameter "?status=OK" fom the url below.
Current:
https://example.com/download/d2e9cc4f-f7df-4ebd-a0e4-7836c8013075?status=OK
Goal:
https://example.com/download/d2e9cc4f-f7df-4ebd-a0e4-7836c8013075
Nginx:
location /download/ {
rewrite ^(/download/.*)?$ $1 permanent;
}
Unfortunately the above doesn't work.
The query string is not part of the normalized URI used by location and rewrite statements to test the regular expression.
You can check for the presence of any argument with if ($args) { ... } or only check for the presence of the status= argument with if ($arg_status) { ... }.
For example:
location /download/ {
if ($args) { return 301 $uri; }
... # do something with the corrected URI
}
The rewrite statement is also capable of removing the query string with rewrite ^(.*)$ $1? permanent, but the return statement seems simpler. See this caution on the use of if.
Related
I am trying to build a rewrite for CDN system which uses arguments to point to the data. All data is stored in the same location so any rewrite needs to wildcard rewrite the $arg_name and then pass the value for the data along. Turning this:
http://cdn.example.com/data/?main_loc=datastring
into this:
http://example.com/datastore/datastring
Using a location directive I can fetch the request to /data/, but from there I don't know what the rewrite would need to look like to do a "match any arg name" like main_loc, backup_loc etc. to pass its value as rewrite.
Can I apply regex to match any $arg_name and use the value from that?
location ^~ /data/ {
rewrite ^$arg_(\w*\_\w*)$ http://example.com/datastore/$1;
}
Or what would that look like?
You could capture the arg value with the following map:
map $args $arg_value {
~=(.*) $1;
}
Then redirect to it:
location = /data/ {
return 301 http://example.com/datastore/$arg_value;
}
I want to download any file from the host whose last address had the x-oss-process parameter.
i.php?path=$1&x-oss-process=%1
Refer that $1 is the address of the referenced file and %1 is the value of the x-oss-process parameter
Like the link below
https://dl.example.com/img/all/235868.jpg?x-oss-process=image/resize,m_lfit,h_200,w_200/quality,q_60
After referring this address to the following address
i.php?path=img/all/235868.jpg&x-oss-process=image/resize,m_lfit,h_200,w_200/quality,q_60
Now how do I write the nginx code to do this? Thank you for your help.
If the query argument name didn't contain any dash characters, like x_oss_process instead of x-oss-process, the solution would be much more simple. In that case we could check $arg_x_oss_process variable (see $arg_name variable description):
if ($arg_x_oss_process) {
rewrite ^ /i.php?path=$uri;
}
The first parameter ^ is a regex that matches any string, $uri is a normalized request URI (without query arguments). All the query arguments would be added to the rewrited URI (see the rewrite directive description):
If a replacement string includes the new request arguments, the previous request arguments are appended after them. If this is undesired, putting a question mark at the end of a replacement string avoids having them appended, for example:
rewrite ^/users/(.*)$ /show?user=$1? last;
However since your query argument name contain dashes, the solution will be more complex (see this SO question for additional details). We would need to get the x-oss-process query argument value from $args variable using the map directive which shoud be placed outside the server block:
map $args $x_oss_process {
~(?:^|&)x-oss-process=([^&]*) $1;
}
server {
...
if ($x_oss_process) {
rewrite ^ /i.php?path=$uri;
}
...
}
This rewrite rule will rewrite
/img/all/235868.jpg?x-oss-process=image/resize,m_lfit,h_200,w_200/quality,q_60
request to the
/i.php?path=/img/all/235868.jpg&x-oss-process=image/resize,m_lfit,h_200,w_200/quality,q_60
This is slighly different from what you've been asked for (note the slash before img/all/235868.jpg URI part). I'd rather change i.php script to correctly process this, but if you want to strip this slash with nginx itself, you can use second map block:
map $args $x_oss_process {
~(?:^|&)x-oss-process=([^&]*) $1;
}
map $uri $truncated_uri {
~/(.*) $1;
}
server {
...
if ($x_oss_process) {
rewrite ^ /i.php?path=$truncated_uri;
}
...
}
I'm trying to create an nginx rewrite that will rewrite /pagename to /pagename/
I've tried using:
location ~ "^/test$" {
rewrite /test /test/ break;
}
but that doesn't seem to work...
any help would be appreciated.
The first parameter of a rewrite statement is a regular expression, and the flag you should use is probably permanent (see this document for details), for example:
location ~ "^/test$" {
rewrite ^(/test)$ $1/ permanent;
}
But you do not need to match the regular expression twice, once in the location and again in the rewrite, so a return would be more efficient, for example:
location ~ "^(/test)$" {
return 301 $1/$is_args$args;
}
Also, the location matches a single URI, to the = operator would be better than a regular expression (see this document for details). So the preferred solution is:
location = /test {
return 301 $uri/$is_args$args;
}
I ended up using return:
return 301 /test/;
I want to redirect all /filename.xml files to /filename.
I can redirect an individual file like this
location = /mascus-export.xml {
rewrite .* /mascus-export redirect;
}
but rather than listing each .xml file like individually, I want redirect all. Something like this:
location = /*.xml {
rewrite .* /* redirect;
}
I've tried this type of thing in every combination
location = /(*)$.xml {
rewrite .* /$1 redirect;
}
but nothing seems to work.
You are trying to write a regular expression location block, which begins with ~ and not =. See this document for details.
For example:
location ~ \.xml$ { ... }
The rewrite needs to capture part of the URI using parentheses. For example:
rewrite ^(.*)\.xml$ $1 redirect;
The rewrite will work perfectly well either enclosed within the above location block, or just naked within the enclosing server block.
If you are going to use a regular expression location block, you do not need to use a rewrite statement too. Use a return statement instead. For example:
location ~ ^(.*)\.xml$ {
return 302 $1;
}
When user visits:
/profile.php?mode=viewprofile&u=[NUMBER FROM 1 TO 4000]
I want nginx to return:
/memberlist.php?mode=viewprofile&u=[SAME NUMBER]
How can I do it? Thank you for help.
The problem is that you need to match /profile.php and mode=viewprofile which is not trivial nginx. There are a number of ways to achieve it.
You could replicate the location ~\.php$ block and add the conditional redirection there:
location = /profile.php {
if ($arg_mode = viewprofile) {
return 301 /memberlist.php?$args;
}
... # add location ~\.php$ stuff here
}
Alternatively, check the $request_uri (which contains the original URI including query string), early in the server block:
if ($request_uri ~ "^/profile\.php\?mode=viewprofile&") {
return 301 /memberlist.php?$args;
}
See this caution on the use of the if statement.