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
281007c4
Commit
281007c4
authored
Dec 31, 2015
by
Abiola Ibrahim
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'upstream/master' into rewrite-patch
parents
34689862
b6326d40
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
89 additions
and
69 deletions
+89
-69
middleware/replacer.go
middleware/replacer.go
+19
-12
middleware/replacer_test.go
middleware/replacer_test.go
+70
-57
No files found.
middleware/replacer.go
View file @
281007c4
...
@@ -86,9 +86,9 @@ func NewReplacer(r *http.Request, rr *responseRecorder, emptyValue string) Repla
...
@@ -86,9 +86,9 @@ func NewReplacer(r *http.Request, rr *responseRecorder, emptyValue string) Repla
rep
.
replacements
[
"{latency}"
]
=
time
.
Since
(
rr
.
start
)
.
String
()
rep
.
replacements
[
"{latency}"
]
=
time
.
Since
(
rr
.
start
)
.
String
()
}
}
// Header placeholders
// Header placeholders
(case-insensitive)
for
header
,
val
:=
range
r
.
Header
{
for
header
,
val
ues
:=
range
r
.
Header
{
rep
.
replacements
[
headerReplacer
+
header
+
"}"
]
=
strings
.
Join
(
val
,
","
)
rep
.
replacements
[
headerReplacer
+
strings
.
ToLower
(
header
)
+
"}"
]
=
strings
.
Join
(
values
,
","
)
}
}
return
rep
return
rep
...
@@ -97,24 +97,31 @@ func NewReplacer(r *http.Request, rr *responseRecorder, emptyValue string) Repla
...
@@ -97,24 +97,31 @@ func NewReplacer(r *http.Request, rr *responseRecorder, emptyValue string) Repla
// Replace performs a replacement of values on s and returns
// Replace performs a replacement of values on s and returns
// the string with the replaced values.
// the string with the replaced values.
func
(
r
replacer
)
Replace
(
s
string
)
string
{
func
(
r
replacer
)
Replace
(
s
string
)
string
{
for
placeholder
,
replacement
:=
range
r
.
replacements
{
// Header replacements - these are case-insensitive, so we can't just use strings.Replace()
if
replacement
==
""
{
replacement
=
r
.
emptyValue
}
s
=
strings
.
Replace
(
s
,
placeholder
,
replacement
,
-
1
)
}
// Replace any header placeholders that weren't found
for
strings
.
Contains
(
s
,
headerReplacer
)
{
for
strings
.
Contains
(
s
,
headerReplacer
)
{
idxStart
:=
strings
.
Index
(
s
,
headerReplacer
)
idxStart
:=
strings
.
Index
(
s
,
headerReplacer
)
endOffset
:=
idxStart
+
len
(
headerReplacer
)
endOffset
:=
idxStart
+
len
(
headerReplacer
)
idxEnd
:=
strings
.
Index
(
s
[
endOffset
:
],
"}"
)
idxEnd
:=
strings
.
Index
(
s
[
endOffset
:
],
"}"
)
if
idxEnd
>
-
1
{
if
idxEnd
>
-
1
{
s
=
s
[
:
idxStart
]
+
r
.
emptyValue
+
s
[
endOffset
+
idxEnd
+
1
:
]
placeholder
:=
strings
.
ToLower
(
s
[
idxStart
:
endOffset
+
idxEnd
+
1
])
replacement
:=
r
.
replacements
[
placeholder
]
if
replacement
==
""
{
replacement
=
r
.
emptyValue
}
s
=
s
[
:
idxStart
]
+
replacement
+
s
[
endOffset
+
idxEnd
+
1
:
]
}
else
{
}
else
{
break
break
}
}
}
}
// Regular replacements - these are easier because they're case-sensitive
for
placeholder
,
replacement
:=
range
r
.
replacements
{
if
replacement
==
""
{
replacement
=
r
.
emptyValue
}
s
=
strings
.
Replace
(
s
,
placeholder
,
replacement
,
-
1
)
}
return
s
return
s
}
}
...
...
middleware/replacer_test.go
View file @
281007c4
...
@@ -10,102 +10,115 @@ import (
...
@@ -10,102 +10,115 @@ import (
func
TestNewReplacer
(
t
*
testing
.
T
)
{
func
TestNewReplacer
(
t
*
testing
.
T
)
{
w
:=
httptest
.
NewRecorder
()
w
:=
httptest
.
NewRecorder
()
recordRequest
:=
NewResponseRecorder
(
w
)
recordRequest
:=
NewResponseRecorder
(
w
)
userJSON
:=
`{"username": "dennis"}`
reader
:=
strings
.
NewReader
(
`{"username": "dennis"}`
)
reader
:=
strings
.
NewReader
(
userJSON
)
//Convert string to reader
request
,
err
:=
http
.
NewRequest
(
"POST"
,
"http://localhost"
,
reader
)
request
,
err
:=
http
.
NewRequest
(
"POST"
,
"http://caddyserver.com"
,
reader
)
//Create request with JSON body
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Fatal
f
(
"Request Formation Failed
\n
"
)
t
.
Fatal
(
"Request Formation Failed
\n
"
)
}
}
replaceValues
:=
NewReplacer
(
request
,
recordRequest
,
""
)
replaceValues
:=
NewReplacer
(
request
,
recordRequest
,
""
)
switch
v
:=
replaceValues
.
(
type
)
{
switch
v
:=
replaceValues
.
(
type
)
{
case
replacer
:
case
replacer
:
if
v
.
replacements
[
"{host}"
]
!=
"
caddyserver.com
"
{
if
v
.
replacements
[
"{host}"
]
!=
"
localhost
"
{
t
.
Error
f
(
"Expected host to be caddyserver.com
"
)
t
.
Error
(
"Expected host to be localhost
"
)
}
}
if
v
.
replacements
[
"{method}"
]
!=
"POST"
{
if
v
.
replacements
[
"{method}"
]
!=
"POST"
{
t
.
Error
f
(
"Expected request method to be POST"
)
t
.
Error
(
"Expected request method to be POST"
)
}
}
if
v
.
replacements
[
"{status}"
]
!=
"200"
{
if
v
.
replacements
[
"{status}"
]
!=
"200"
{
t
.
Error
f
(
"Expected status to be 200"
)
t
.
Error
(
"Expected status to be 200"
)
}
}
default
:
default
:
t
.
Fatal
f
(
"Return Value from New Replacer expected pass type assertion into a replacer type
\n
"
)
t
.
Fatal
(
"Return Value from New Replacer expected pass type assertion into a replacer type
\n
"
)
}
}
}
}
func
TestReplace
(
t
*
testing
.
T
)
{
func
TestReplace
(
t
*
testing
.
T
)
{
w
:=
httptest
.
NewRecorder
()
w
:=
httptest
.
NewRecorder
()
recordRequest
:=
NewResponseRecorder
(
w
)
recordRequest
:=
NewResponseRecorder
(
w
)
userJSON
:=
`{"username": "dennis"}`
reader
:=
strings
.
NewReader
(
`{"username": "dennis"}`
)
reader
:=
strings
.
NewReader
(
userJSON
)
//Convert string to reader
request
,
err
:=
http
.
NewRequest
(
"POST"
,
"http://
caddyserver.com"
,
reader
)
//Create request with JSON body
request
,
err
:=
http
.
NewRequest
(
"POST"
,
"http://
localhost"
,
reader
)
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Fatal
f
(
"Request Formation Failed
\n
"
)
t
.
Fatal
(
"Request Formation Failed
\n
"
)
}
}
replaceValues
:=
NewReplacer
(
request
,
recordRequest
,
""
)
request
.
Header
.
Set
(
"Custom"
,
"foobarbaz"
)
request
.
Header
.
Set
(
"ShorterVal"
,
"1"
)
repl
:=
NewReplacer
(
request
,
recordRequest
,
"-"
)
switch
v
:=
replaceValues
.
(
type
)
{
if
expected
,
actual
:=
"This host is localhost."
,
repl
.
Replace
(
"This host is {host}."
);
expected
!=
actual
{
case
replacer
:
t
.
Errorf
(
"{host} replacement: expected '%s', got '%s'"
,
expected
,
actual
)
}
if
expected
,
actual
:=
"This request method is POST."
,
repl
.
Replace
(
"This request method is {method}."
);
expected
!=
actual
{
t
.
Errorf
(
"{method} replacement: expected '%s', got '%s'"
,
expected
,
actual
)
}
if
expected
,
actual
:=
"The response status is 200."
,
repl
.
Replace
(
"The response status is {status}."
);
expected
!=
actual
{
t
.
Errorf
(
"{status} replacement: expected '%s', got '%s'"
,
expected
,
actual
)
}
if
expected
,
actual
:=
"The Custom header is foobarbaz."
,
repl
.
Replace
(
"The Custom header is {>Custom}."
);
expected
!=
actual
{
t
.
Errorf
(
"{>Custom} replacement: expected '%s', got '%s'"
,
expected
,
actual
)
}
if
v
.
Replace
(
"This host is {host}"
)
!=
"This host is caddyserver.com"
{
// Test header case-insensitivity
t
.
Errorf
(
"Expected host replacement failed"
)
if
expected
,
actual
:=
"The cUsToM header is foobarbaz..."
,
repl
.
Replace
(
"The cUsToM header is {>cUsToM}..."
);
expected
!=
actual
{
}
t
.
Errorf
(
"{>cUsToM} replacement: expected '%s', got '%s'"
,
expected
,
actual
)
if
v
.
Replace
(
"This request method is {method}"
)
!=
"This request method is POST"
{
}
t
.
Errorf
(
"Expected method replacement failed"
)
}
if
v
.
Replace
(
"The response status is {status}"
)
!=
"The response status is 200"
{
t
.
Errorf
(
"Expected status replacement failed"
)
}
default
:
// Test non-existent header/value
t
.
Fatalf
(
"Return Value from New Replacer expected pass type assertion into a replacer type
\n
"
)
if
expected
,
actual
:=
"The Non-Existent header is -."
,
repl
.
Replace
(
"The Non-Existent header is {>Non-Existent}."
);
expected
!=
actual
{
t
.
Errorf
(
"{>Non-Existent} replacement: expected '%s', got '%s'"
,
expected
,
actual
)
}
// Test bad placeholder
if
expected
,
actual
:=
"Bad {host placeholder..."
,
repl
.
Replace
(
"Bad {host placeholder..."
);
expected
!=
actual
{
t
.
Errorf
(
"bad placeholder: expected '%s', got '%s'"
,
expected
,
actual
)
}
// Test bad header placeholder
if
expected
,
actual
:=
"Bad {>Custom placeholder"
,
repl
.
Replace
(
"Bad {>Custom placeholder"
);
expected
!=
actual
{
t
.
Errorf
(
"bad header placeholder: expected '%s', got '%s'"
,
expected
,
actual
)
}
// Test bad header placeholder with valid one later
if
expected
,
actual
:=
"Bad -"
,
repl
.
Replace
(
"Bad {>Custom placeholder {>ShorterVal}"
);
expected
!=
actual
{
t
.
Errorf
(
"bad header placeholders: expected '%s', got '%s'"
,
expected
,
actual
)
}
}
// Test shorter header value with multiple placeholders
if
expected
,
actual
:=
"Short value 1 then foobarbaz."
,
repl
.
Replace
(
"Short value {>ShorterVal} then {>Custom}."
);
expected
!=
actual
{
t
.
Errorf
(
"short value: expected '%s', got '%s'"
,
expected
,
actual
)
}
}
}
func
TestSet
(
t
*
testing
.
T
)
{
func
TestSet
(
t
*
testing
.
T
)
{
w
:=
httptest
.
NewRecorder
()
w
:=
httptest
.
NewRecorder
()
recordRequest
:=
NewResponseRecorder
(
w
)
recordRequest
:=
NewResponseRecorder
(
w
)
userJSON
:=
`{"username": "dennis"}`
reader
:=
strings
.
NewReader
(
`{"username": "dennis"}`
)
reader
:=
strings
.
NewReader
(
userJSON
)
//Convert string to reader
request
,
err
:=
http
.
NewRequest
(
"POST"
,
"http://
caddyserver.com"
,
reader
)
//Create request with JSON body
request
,
err
:=
http
.
NewRequest
(
"POST"
,
"http://
localhost"
,
reader
)
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Fatalf
(
"Request Formation Failed
\n
"
)
t
.
Fatalf
(
"Request Formation Failed
\n
"
)
}
}
repl
aceValues
:=
NewReplacer
(
request
,
recordRequest
,
""
)
repl
:=
NewReplacer
(
request
,
recordRequest
,
""
)
repl
aceValues
.
Set
(
"host"
,
"getcaddy.com"
)
repl
.
Set
(
"host"
,
"getcaddy.com"
)
repl
aceValues
.
Set
(
"method"
,
"GET"
)
repl
.
Set
(
"method"
,
"GET"
)
repl
aceValues
.
Set
(
"status"
,
"201"
)
repl
.
Set
(
"status"
,
"201"
)
repl
aceValues
.
Set
(
"variable"
,
"value"
)
repl
.
Set
(
"variable"
,
"value"
)
switch
v
:=
replaceValues
.
(
type
)
{
if
repl
.
Replace
(
"This host is {host}"
)
!=
"This host is getcaddy.com"
{
case
replacer
:
t
.
Error
(
"Expected host replacement failed"
)
}
if
v
.
Replace
(
"This host is {host}"
)
!=
"This host is getcaddy.com"
{
if
repl
.
Replace
(
"This request method is {method}"
)
!=
"This request method is GET"
{
t
.
Errorf
(
"Expected host replacement failed"
)
t
.
Error
(
"Expected method replacement failed"
)
}
}
if
v
.
Replace
(
"This request method is {method}"
)
!=
"This request method is GET"
{
if
repl
.
Replace
(
"The response status is {status}"
)
!=
"The response status is 201"
{
t
.
Errorf
(
"Expected method replacement failed"
)
t
.
Error
(
"Expected status replacement failed"
)
}
}
if
v
.
Replace
(
"The response status is {status}"
)
!=
"The response status is 201"
{
if
repl
.
Replace
(
"The value of variable is {variable}"
)
!=
"The value of variable is value"
{
t
.
Errorf
(
"Expected status replacement failed"
)
t
.
Error
(
"Expected variable replacement failed"
)
}
if
v
.
Replace
(
"The value of variable is {variable}"
)
!=
"The value of variable is value"
{
t
.
Errorf
(
"Expected status replacement failed"
)
}
default
:
t
.
Fatalf
(
"Return Value from New Replacer expected pass type assertion into a replacer type
\n
"
)
}
}
}
}
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