Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
caddy
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
caddy
Commits
bec9b9a3
Commit
bec9b9a3
authored
Jul 24, 2015
by
Matthew Holt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
redir: Redirect tables
Open a redir block to bulk-specify a bunch of redirects that share a status code
parent
bf47951f
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
117 additions
and
42 deletions
+117
-42
config/setup/redir.go
config/setup/redir.go
+117
-42
No files found.
config/setup/redir.go
View file @
bec9b9a3
...
...
@@ -22,49 +22,124 @@ func Redir(c *Controller) (middleware.Middleware, error) {
func
redirParse
(
c
*
Controller
)
([]
redirect
.
Rule
,
error
)
{
var
redirects
[]
redirect
.
Rule
// setRedirCode sets the redirect code for rule if it can, or returns an error
setRedirCode
:=
func
(
code
string
,
rule
*
redirect
.
Rule
)
error
{
if
code
==
"meta"
{
rule
.
Meta
=
true
}
else
if
codeNumber
,
ok
:=
httpRedirs
[
code
];
ok
{
rule
.
Code
=
codeNumber
}
else
{
return
c
.
Errf
(
"Invalid redirect code '%v'"
,
code
)
}
return
nil
}
// checkAndSaveRule checks the rule for validity (except the redir code)
// and saves it if it's valid, or returns an error.
checkAndSaveRule
:=
func
(
rule
redirect
.
Rule
)
error
{
if
rule
.
From
==
rule
.
To
{
return
c
.
Err
(
"'from' and 'to' values of redirect rule cannot be the same"
)
}
for
_
,
otherRule
:=
range
redirects
{
if
otherRule
.
From
==
rule
.
From
{
return
c
.
Errf
(
"rule with duplicate 'from' value: %s -> %s"
,
otherRule
.
From
,
otherRule
.
To
)
}
}
redirects
=
append
(
redirects
,
rule
)
return
nil
}
for
c
.
Next
()
{
var
rule
redirect
.
Rule
args
:=
c
.
RemainingArgs
()
// Always set the default Code, then overwrite
rule
.
Code
=
http
.
StatusMovedPermanently
switch
len
(
args
)
{
case
1
:
// To specified
rule
.
From
=
"/"
rule
.
To
=
args
[
0
]
case
2
:
// To and Code specified
rule
.
From
=
"/"
rule
.
To
=
args
[
0
]
if
"meta"
==
args
[
1
]
{
rule
.
Meta
=
true
}
else
if
code
,
ok
:=
httpRedirs
[
args
[
1
]];
!
ok
{
return
redirects
,
c
.
Err
(
"Invalid redirect code '"
+
args
[
1
]
+
"'"
)
var
hadOptionalBlock
bool
for
c
.
NextBlock
()
{
hadOptionalBlock
=
true
var
rule
redirect
.
Rule
// Set initial redirect code
// BUG: If the code is specified for a whole block and that code is invalid,
// the line number will appear on the first line inside the block, even if that
// line overwrites the block-level code with a valid redirect code. The program
// still functions correctly, but the line number in the error reporting is
// misleading to the user.
if
len
(
args
)
==
1
{
err
:=
setRedirCode
(
args
[
0
],
&
rule
)
if
err
!=
nil
{
return
redirects
,
err
}
}
else
{
rule
.
Code
=
code
rule
.
Code
=
http
.
StatusMovedPermanently
// default
code
}
case
3
:
// From, To, and Code specified
rule
.
From
=
args
[
0
]
rule
.
To
=
args
[
1
]
if
"meta"
==
args
[
2
]
{
rule
.
Meta
=
true
}
else
if
code
,
ok
:=
httpRedirs
[
args
[
2
]];
!
ok
{
return
redirects
,
c
.
Err
(
"Invalid redirect code '"
+
args
[
2
]
+
"'"
)
}
else
{
rule
.
Code
=
code
// RemainingArgs only gets the values after the current token, but in our
// case we want to include the current token to get an accurate count.
insideArgs
:=
append
([]
string
{
c
.
Val
()},
c
.
RemainingArgs
()
...
)
switch
len
(
insideArgs
)
{
case
1
:
// To specified (catch-all redirect)
rule
.
From
=
"/"
rule
.
To
=
insideArgs
[
0
]
case
2
:
// From and To specified
rule
.
From
=
insideArgs
[
0
]
rule
.
To
=
insideArgs
[
1
]
case
3
:
// From, To, and Code specified
rule
.
From
=
insideArgs
[
0
]
rule
.
To
=
insideArgs
[
1
]
err
:=
setRedirCode
(
insideArgs
[
2
],
&
rule
)
if
err
!=
nil
{
return
redirects
,
err
}
default
:
return
redirects
,
c
.
ArgErr
()
}
default
:
return
redirects
,
c
.
ArgErr
()
}
if
rule
.
From
==
rule
.
To
{
return
redirects
,
c
.
Err
(
"Redirect rule cannot allow From and To arguments to be the same."
)
err
:=
checkAndSaveRule
(
rule
)
if
err
!=
nil
{
return
redirects
,
err
}
}
redirects
=
append
(
redirects
,
rule
)
if
!
hadOptionalBlock
{
var
rule
redirect
.
Rule
rule
.
Code
=
http
.
StatusMovedPermanently
// default
switch
len
(
args
)
{
case
1
:
// To specified (catch-all redirect)
rule
.
From
=
"/"
rule
.
To
=
args
[
0
]
case
2
:
// To and Code specified (catch-all redirect)
rule
.
From
=
"/"
rule
.
To
=
args
[
0
]
err
:=
setRedirCode
(
args
[
1
],
&
rule
)
if
err
!=
nil
{
return
redirects
,
err
}
case
3
:
// From, To, and Code specified
rule
.
From
=
args
[
0
]
rule
.
To
=
args
[
1
]
err
:=
setRedirCode
(
args
[
2
],
&
rule
)
if
err
!=
nil
{
return
redirects
,
err
}
default
:
return
redirects
,
c
.
ArgErr
()
}
err
:=
checkAndSaveRule
(
rule
)
if
err
!=
nil
{
return
redirects
,
err
}
}
}
return
redirects
,
nil
...
...
@@ -72,12 +147,12 @@ func redirParse(c *Controller) ([]redirect.Rule, error) {
// httpRedirs is a list of supported HTTP redirect codes.
var
httpRedirs
=
map
[
string
]
int
{
"300"
:
300
,
"301"
:
301
,
"302"
:
302
,
"303"
:
303
,
"304"
:
304
,
"305"
:
305
,
"307"
:
307
,
"308"
:
308
,
"300"
:
300
,
// Multiple Choices
"301"
:
301
,
// Moved Permanently
"302"
:
302
,
// Found (NOT CORRECT for "Temporary Redirect", see 307)
"303"
:
303
,
// See Other
"304"
:
304
,
// Not Modified
"305"
:
305
,
// Use Proxy
"307"
:
307
,
// Temporary Redirect
"308"
:
308
,
// Permanent Redirect
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment