HTTP redirects are a method for web servers to direct clients from one url to another. These can be used for temporarily handling errors / downtime, redirecting http to https, migrating from one domain to another, changing url schemes, etc. In its simplest form a HTTP redirect is a combination of a status code and the Location header. We will create some common HTTP redirects with Undertow.

Redirect Example

We will be working with the following web server containing a few simple routes to demonstrate each type of redirect.

public static void hello(HttpServerExchange exchange) {
    Exchange.body().sendText(exchange, "Hello");
}

public static void temporaryRedirect(HttpServerExchange exchange) {
    Exchange.redirect().temporary(exchange, "/hello");
}

public static void permanentRedirect(HttpServerExchange exchange) {
    Exchange.redirect().permanent(exchange, "/hello");
}

public static void referrerRedirect(HttpServerExchange exchange) {
    Exchange.redirect().referer(exchange);
}

private static final HttpHandler ROUTES = new RoutingHandler()
    .get("/hello", RedirectServer::hello)
    .get("/temporaryRedirect", RedirectServer::temporaryRedirect)
    .get("/permanentRedirect", RedirectServer::permanentRedirect)
    .get("/referrerRedirect", RedirectServer::referrerRedirect)
;

public static void main(String[] args) {
    SimpleServer server = SimpleServer.simpleServer(ROUTES);
    server.start();
}

Hello Handler

All endpoints will redirect to the hello handler which simply outputs the text Hello.

curl 127.0.0.1:8080/hello
Hello

Temporary Redirect (302)

The temporary redirect is one of the most commonly used redirects and as it's name states it is meant to be temporary. There are many applications of the temporary redirect. Some common uses are redirecting to error pages, redirecting you back to your previous page after a form submission, and redirecting unauthenticated users to a login page.

default void temporary(HttpServerExchange exchange, String location) {
    exchange.setStatusCode(StatusCodes.FOUND);
    exchange.getResponseHeaders().put(Headers.LOCATION, location);
    exchange.endExchange();
}
curl -v -L 127.0.0.1:8080/temporaryRedirect
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
> GET /temporaryRedirect HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/7.49.1
> Accept: */*
>
< HTTP/1.1 302 Found
< Connection: keep-alive
< Location: /hello
< Content-Length: 0
< Date: Tue, 17 Jan 2017 02:22:02 GMT
<
* Connection #0 to host 127.0.0.1 left intact
* Issue another request to this URL: 'http://127.0.0.1:8080/hello'
* Found bundle for host 127.0.0.1: 0x7fb928d0c260 [can pipeline]
* Re-using existing connection! (#0) with host 127.0.0.1
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
> GET /hello HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/7.49.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Connection: keep-alive
< Content-Type: text/plain
< Content-Length: 5
< Date: Tue, 17 Jan 2017 02:22:02 GMT

Permanent Redirect (301)

The permanent redirect works very similarly to the temporary redirect with the added implication that this redirect is permanent. This implication can be used by clients in various ways. One of the most common is web crawlers updating their indexes based on 301s. If you decide to update your domain name, redirect from http to https, or change your url scheme, the 301 redirect allows you to keep your old links active but tell the crawlers they should start using the new link instead. This is one of the primary ways to make sure Google starts listing your results under the new urls.

default void permanent(HttpServerExchange exchange, String location) {
    exchange.setStatusCode(StatusCodes.MOVED_PERMANENTLY);
    exchange.getResponseHeaders().put(Headers.LOCATION, location);
    exchange.endExchange();
}
curl -v -L 127.0.0.1:8080/permanentRedirect
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
> GET /permanentRedirect HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/7.49.1
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
< Connection: keep-alive
< Location: /hello
< Content-Length: 0
< Date: Tue, 17 Jan 2017 02:22:23 GMT
<
* Connection #0 to host 127.0.0.1 left intact
* Issue another request to this URL: 'http://127.0.0.1:8080/hello'
* Found bundle for host 127.0.0.1: 0x7ff89940c370 [can pipeline]
* Re-using existing connection! (#0) with host 127.0.0.1
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
> GET /hello HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/7.49.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Connection: keep-alive
< Content-Type: text/plain
< Content-Length: 5
< Date: Tue, 17 Jan 2017 02:22:23 GMT

Referrer Redirect Helper

Although server side rendered websites are becoming less popular and being replaced by single page apps they are still a great tool for many use cases. In server side rendered web pages many actions trigger form POST requests which then need to redirect the user to another page when it completes. This is a helper intended to dynamically redirect back to the page the request was made from based on the Referer header. Yes the Referer header was misspelled in the HTTP spec and has stuck around that way.

default void referer(HttpServerExchange exchange) {
    exchange.setStatusCode(StatusCodes.FOUND);
    exchange.getResponseHeaders().put(Headers.LOCATION, exchange.getRequestHeaders().get(Headers.REFERER, 0));
    exchange.endExchange();
}
curl -v -L --referer 'http://www.google.com' 127.0.0.1:8080/referrerRedirect
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
> GET /referrerRedirect HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/7.49.1
> Accept: */*
> Referer: http://www.google.com
>
< HTTP/1.1 302 Found
< Connection: keep-alive
< Location: http://www.google.com
< Content-Length: 0
< Date: Tue, 17 Jan 2017 02:23:35 GMT
<
* Connection #0 to host 127.0.0.1 left intact
* Issue another request to this URL: 'http://www.google.com'
* Rebuilt URL to: http://www.google.com/
*   Trying 216.58.193.132...
* Connected to www.google.com (216.58.193.132) port 80 (#1)
> GET / HTTP/1.1
> Host: www.google.com
> User-Agent: curl/7.49.1
> Accept: */*
> Referer: http://www.google.com
>
< HTTP/1.1 200 OK