Rewrites and Redirects

From Training Material
Jump to navigation Jump to search


title
Rewrites and Redirects
author
Sam Bashton (NobleProg Ltd)

Redirects ⌘

  • Content moved, but still want it to be available at another location?
  • Use a redirect
  • Very very common, in part thanks to SEO

Simple redirect ⌘

  • page at `/calzado/` has been moved to `/zapatos/`
  • We need to send a redirect telling all clients it has been permanently moved

302: Found ⌘

  • Used when a document at one URL should in fact be requested via another
  • Server sends back a redirect to the other location
  • Browser makes two requests - one for the initial URL, one for the location given in the reply
  • Browser should not cache this redirect

301: Moved Permanently ⌘

  • Sends back a redirect to the browser with the new HTTP location
  • Browser then makes a second request, to the location given in the reply to the first request
  • Browser can cache this redirect
  • Also obeyed by search engines (Google)

Our shoe redirect ⌘

```
location /calzado {
 rewrite ^ http://localhost:8080/zapatos;
}
```

Testing our redirect ⌘

We can easily test the redirect using `curl`

```
$ curl -I http://localhost/calzado/
HTTP/1.1 302 Moved Temporarily
Server: nginx/1.4.1
Date: Tue, 28 May 2013 13:59:32 GMT
Content-Type: text/html
Content-Length: 160
Connection: keep-alive
Location: http://localhost:8080/zapatos/
```

Changing the 302 to a 301 ⌘

```
location /calzado {
 rewrite ^ http://localhost:8080/zapatos permanent;
}
```

More complex redirects ⌘

  • Now we need to redirect mens and womens shoes
  • We can use both a regex location match and regex rewrite:
```
location ~ /(hombre|mujer)/calzado/ {
 rewrite /(hombre|mujer)/calzado/ http://localhost:8080/$1/zapatos/;
}
```

Test complex redirect ⌘

```
$ curl -I http://localhost/mujer/calzado/
HTTP/1.1 302 Moved Temporarily
Server: nginx/1.4.1
Date: Tue, 28 May 2013 14:20:24 GMT
Content-Type: text/html
Content-Length: 160
Connection: keep-alive
Location: http://localhost:8080/mujer/zapatos/
```

Adding more complexity ⌘

  • We now want our redirect only for the host example.es
  • We can add a conditional
```
location ~ /(hombre|mujer)/calzado/ {
 if ($host = "example.es") {
   rewrite /(hombre|mujer)/calzado/ http://localhost:8080/$1/zapatos/;
 }
}
```

Testing if ⌘

```
$ curl -I http://localhost/mujer/calzado/
HTTP/1.1 404 Not Found
Server: nginx/1.4.1
Date: Tue, 28 May 2013 14:38:59 GMT
Content-Type: text/html
Content-Length: 168
Connection: keep-alive
$ curl -I http://example.es/mujer/calzado/
HTTP/1.1 302 Moved Temporarily
Server: nginx/1.4.1
Date: Tue, 28 May 2013 14:39:04 GMT
Content-Type: text/html
Content-Length: 160
Connection: keep-alive
Location: http://localhost:8080/mujer/zapatos/
```
=== Rewrites ⌘===
  • Much the same as redirects, but done server side
  • No visibility to the end user

Rewrite example

  • Requests for `/en/shoes/` should be fulfilled by the content in the
 `/zapatos/` directory
```
location / {
 root /usr/share/nginx/html;
 index index.html index.html;
 rewrite /en/shoes/ /zapatos/;
}
```

try_files ⌘

  • One common pattern is for rewrites to be used only if a file
 of the corresponding name doesn't exist on disk
  • For example, everything should be handled by index.php, with the path
 passed as a query string
```

location / {

  root /usr/share/nginx/html;
 index index.php;
 try_files $uri $uri/ /index.php?q=$uri;
}
```

Exercise ⌘

  • Implement serving of /extra/ from /usr/share/doc/HTML using a rewrite
  • Make requests to /foo/ send a permanent redirect to /extra/