-
Notifications
You must be signed in to change notification settings - Fork 247
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add append header modifier #247
Conversation
header/header_modifier.go
Outdated
return m.setOrAddHeader(proxyutil.ResponseHeader(res)) | ||
} | ||
|
||
func (m *modifier) setOrAddHeader(h *proxyutil.Header) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need to pull this out in a function - it's fine to just have this in ModifyRequest / ModifyResponse
header/header_modifier.go
Outdated
func (m *modifier) setOrAddHeader(h *proxyutil.Header) error { | ||
if m.add { | ||
return h.Add(m.name, m.value) | ||
} else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don't need the "else" - have the Set happen in the normal flow
header/header_modifier.go
Outdated
} | ||
|
||
// NewModifier returns a modifier that will set the header at name with | ||
// the given value for both requests and responses. If the header name already | ||
// exists all values will be overwritten. | ||
func NewModifier(name, value string) martian.RequestResponseModifier { | ||
func NewModifier(name, value string, add bool) martian.RequestResponseModifier { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rather than have this in the constructor, just let the default behavior be Set (same as current)
Add a func on modifier that changes it called SetBehavior
header/header_modifier.go
Outdated
@@ -29,31 +29,42 @@ func init() { | |||
|
|||
type modifier struct { | |||
name, value string | |||
add bool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm trying to think of a better way to name / represent this...
We have 2 "modes" - Append or Replace - so maybe instead of the add bool
, we could have a Mode that's an int that represents the modes that are defined with something like:
const (
ReplaceValues = iota
AppendValues
)
and then the struct could be:
type modifier struct {
name, value string
behavior int
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What would that look like on the wire?
{
"name": ...
...
"behavior": "replace" | "append"
}
?
Another option might be to still have a boolean flag but invert it and default it to true
{
"name": ...
...
"replace": false
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I was thinking there would be a "behavior" key that was either "replace" or "append"
Your modifierJSON struct would have a
Behavior string `json:"behavior"`
and then in modifierFromJSON you'd have a check like
if msg.Behavior == "append" {
modifier.SetBehavior(AppendValues)
}
header/header_modifier.go
Outdated
@@ -27,31 +27,52 @@ func init() { | |||
parse.Register("header.Modifier", modifierFromJSON) | |||
} | |||
|
|||
type modifier struct { | |||
type HeaderSetBehavior int |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add comment for exported type
https://github.com/golang/go/wiki/CodeReviewComments#doc-comments
header/header_modifier.go
Outdated
type HeaderSetBehavior int | ||
|
||
const ( | ||
ReplaceValues HeaderSetBehavior = iota |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add comment for exported type
https://github.com/golang/go/wiki/CodeReviewComments#doc-comments
header/header_modifier.go
Outdated
AppendValues | ||
) | ||
|
||
type Modifier struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add comment for exported type
https://github.com/golang/go/wiki/CodeReviewComments#doc-comments
header/header_modifier.go
Outdated
func NewModifier(name, value string) martian.RequestResponseModifier { | ||
return &modifier{ | ||
func NewModifier(name, value string) *Modifier { | ||
return &Modifier{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
set the default behavior here:
mod := &Modifier{Name: http.CanonicalHeaderKey(name), Value: value}
mod.SetBehavior(ReplaceValues)
return mod
header/header_modifier.go
Outdated
} | ||
|
||
func (m *Modifier) SetBehavior(b HeaderSetBehavior) { | ||
m.behavior = b | ||
} | ||
|
||
// NewModifier returns a modifier that will set the header at name with | ||
// the given value for both requests and responses. If the header name already |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
update godoc to say that "by default, if header name already exists..."
header/header_modifier.go
Outdated
@@ -74,5 +95,13 @@ func modifierFromJSON(b []byte) (*parse.Result, error) { | |||
|
|||
modifier := NewModifier(msg.Name, msg.Value) | |||
|
|||
if msg.Behavior == "" || msg.Behavior == "replace" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if the default behavior is set in NewModifier, you should only need to do:
if strings.ToLower(msg.Behavior) == "append" {
modifier.SetBehavior(AppendValues)
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could just assume that anything that isn't append
gives you the default replace
behavior.
But, if you'd like to be explicit and return an error on a value that is neither append or default, use a switch:
switch strings.ToLower(msg.Behavior) {
case "append":
modifier.SetBehavior(AppendValues)
case "replace":
modifier.SetBehavior(ReplaceValues)
default:
return nil, fmt.Errorf("Invalid header modifier behavior %q. Must be either %q or %q", msg.Behavior, "append", "replace")
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Went with a switch here, I think silently ignoring the other val would be annoying to debug
header/header_modifier.go
Outdated
return h.Set(m.name, m.value) | ||
} | ||
|
||
func (m *Modifier) SetBehavior(b HeaderSetBehavior) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add comment for exported func
https://github.com/golang/go/wiki/CodeReviewComments#doc-comments
header/header_modifier.go
Outdated
@@ -27,13 +27,17 @@ func init() { | |||
parse.Register("header.Modifier", modifierFromJSON) | |||
} | |||
|
|||
// Behavior when setting a new header with regard to duplicate header names. | |||
type HeaderSetBehavior int |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment should be of the form:
HeaderSetBehavior sets the behavior of...
header/header_modifier.go
Outdated
type HeaderSetBehavior int | ||
|
||
const ( | ||
// Replace all previous headers with the same canonicalized name. | ||
ReplaceValues HeaderSetBehavior = iota |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment should be of the form:
ReplaceValues replaces ...
header/header_modifier.go
Outdated
ReplaceValues HeaderSetBehavior = iota | ||
// Append new header without replacing existing ones. | ||
AppendValues |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment should be of the form:
AppendValues appends...
header/header_modifier.go
Outdated
if msg.Behavior == "" || msg.Behavior == "replace" { | ||
modifier.SetBehavior(ReplaceValues) | ||
} else if msg.Behavior == "append" { | ||
switch msg.Behavior { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
downcase this with strings.ToLower(msg.Behavior)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have any other case insensitive tokens in the Martian API? I'd argue against that sort of behavior only in one place (e.g. why make the behavior enumeration case insensitive and not the "behavior" key itself, or all the JSON keys for that matter?) especially since the API errors if the enumeration doesn't match one of the known values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah ok yeah that's fair
header/header_modifier.go
Outdated
} else if msg.Behavior == "append" { | ||
switch msg.Behavior { | ||
case "": | ||
fallthrough |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we never really use fallthrough
do this in Martian, instead:
case "append", "":
modifier.SetBehavior(AppendValues)
from golint: header/header_modifier.go:31:6: type name will be used as header.HeaderSetBehavior by other packages, and that stutters; consider calling this SetBehavior |
Makes the header set behavior setter's signature sorta interesting func (m *Modifier) SetBehavior(b SetBehavior) { What about // DuplicateBehavior defines the behavior of setting a new header that already exists.
type DuplicateBehavior int
const (
// ReplaceValues replaces all previous headers with the same canonicalized name.
ReplaceValues SetBehavior = iota
// AppendValues appends the new header without replacing existing ones.
AppendValues
)
func (m *Modifier) SetBehavior(b DuplicateBehavior) { |
header/header_append_modifier.go
Outdated
return proxyutil.ResponseHeader(res).Add(m.name, m.value) | ||
} | ||
|
||
// NewAppendModifier returns a appendModifier that will append a header with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/a/an
No description provided.