rewrite middleware: add subdomain redirect example

This commit is contained in:
Gerasimos (Makis) Maropoulos 2020-08-20 16:34:19 +03:00
parent ffae9c0d09
commit cb80e43ff0
No known key found for this signature in database
GPG Key ID: 5DBE766BD26A54E7
4 changed files with 56 additions and 11 deletions

View File

@ -1,3 +1,4 @@
127.0.0.1 mydomain.com 127.0.0.1 mydomain.com
127.0.0.1 www.mydomain.com 127.0.0.1 www.mydomain.com
127.0.0.1 test.mydomain.com 127.0.0.1 test.mydomain.com
127.0.0.1 newtest.mydomain.com

View File

@ -13,17 +13,22 @@ func main() {
app.Subdomain("test").Get("/", testIndex) app.Subdomain("test").Get("/", testIndex)
newtest := app.Subdomain("newtest")
newtest.Get("/", newTestIndex)
newtest.Get("/", newTestAbout)
redirects := rewrite.Load("redirects.yml") redirects := rewrite.Load("redirects.yml")
app.WrapRouter(redirects) app.WrapRouter(redirects)
// http://mydomain.com:8080/seo/about -> http://www.mydomain.com:8080/about // http://mydomain.com:8080/seo/about -> http://www.mydomain.com:8080/about
// http://test.mydomain.com:8080 // http://test.mydomain.com:8080 -> http://newtest.mydomain.com:8080
// http://localhost:8080/seo -> http://localhost:8080 // http://test.mydomain.com:8080/seo/about -> http://newtest.mydomain.com:8080/about
// http://localhost:8080/seo -> http://localhost:8080
// http://localhost:8080/about // http://localhost:8080/about
// http://localhost:8080/docs/v12/hello -> http://localhost:8080/docs // http://localhost:8080/docs/v12/hello -> http://localhost:8080/docs
// http://localhost:8080/docs/v12some -> http://localhost:8080/docs // http://localhost:8080/docs/v12some -> http://localhost:8080/docs
// http://localhost:8080/oldsome -> http://localhost:8080 // http://localhost:8080/oldsome -> http://localhost:8080
// http://localhost:8080/oldindex/random -> http://localhost:8080 // http://localhost:8080/oldindex/random -> http://localhost:8080
app.Listen(":8080") app.Listen(":8080")
} }
@ -40,7 +45,15 @@ func docs(ctx iris.Context) {
} }
func testIndex(ctx iris.Context) { func testIndex(ctx iris.Context) {
ctx.WriteString("Test Subdomain Index") ctx.WriteString("Test Subdomain Index (This should never be executed, redirects to newtest subdomain)")
}
func newTestIndex(ctx iris.Context) {
ctx.WriteString("New Test Subdomain Index")
}
func newTestAbout(ctx iris.Context) {
ctx.WriteString("New Test Subdomain About")
} }
/* More... /* More...
@ -49,6 +62,7 @@ rewriteOptions := rewrite.Options{
"301 /seo/(.*) /$1", "301 /seo/(.*) /$1",
"301 /docs/v12(.*) /docs", "301 /docs/v12(.*) /docs",
"301 /old(.*) /", "301 /old(.*) /",
"301 ^(http|https)://test.(.*) $1://newtest.$2",
}, },
PrimarySubdomain: "www", PrimarySubdomain: "www",
} }

View File

@ -6,5 +6,7 @@ RedirectMatch:
- 301 /docs/v12(.*) /docs - 301 /docs/v12(.*) /docs
# redirects /old(.*) to / # redirects /old(.*) to /
- 301 /old(.*) / - 301 /old(.*) /
# redirects http or https://test.* to http or https://newtest.*
- 301 ^(http|https)://test.(.*) $1://newtest.$2
# redirects root domain to www. # redirects root domain to www.
PrimarySubdomain: www PrimarySubdomain: www

View File

@ -8,6 +8,7 @@ import (
"regexp" "regexp"
"strconv" "strconv"
"strings" "strings"
"text/template"
"github.com/kataras/iris/v12/context" "github.com/kataras/iris/v12/context"
"github.com/kataras/iris/v12/core/router" "github.com/kataras/iris/v12/core/router"
@ -176,7 +177,8 @@ func (e *Engine) Rewrite(w http.ResponseWriter, r *http.Request, routeHandler ht
for _, rd := range e.redirects { for _, rd := range e.redirects {
src := r.URL.Path src := r.URL.Path
if !rd.isRelativePattern { if !rd.isRelativePattern {
src = r.URL.String() // don't change the request, use a full redirect.
src = context.GetScheme(r) + context.GetHost(r) + r.URL.RequestURI()
} }
if target, ok := rd.matchAndReplace(src); ok { if target, ok := rd.matchAndReplace(src); ok {
@ -185,7 +187,14 @@ func (e *Engine) Rewrite(w http.ResponseWriter, r *http.Request, routeHandler ht
return return
} }
http.Redirect(w, r, target, rd.code) if !rd.isRelativePattern {
// this performs better, no need to check query or host,
// the uri already built.
redirectAbs(w, r, target, rd.code)
} else {
http.Redirect(w, r, target, rd.code)
}
return return
} }
} }
@ -263,3 +272,22 @@ func getPort(hostport string) string { // returns :port, note that this is only
return "" return ""
} }
func redirectAbs(w http.ResponseWriter, r *http.Request, url string, code int) {
// part of net/http std library.
h := w.Header()
_, hadCT := h[context.ContentTypeHeaderKey]
h.Set("Location", url)
if !hadCT && (r.Method == http.MethodGet || r.Method == http.MethodHead) {
h.Set(context.ContentTypeHeaderKey, "text/html; charset=utf-8")
}
w.WriteHeader(code)
// Shouldn't send the body for POST or HEAD; that leaves GET.
if !hadCT && r.Method == "GET" {
body := "<a href=\"" + template.HTMLEscapeString(url) + "\">" + http.StatusText(code) + "</a>.\n"
fmt.Fprintln(w, body)
}
}