Home

Awesome

Rewrite

build status report card godocs

Like Apache mod_rewrite but for Golang's net/http. Initially created for the Iris Web Framework a long time ago. The success of its usefulness is well known as many others have copied and moved the original source code into various frameworks since then, if you deem it necessary, you are free to do the same.

Installation

The only requirement is the Go Programming Language.

$ go get github.com/kataras/rewrite

Examples

Getting Started

The Rewrite Middleware supports rewrite URL path, subdomain or host based on a regular expression search and replace.

The syntax is familiar to the majority of the backend developers out there and it looks like that:

REDIRECT_CODE_DIGITSPATTERN_REGEXTARGET_REPL
301/seo/(.*)/$1

Would redirect all requests from relative path /seo/* to /* using the 301 (Moved Permanently) HTTP Status Code. Learn more about regex.

Usage

First of all, you should import the builtin middleware as follows:

import "github.com/kataras/rewrite"

There are two ways to load rewrite options in order to parse and register the redirect rules:

1. Through code using the New function and Handler method. Parse errors can be handled and rules can be programmatically created.

// 1. Code the redirect rules.
opts := rewrite.Options{
	RedirectMatch: []string{
		"301 /seo/(.*) /$1",
		"301 /docs/v12(.*) /docs",
		"301 /old(.*) /",
	},
	PrimarySubdomain: "www",
}
// 2. Initialize the Rewrite Engine.
rw, err := rewrite.New(opts)
if err != nil { 
	panic(err)
}

// 3. Wrap the router using Engine's Handler method.
http.ListenAndServe(":8080", rw.Handler(mux))

2. Or through a yaml file using the Load function which returns a func(http.Handler) http.Handler. It is the most common scenario and the simplest one. It panics on parse errors.

The "redirects.yml" file looks like that:

RedirectMatch:
  # Redirects /seo/* to /*
  - 301 /seo/(.*) /$1

  # Redirects /docs/v12* to /docs
  - 301 /docs/v12(.*) /docs

  # Redirects /old(.*) to /
  - 301 /old(.*) /

# Redirects root domain requests to www.
PrimarySubdomain: www
func main() {
    mux := http.NewServeMux()
    // [...routes]
	redirects := rewrite.Load("redirects.yml")
	// Wrap the router.
    http.ListenAndServe(":8080", redirects(mux))
}

Example

Let's write a simple application which follows the redirect rules of:

SOURCETARGET
http://localhost:8080/seo/abouthttp://localhost:8080/about
http://mydomain.com:8080/docs/v12/hellohttp://www.mydomain.com:8080/docs
http://mydomain.com:8080/docs/v12somehttp://www.mydomain.com:8080/docs
http://mydomain.com:8080/oldsomehttp://www.mydomain.com:8080
http://mydomain.com:8080/oldindex/randomhttp://www.mydomain.com:8080

Server

package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/kataras/rewrite"
)

func main() {
	// Code the redirect rules.
	opts := rewrite.Options{
		RedirectMatch: []string{
			"301 /seo/(.*) /$1",       // redirect /seo/* to /*
			"301 /docs/v12(.*) /docs", // redirect docs/v12/* to /docs
			"301 /old(.*) /",          // redirect /old** to /
		},
		PrimarySubdomain: "www", // redirect root to www. subdomain.
	}
	// Initialize the Rewrite Engine.
	rw, err := rewrite.New(opts)
	if err != nil {
		log.Fatal(err)
	}

	router := http.NewServeMux()
	router.HandleFunc("/", index)
	router.HandleFunc("/about", about)
	router.HandleFunc("/docs", docs)

	log.Println("Listening on :8080")
	// Wrap the router using the Handler method.
	http.ListenAndServe(":8080", rw.Handler(router))
}

func index(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintln(w, "Index")
}

func about(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintln(w, "About")
}

func docs(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintln(w, "Docs")
}

Hosts File

127.0.0.1	mydomain.com
127.0.0.1	www.mydomain.com

Navigate here if you don't know how to modify the system's hosts file.

License

This software is licensed under the MIT License.