3

What I want is for the first to be turned into the second..

/widget              => /widget/index.php
/widget/             => /widget/index.php
/widget?act=list     => /widget/index.php?act=list
/widget/?act=list    => /widget/index.php?act=list
/widget/list         => /widget/index.php?act=list
/widget/v2?act=list  => /widget/v2.php?act=list
/widget/v2/?act=list => /widget/v2.php?act=list
/widget/v2/list      => /widget/v2.php?act=list

v2 could also be v45, basically "v\d+"
act, "list" in this case, can have many values and more will be added.
Any additional query parameters would just be passed on with $args, I guess.

Basically URLs not specifying the version will go to index.php, which can then decide what specific version file to include. What I am afraid of happening is loops - this should sit in

location /widget {

right?.

(As for putting the version of the API in the URL, I'm not trying to be RESTful, and target audience is small)

Resources on how to do this entirely in index.php using "routers" also welcome :-/

1
  • .. is this question too easy (I should figure it out myself) or too hard?
    – MSpreij
    Aug 14, 2014 at 16:36

2 Answers 2

3

With three rules you can match the example cases and following versions of the widgets:

rewrite ^\/widget\/(v\d+)\/?(\?act=)?(.*)$ /widget/$1.php?act=$2 last;
rewrite ^\/widget\/?$ /widget/index.php last;
rewrite ^\/widget\/?(\?act=)?(.*) /widget/index.php?act=$2 last;

I have written these using a online regexp tester but did not setup a test environment with Nginx.

The first rule will match all cases with a version number, covering with or without a slash and with or without the ?act argument.

The second rule will cover the basic widget call without any arguments, again with and without trailing slash.

The last rule will cover all non-versioned widget calls, covering with or without a slash and with or without the ?act argument.

Order of there last two rules are important.

2
  • aaand I awarded the bounty to the wrong post >.< no idea how /that/ happened, work is making me too tired. Gods of ServerFault, feel free to whatever.
    – MSpreij
    Aug 25, 2014 at 22:57
  • np, just hope the answer was to your satisfaction :)
    – Joffrey
    Aug 26, 2014 at 14:23
2
+50
server {
    ...
    rewrite ^/widget$                   /widget/index.php           last;
    rewrite ^/widget/$                  /widget/index.php           last;
    rewrite ^/widget\?act=list$         /widget/index.php?act=list  last;
    rewrite ^/widget/\?act=list$        /widget/index.php?act=list  last;
    rewrite ^/widget/list$              /widget/index.php?act=list  last;
    rewrite ^/widget/v(\d+)\?act=list$  /widget/v$1.php?act=list    last;
    rewrite ^/widget/v(\d+)/\?act=list$ /widget/v$1.php?act=list    last;
    rewrite ^/widget/v(\d+)/list$       /widget/v$1.php?act=list    last;
    ...
    location /widget {
        ...
    }
}

To match the digits you need a capture group (), this is a regex concept.
The capture group is referenced in the rewrite as $1 which means 'backreference 1'

Although I don't know if this is going to be a sustainable list for you.
For instance, instead of capture ?act=list, why not capture everything, and add it back in the rewrite rule like this:

rewrite ^/widget(.*)         /widget/index.php?$1  last;

I'm not 100% sure on how your URLs will look before the rewrite, so I can't give a comprehensive rule for this.

1
  • "Although I don't know if this is going to be a sustainable list for you." Afraid not :-/ There are many values for act, and more will be added, esp in future versions.
    – MSpreij
    Aug 22, 2014 at 10:27

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .