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
Łukasz Nowak
caddy
Commits
d0ddfc84
Commit
d0ddfc84
authored
Sep 27, 2016
by
Tw
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
header: defer header operations
fix issue #1131 Signed-off-by:
Tw
<
tw19881113@gmail.com
>
parent
4adbcd25
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
68 additions
and
5 deletions
+68
-5
caddyhttp/header/header.go
caddyhttp/header/header.go
+64
-4
caddyhttp/header/header_test.go
caddyhttp/header/header_test.go
+4
-1
No files found.
caddyhttp/header/header.go
View file @
d0ddfc84
...
...
@@ -21,22 +21,23 @@ type Headers struct {
// setting headers on the response according to the configured rules.
func
(
h
Headers
)
ServeHTTP
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
(
int
,
error
)
{
replacer
:=
httpserver
.
NewReplacer
(
r
,
nil
,
""
)
rww
:=
&
responseWriterWrapper
{
w
:
w
}
for
_
,
rule
:=
range
h
.
Rules
{
if
httpserver
.
Path
(
r
.
URL
.
Path
)
.
Matches
(
rule
.
Path
)
{
for
_
,
header
:=
range
rule
.
Headers
{
// One can either delete a header, add multiple values to a header, or simply
// set a header.
if
strings
.
HasPrefix
(
header
.
Name
,
"-"
)
{
w
.
Header
()
.
Del
(
strings
.
TrimLeft
(
header
.
Name
,
"-"
))
rww
.
delHeader
(
strings
.
TrimLeft
(
header
.
Name
,
"-"
))
}
else
if
strings
.
HasPrefix
(
header
.
Name
,
"+"
)
{
w
.
Header
()
.
Add
(
strings
.
TrimLeft
(
header
.
Name
,
"+"
),
replacer
.
Replace
(
header
.
Value
))
rww
.
addHeader
(
strings
.
TrimLeft
(
header
.
Name
,
"+"
),
replacer
.
Replace
(
header
.
Value
))
}
else
{
w
.
Header
()
.
Set
(
header
.
Name
,
replacer
.
Replace
(
header
.
Value
))
rww
.
setHeader
(
header
.
Name
,
replacer
.
Replace
(
header
.
Value
))
}
}
}
}
return
h
.
Next
.
ServeHTTP
(
w
,
r
)
return
h
.
Next
.
ServeHTTP
(
rw
w
,
r
)
}
type
(
...
...
@@ -53,3 +54,62 @@ type (
Value
string
}
)
// headerOperation represents an operation on the header
type
headerOperation
func
(
http
.
Header
)
// responseWriterWrapper wraps the real ResponseWriter.
// It defers header operations until writeHeader
type
responseWriterWrapper
struct
{
w
http
.
ResponseWriter
ops
[]
headerOperation
wroteHeader
bool
}
func
(
rww
*
responseWriterWrapper
)
Header
()
http
.
Header
{
return
rww
.
w
.
Header
()
}
func
(
rww
*
responseWriterWrapper
)
Write
(
d
[]
byte
)
(
int
,
error
)
{
if
!
rww
.
wroteHeader
{
rww
.
WriteHeader
(
http
.
StatusOK
)
}
return
rww
.
w
.
Write
(
d
)
}
func
(
rww
*
responseWriterWrapper
)
WriteHeader
(
status
int
)
{
if
rww
.
wroteHeader
{
return
}
rww
.
wroteHeader
=
true
// capture the original headers
h
:=
rww
.
Header
()
// perform our revisions
for
_
,
op
:=
range
rww
.
ops
{
op
(
h
)
}
rww
.
w
.
WriteHeader
(
status
)
}
// addHeader registers a http.Header.Add operation
func
(
rww
*
responseWriterWrapper
)
addHeader
(
key
,
value
string
)
{
rww
.
ops
=
append
(
rww
.
ops
,
func
(
h
http
.
Header
)
{
h
.
Add
(
key
,
value
)
})
}
// delHeader registers a http.Header.Del operation
func
(
rww
*
responseWriterWrapper
)
delHeader
(
key
string
)
{
rww
.
ops
=
append
(
rww
.
ops
,
func
(
h
http
.
Header
)
{
h
.
Del
(
key
)
})
}
// setHeader registers a http.Header.Set operation
func
(
rww
*
responseWriterWrapper
)
setHeader
(
key
,
value
string
)
{
rww
.
ops
=
append
(
rww
.
ops
,
func
(
h
http
.
Header
)
{
h
.
Set
(
key
,
value
)
})
}
caddyhttp/header/header_test.go
View file @
d0ddfc84
package
header
import
(
"fmt"
"net/http"
"net/http/httptest"
"os"
...
...
@@ -30,6 +31,8 @@ func TestHeader(t *testing.T) {
}
{
he
:=
Headers
{
Next
:
httpserver
.
HandlerFunc
(
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
(
int
,
error
)
{
w
.
Header
()
.
Set
(
"Bar"
,
"Removed in /a"
)
fmt
.
Fprint
(
w
,
"This is a test"
)
return
0
,
nil
}),
Rules
:
[]
Rule
{
...
...
@@ -47,7 +50,6 @@ func TestHeader(t *testing.T) {
}
rec
:=
httptest
.
NewRecorder
()
rec
.
Header
()
.
Set
(
"Bar"
,
"Removed in /a"
)
he
.
ServeHTTP
(
rec
,
req
)
...
...
@@ -61,6 +63,7 @@ func TestHeader(t *testing.T) {
func
TestMultipleHeaders
(
t
*
testing
.
T
)
{
he
:=
Headers
{
Next
:
httpserver
.
HandlerFunc
(
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
(
int
,
error
)
{
fmt
.
Fprint
(
w
,
"This is a test"
)
return
0
,
nil
}),
Rules
:
[]
Rule
{
...
...
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