mirror of
https://github.com/caddyserver/caddy.git
synced 2025-01-09 04:18:50 +03:00
Merge pull request #479 from abiosoft/rewrite-patch
rewrite: not_has, not_match, multiple to, and status codes
This commit is contained in:
commit
5f6a0a4c0b
7 changed files with 178 additions and 29 deletions
|
@ -2,6 +2,7 @@ package setup
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/mholt/caddy/middleware"
|
"github.com/mholt/caddy/middleware"
|
||||||
|
@ -33,6 +34,7 @@ func rewriteParse(c *Controller) ([]rewrite.Rule, error) {
|
||||||
var err error
|
var err error
|
||||||
var base = "/"
|
var base = "/"
|
||||||
var pattern, to string
|
var pattern, to string
|
||||||
|
var status int
|
||||||
var ext []string
|
var ext []string
|
||||||
|
|
||||||
args := c.RemainingArgs()
|
args := c.RemainingArgs()
|
||||||
|
@ -40,9 +42,6 @@ func rewriteParse(c *Controller) ([]rewrite.Rule, error) {
|
||||||
var ifs []rewrite.If
|
var ifs []rewrite.If
|
||||||
|
|
||||||
switch len(args) {
|
switch len(args) {
|
||||||
case 2:
|
|
||||||
rule = rewrite.NewSimpleRule(args[0], args[1])
|
|
||||||
simpleRules = append(simpleRules, rule)
|
|
||||||
case 1:
|
case 1:
|
||||||
base = args[0]
|
base = args[0]
|
||||||
fallthrough
|
fallthrough
|
||||||
|
@ -76,20 +75,31 @@ func rewriteParse(c *Controller) ([]rewrite.Rule, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
ifs = append(ifs, ifCond)
|
ifs = append(ifs, ifCond)
|
||||||
|
case "status":
|
||||||
|
if !c.NextArg() {
|
||||||
|
return nil, c.ArgErr()
|
||||||
|
}
|
||||||
|
status, _ = strconv.Atoi(c.Val())
|
||||||
|
if status < 400 || status > 499 {
|
||||||
|
return nil, c.Err("status must be 4xx")
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return nil, c.ArgErr()
|
return nil, c.ArgErr()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ensure to is specified
|
// ensure to or status is specified
|
||||||
if to == "" {
|
if to == "" && status == 0 {
|
||||||
return nil, c.ArgErr()
|
return nil, c.ArgErr()
|
||||||
}
|
}
|
||||||
if rule, err = rewrite.NewComplexRule(base, pattern, to, ext, ifs); err != nil {
|
if rule, err = rewrite.NewComplexRule(base, pattern, to, status, ext, ifs); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
regexpRules = append(regexpRules, rule)
|
regexpRules = append(regexpRules, rule)
|
||||||
|
|
||||||
|
// the only unhandled case is 2 and above
|
||||||
default:
|
default:
|
||||||
return nil, c.ArgErr()
|
rule = rewrite.NewSimpleRule(args[0], strings.Join(args[1:], " "))
|
||||||
|
simpleRules = append(simpleRules, rule)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,8 +50,8 @@ func TestRewriteParse(t *testing.T) {
|
||||||
}},
|
}},
|
||||||
{`rewrite a`, true, []rewrite.Rule{}},
|
{`rewrite a`, true, []rewrite.Rule{}},
|
||||||
{`rewrite`, true, []rewrite.Rule{}},
|
{`rewrite`, true, []rewrite.Rule{}},
|
||||||
{`rewrite a b c`, true, []rewrite.Rule{
|
{`rewrite a b c`, false, []rewrite.Rule{
|
||||||
rewrite.SimpleRule{From: "a", To: "b"},
|
rewrite.SimpleRule{From: "a", To: "b c"},
|
||||||
}},
|
}},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,6 +137,33 @@ func TestRewriteParse(t *testing.T) {
|
||||||
}`, false, []rewrite.Rule{
|
}`, false, []rewrite.Rule{
|
||||||
&rewrite.ComplexRule{Base: "/", To: "/to", Ifs: []rewrite.If{rewrite.If{A: "{path}", Operator: "is", B: "a"}}},
|
&rewrite.ComplexRule{Base: "/", To: "/to", Ifs: []rewrite.If{rewrite.If{A: "{path}", Operator: "is", B: "a"}}},
|
||||||
}},
|
}},
|
||||||
|
{`rewrite {
|
||||||
|
status 400
|
||||||
|
}`, false, []rewrite.Rule{
|
||||||
|
&rewrite.ComplexRule{Base: "/", Regexp: regexp.MustCompile(".*"), Status: 400},
|
||||||
|
}},
|
||||||
|
{`rewrite {
|
||||||
|
to /to
|
||||||
|
status 400
|
||||||
|
}`, false, []rewrite.Rule{
|
||||||
|
&rewrite.ComplexRule{Base: "/", To: "/to", Regexp: regexp.MustCompile(".*"), Status: 400},
|
||||||
|
}},
|
||||||
|
{`rewrite {
|
||||||
|
status 399
|
||||||
|
}`, true, []rewrite.Rule{
|
||||||
|
&rewrite.ComplexRule{},
|
||||||
|
}},
|
||||||
|
{`rewrite {
|
||||||
|
status 0
|
||||||
|
}`, true, []rewrite.Rule{
|
||||||
|
&rewrite.ComplexRule{},
|
||||||
|
}},
|
||||||
|
{`rewrite {
|
||||||
|
to /to
|
||||||
|
status 0
|
||||||
|
}`, true, []rewrite.Rule{
|
||||||
|
&rewrite.ComplexRule{},
|
||||||
|
}},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, test := range regexpTests {
|
for i, test := range regexpTests {
|
||||||
|
|
|
@ -14,9 +14,11 @@ const (
|
||||||
Is = "is"
|
Is = "is"
|
||||||
Not = "not"
|
Not = "not"
|
||||||
Has = "has"
|
Has = "has"
|
||||||
|
NotHas = "not_has"
|
||||||
StartsWith = "starts_with"
|
StartsWith = "starts_with"
|
||||||
EndsWith = "ends_with"
|
EndsWith = "ends_with"
|
||||||
Match = "match"
|
Match = "match"
|
||||||
|
NotMatch = "not_match"
|
||||||
)
|
)
|
||||||
|
|
||||||
func operatorError(operator string) error {
|
func operatorError(operator string) error {
|
||||||
|
@ -34,9 +36,11 @@ var conditions = map[string]condition{
|
||||||
Is: isFunc,
|
Is: isFunc,
|
||||||
Not: notFunc,
|
Not: notFunc,
|
||||||
Has: hasFunc,
|
Has: hasFunc,
|
||||||
|
NotHas: notHasFunc,
|
||||||
StartsWith: startsWithFunc,
|
StartsWith: startsWithFunc,
|
||||||
EndsWith: endsWithFunc,
|
EndsWith: endsWithFunc,
|
||||||
Match: matchFunc,
|
Match: matchFunc,
|
||||||
|
NotMatch: notMatchFunc,
|
||||||
}
|
}
|
||||||
|
|
||||||
// isFunc is condition for Is operator.
|
// isFunc is condition for Is operator.
|
||||||
|
@ -57,6 +61,12 @@ func hasFunc(a, b string) bool {
|
||||||
return strings.Contains(a, b)
|
return strings.Contains(a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// notHasFunc is condition for NotHas operator.
|
||||||
|
// It checks if b is not a substring of a.
|
||||||
|
func notHasFunc(a, b string) bool {
|
||||||
|
return !strings.Contains(a, b)
|
||||||
|
}
|
||||||
|
|
||||||
// startsWithFunc is condition for StartsWith operator.
|
// startsWithFunc is condition for StartsWith operator.
|
||||||
// It checks if b is a prefix of a.
|
// It checks if b is a prefix of a.
|
||||||
func startsWithFunc(a, b string) bool {
|
func startsWithFunc(a, b string) bool {
|
||||||
|
@ -71,11 +81,20 @@ func endsWithFunc(a, b string) bool {
|
||||||
|
|
||||||
// matchFunc is condition for Match operator.
|
// matchFunc is condition for Match operator.
|
||||||
// It does regexp matching of a against pattern in b
|
// It does regexp matching of a against pattern in b
|
||||||
|
// and returns if they match.
|
||||||
func matchFunc(a, b string) bool {
|
func matchFunc(a, b string) bool {
|
||||||
matched, _ := regexp.MatchString(b, a)
|
matched, _ := regexp.MatchString(b, a)
|
||||||
return matched
|
return matched
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// notMatchFunc is condition for NotMatch operator.
|
||||||
|
// It does regexp matching of a against pattern in b
|
||||||
|
// and returns if they do not match.
|
||||||
|
func notMatchFunc(a, b string) bool {
|
||||||
|
matched, _ := regexp.MatchString(b, a)
|
||||||
|
return !matched
|
||||||
|
}
|
||||||
|
|
||||||
// If is statement for a rewrite condition.
|
// If is statement for a rewrite condition.
|
||||||
type If struct {
|
type If struct {
|
||||||
A string
|
A string
|
||||||
|
|
|
@ -20,6 +20,11 @@ func TestConditions(t *testing.T) {
|
||||||
{"ba has b", true},
|
{"ba has b", true},
|
||||||
{"bab has b", true},
|
{"bab has b", true},
|
||||||
{"bab has bb", false},
|
{"bab has bb", false},
|
||||||
|
{"a not_has a", false},
|
||||||
|
{"a not_has b", true},
|
||||||
|
{"ba not_has b", false},
|
||||||
|
{"bab not_has b", false},
|
||||||
|
{"bab not_has bb", true},
|
||||||
{"bab starts_with bb", false},
|
{"bab starts_with bb", false},
|
||||||
{"bab starts_with ba", true},
|
{"bab starts_with ba", true},
|
||||||
{"bab starts_with bab", true},
|
{"bab starts_with bab", true},
|
||||||
|
@ -37,6 +42,17 @@ func TestConditions(t *testing.T) {
|
||||||
{"b0a match b[a-z]", false},
|
{"b0a match b[a-z]", false},
|
||||||
{"b0a match b[a-z]+", false},
|
{"b0a match b[a-z]+", false},
|
||||||
{"b0a match b[a-z0-9]+", true},
|
{"b0a match b[a-z0-9]+", true},
|
||||||
|
{"a not_match *", true},
|
||||||
|
{"a not_match a", false},
|
||||||
|
{"a not_match .*", false},
|
||||||
|
{"a not_match a.*", false},
|
||||||
|
{"a not_match b.*", true},
|
||||||
|
{"ba not_match b.*", false},
|
||||||
|
{"ba not_match b[a-z]", false},
|
||||||
|
{"b0 not_match b[a-z]", true},
|
||||||
|
{"b0a not_match b[a-z]", true},
|
||||||
|
{"b0a not_match b[a-z]+", true},
|
||||||
|
{"b0a not_match b[a-z0-9]+", false},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, test := range tests {
|
for i, test := range tests {
|
||||||
|
|
|
@ -13,6 +13,19 @@ import (
|
||||||
"github.com/mholt/caddy/middleware"
|
"github.com/mholt/caddy/middleware"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// RewriteResult is the result of a rewrite
|
||||||
|
type RewriteResult int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// RewriteIgnored is returned when rewrite is not done on request.
|
||||||
|
RewriteIgnored RewriteResult = iota
|
||||||
|
// RewriteDone is returned when rewrite is done on request.
|
||||||
|
RewriteDone
|
||||||
|
// RewriteStatus is returned when rewrite is not needed and status code should be set
|
||||||
|
// for the request.
|
||||||
|
RewriteStatus
|
||||||
|
)
|
||||||
|
|
||||||
// Rewrite is middleware to rewrite request locations internally before being handled.
|
// Rewrite is middleware to rewrite request locations internally before being handled.
|
||||||
type Rewrite struct {
|
type Rewrite struct {
|
||||||
Next middleware.Handler
|
Next middleware.Handler
|
||||||
|
@ -22,9 +35,18 @@ type Rewrite struct {
|
||||||
|
|
||||||
// ServeHTTP implements the middleware.Handler interface.
|
// ServeHTTP implements the middleware.Handler interface.
|
||||||
func (rw Rewrite) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
|
func (rw Rewrite) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
|
outer:
|
||||||
for _, rule := range rw.Rules {
|
for _, rule := range rw.Rules {
|
||||||
if ok := rule.Rewrite(rw.FileSys, r); ok {
|
switch result := rule.Rewrite(rw.FileSys, r); result {
|
||||||
|
case RewriteDone:
|
||||||
|
break outer
|
||||||
|
case RewriteIgnored:
|
||||||
break
|
break
|
||||||
|
case RewriteStatus:
|
||||||
|
// only valid for complex rules.
|
||||||
|
if cRule, ok := rule.(*ComplexRule); ok && cRule.Status != 0 {
|
||||||
|
return cRule.Status, nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rw.Next.ServeHTTP(w, r)
|
return rw.Next.ServeHTTP(w, r)
|
||||||
|
@ -33,7 +55,7 @@ func (rw Rewrite) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error)
|
||||||
// Rule describes an internal location rewrite rule.
|
// Rule describes an internal location rewrite rule.
|
||||||
type Rule interface {
|
type Rule interface {
|
||||||
// Rewrite rewrites the internal location of the current request.
|
// Rewrite rewrites the internal location of the current request.
|
||||||
Rewrite(http.FileSystem, *http.Request) bool
|
Rewrite(http.FileSystem, *http.Request) RewriteResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// SimpleRule is a simple rewrite rule.
|
// SimpleRule is a simple rewrite rule.
|
||||||
|
@ -47,7 +69,7 @@ func NewSimpleRule(from, to string) SimpleRule {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rewrite rewrites the internal location of the current request.
|
// Rewrite rewrites the internal location of the current request.
|
||||||
func (s SimpleRule) Rewrite(fs http.FileSystem, r *http.Request) bool {
|
func (s SimpleRule) Rewrite(fs http.FileSystem, r *http.Request) RewriteResult {
|
||||||
if s.From == r.URL.Path {
|
if s.From == r.URL.Path {
|
||||||
// take note of this rewrite for internal use by fastcgi
|
// take note of this rewrite for internal use by fastcgi
|
||||||
// all we need is the URI, not full URL
|
// all we need is the URI, not full URL
|
||||||
|
@ -56,7 +78,7 @@ func (s SimpleRule) Rewrite(fs http.FileSystem, r *http.Request) bool {
|
||||||
// attempt rewrite
|
// attempt rewrite
|
||||||
return To(fs, r, s.To, newReplacer(r))
|
return To(fs, r, s.To, newReplacer(r))
|
||||||
}
|
}
|
||||||
return false
|
return RewriteIgnored
|
||||||
}
|
}
|
||||||
|
|
||||||
// ComplexRule is a rewrite rule based on a regular expression
|
// ComplexRule is a rewrite rule based on a regular expression
|
||||||
|
@ -67,6 +89,10 @@ type ComplexRule struct {
|
||||||
// Path to rewrite to
|
// Path to rewrite to
|
||||||
To string
|
To string
|
||||||
|
|
||||||
|
// If set, neither performs rewrite nor proceeds
|
||||||
|
// with request. Only returns code.
|
||||||
|
Status int
|
||||||
|
|
||||||
// Extensions to filter by
|
// Extensions to filter by
|
||||||
Exts []string
|
Exts []string
|
||||||
|
|
||||||
|
@ -78,7 +104,7 @@ type ComplexRule struct {
|
||||||
|
|
||||||
// NewRegexpRule creates a new RegexpRule. It returns an error if regexp
|
// NewRegexpRule creates a new RegexpRule. It returns an error if regexp
|
||||||
// pattern (pattern) or extensions (ext) are invalid.
|
// pattern (pattern) or extensions (ext) are invalid.
|
||||||
func NewComplexRule(base, pattern, to string, ext []string, ifs []If) (*ComplexRule, error) {
|
func NewComplexRule(base, pattern, to string, status int, ext []string, ifs []If) (*ComplexRule, error) {
|
||||||
// validate regexp if present
|
// validate regexp if present
|
||||||
var r *regexp.Regexp
|
var r *regexp.Regexp
|
||||||
if pattern != "" {
|
if pattern != "" {
|
||||||
|
@ -102,6 +128,7 @@ func NewComplexRule(base, pattern, to string, ext []string, ifs []If) (*ComplexR
|
||||||
return &ComplexRule{
|
return &ComplexRule{
|
||||||
Base: base,
|
Base: base,
|
||||||
To: to,
|
To: to,
|
||||||
|
Status: status,
|
||||||
Exts: ext,
|
Exts: ext,
|
||||||
Ifs: ifs,
|
Ifs: ifs,
|
||||||
Regexp: r,
|
Regexp: r,
|
||||||
|
@ -109,33 +136,33 @@ func NewComplexRule(base, pattern, to string, ext []string, ifs []If) (*ComplexR
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rewrite rewrites the internal location of the current request.
|
// Rewrite rewrites the internal location of the current request.
|
||||||
func (r *ComplexRule) Rewrite(fs http.FileSystem, req *http.Request) bool {
|
func (r *ComplexRule) Rewrite(fs http.FileSystem, req *http.Request) (re RewriteResult) {
|
||||||
rPath := req.URL.Path
|
rPath := req.URL.Path
|
||||||
replacer := newReplacer(req)
|
replacer := newReplacer(req)
|
||||||
|
|
||||||
// validate base
|
// validate base
|
||||||
if !middleware.Path(rPath).Matches(r.Base) {
|
if !middleware.Path(rPath).Matches(r.Base) {
|
||||||
return false
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate extensions
|
// validate extensions
|
||||||
if !r.matchExt(rPath) {
|
if !r.matchExt(rPath) {
|
||||||
return false
|
return
|
||||||
}
|
|
||||||
|
|
||||||
// include trailing slash in regexp if present
|
|
||||||
start := len(r.Base)
|
|
||||||
if strings.HasSuffix(r.Base, "/") {
|
|
||||||
start--
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate regexp if present
|
// validate regexp if present
|
||||||
if r.Regexp != nil {
|
if r.Regexp != nil {
|
||||||
|
// include trailing slash in regexp if present
|
||||||
|
start := len(r.Base)
|
||||||
|
if strings.HasSuffix(r.Base, "/") {
|
||||||
|
start--
|
||||||
|
}
|
||||||
|
|
||||||
matches := r.FindStringSubmatch(rPath[start:])
|
matches := r.FindStringSubmatch(rPath[start:])
|
||||||
switch len(matches) {
|
switch len(matches) {
|
||||||
case 0:
|
case 0:
|
||||||
// no match
|
// no match
|
||||||
return false
|
return
|
||||||
default:
|
default:
|
||||||
// set regexp match variables {1}, {2} ...
|
// set regexp match variables {1}, {2} ...
|
||||||
for i := 1; i < len(matches); i++ {
|
for i := 1; i < len(matches); i++ {
|
||||||
|
@ -147,10 +174,15 @@ func (r *ComplexRule) Rewrite(fs http.FileSystem, req *http.Request) bool {
|
||||||
// validate rewrite conditions
|
// validate rewrite conditions
|
||||||
for _, i := range r.Ifs {
|
for _, i := range r.Ifs {
|
||||||
if !i.True(req) {
|
if !i.True(req) {
|
||||||
return false
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if status is present, stop rewrite and return it.
|
||||||
|
if r.Status != 0 {
|
||||||
|
return RewriteStatus
|
||||||
|
}
|
||||||
|
|
||||||
// attempt rewrite
|
// attempt rewrite
|
||||||
return To(fs, req, r.To, replacer)
|
return To(fs, req, r.To, replacer)
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ func TestRewrite(t *testing.T) {
|
||||||
if s := strings.Split(regexpRule[3], "|"); len(s) > 1 {
|
if s := strings.Split(regexpRule[3], "|"); len(s) > 1 {
|
||||||
ext = s[:len(s)-1]
|
ext = s[:len(s)-1]
|
||||||
}
|
}
|
||||||
rule, err := NewComplexRule(regexpRule[0], regexpRule[1], regexpRule[2], ext, nil)
|
rule, err := NewComplexRule(regexpRule[0], regexpRule[1], regexpRule[2], 0, ext, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -106,6 +106,51 @@ func TestRewrite(t *testing.T) {
|
||||||
i, test.expectedTo, rec.Body.String())
|
i, test.expectedTo, rec.Body.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
statusTests := []struct {
|
||||||
|
status int
|
||||||
|
base string
|
||||||
|
to string
|
||||||
|
regexp string
|
||||||
|
statusExpected bool
|
||||||
|
}{
|
||||||
|
{400, "/status", "", "", true},
|
||||||
|
{400, "/ignore", "", "", false},
|
||||||
|
{400, "/", "", "^/ignore", false},
|
||||||
|
{400, "/", "", "(.*)", true},
|
||||||
|
{400, "/status", "", "", true},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, s := range statusTests {
|
||||||
|
urlPath := fmt.Sprintf("/status%d", i)
|
||||||
|
rule, err := NewComplexRule(s.base, s.regexp, s.to, s.status, nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Test %d: No error expected for rule but found %v", i, err)
|
||||||
|
}
|
||||||
|
rw.Rules = []Rule{rule}
|
||||||
|
req, err := http.NewRequest("GET", urlPath, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Test %d: Could not create HTTP request: %v", i, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
rec := httptest.NewRecorder()
|
||||||
|
code, err := rw.ServeHTTP(rec, req)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Test %d: No error expected for handler but found %v", i, err)
|
||||||
|
}
|
||||||
|
if s.statusExpected {
|
||||||
|
if rec.Body.String() != "" {
|
||||||
|
t.Errorf("Test %d: Expected empty body but found %s", i, rec.Body.String())
|
||||||
|
}
|
||||||
|
if code != s.status {
|
||||||
|
t.Errorf("Test %d: Expected status code %d found %d", i, s.status, code)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if code != 0 {
|
||||||
|
t.Errorf("Test %d: Expected no status code found %d", i, code)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func urlPrinter(w http.ResponseWriter, r *http.Request) (int, error) {
|
func urlPrinter(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
|
|
|
@ -13,7 +13,7 @@ import (
|
||||||
// To attempts rewrite. It attempts to rewrite to first valid path
|
// To attempts rewrite. It attempts to rewrite to first valid path
|
||||||
// or the last path if none of the paths are valid.
|
// or the last path if none of the paths are valid.
|
||||||
// Returns true if rewrite is successful and false otherwise.
|
// Returns true if rewrite is successful and false otherwise.
|
||||||
func To(fs http.FileSystem, r *http.Request, to string, replacer middleware.Replacer) bool {
|
func To(fs http.FileSystem, r *http.Request, to string, replacer middleware.Replacer) RewriteResult {
|
||||||
tos := strings.Fields(to)
|
tos := strings.Fields(to)
|
||||||
|
|
||||||
// try each rewrite paths
|
// try each rewrite paths
|
||||||
|
@ -38,7 +38,7 @@ func To(fs http.FileSystem, r *http.Request, to string, replacer middleware.Repl
|
||||||
// Let the user know we got here. Rewrite is expected but
|
// Let the user know we got here. Rewrite is expected but
|
||||||
// the resulting url is invalid.
|
// the resulting url is invalid.
|
||||||
log.Printf("[ERROR] rewrite: resulting path '%v' is invalid. error: %v", t, err)
|
log.Printf("[ERROR] rewrite: resulting path '%v' is invalid. error: %v", t, err)
|
||||||
return false
|
return RewriteIgnored
|
||||||
}
|
}
|
||||||
|
|
||||||
// take note of this rewrite for internal use by fastcgi
|
// take note of this rewrite for internal use by fastcgi
|
||||||
|
@ -56,7 +56,7 @@ func To(fs http.FileSystem, r *http.Request, to string, replacer middleware.Repl
|
||||||
r.URL.Fragment = u.Fragment
|
r.URL.Fragment = u.Fragment
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return RewriteDone
|
||||||
}
|
}
|
||||||
|
|
||||||
// isValidFile checks if file exists on the filesystem.
|
// isValidFile checks if file exists on the filesystem.
|
||||||
|
|
Loading…
Reference in a new issue