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
b06b3981
Commit
b06b3981
authored
Sep 27, 2016
by
Matt Holt
Committed by
GitHub
Sep 27, 2016
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1140 from tw4452852/defer_header
header: defer header operations
parents
8cb4e908
d0ddfc84
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 @
b06b3981
...
...
@@ -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 @
b06b3981
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