-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Fixing ResponseWriter to assert to http.Flusher in /sys/monitor endpoint #13200
Conversation
…ResponseWriter issues
http/handler.go
Outdated
statusCode: 200, | ||
headers: listenerCustomHeaders.StatusCodeHeaderMap, | ||
} | ||
nw.SetHeaders(listenerCustomHeaders.StatusCodeHeaderMap) |
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.
Why introduce a method for this instead of just making it an argument to the constructor?
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.
The new responseWriter nw
needs to be instantiated even if the props.ListenerConfig
is nil.
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.
Sorry, I'm not following. What would break if we got rid of SetHeaders and instead assigned listenerCustomHeaders.StatusCodeHeaderMap to a local var here? Then passed that var as a 2nd arg to logical.NewStatusHeaderResponseWriter?
My primary goal here is to minimize mutable state in the type.
http/logical.go
Outdated
@@ -199,7 +199,7 @@ func buildLogicalRequestNoAuth(perfStandby bool, w http.ResponseWriter, r *http. | |||
req.HTTPRequest = r | |||
} | |||
if responseWriter != nil { | |||
req.ResponseWriter = logical.NewHTTPResponseWriter(responseWriter) | |||
req.ResponseWriter = logical.NewStatusHeaderResponseWriter(responseWriter) |
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.
Why do we need to re-wrap? Why can't we just assign responseWriter directly?
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.
So, responseWriter is of type http.ResponseWriter. if I assign that directly, then, where ever we would need extra functionality like ResponseWriter.Written()
, we would need to assert the WrappingResponseWriter
interface first. Although there are not many places right now for such functionality, it is easy to miss fixing those. It is not just the Written()
function as well.
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.
Is it though? I thought everything was wrapped by wrapGenericHandler, and it's always passing down a response writer of the new type.
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.
hmm, I think so? The function signature of this function defines w http.ResponseWriter
which is assigned to responseWriter
. But, another thing is that of which type should the req.ResponseWriter
be defined? should it be http.ResponseWriter
, or logical.StatusHeaderResponseWriter
?
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 wasn't speaking in terms of function signature, I'm saying that since wrapGenericHandler is wrapping all request handlers, we shouldn't need to wrap the response handler again. And if we don't need to handle re-wrapping I think some of the code will be simplified.
I think we should probably stick with http.ResponseWriter, but that's mostly because I expect trying to switch it would cause problems. If it's possible to use StatusHeaderResponseWriter without it being really disruptive, that could make sense.
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.
Sounds good! I will stick with http.ResponseWriter.
sdk/logical/response.go
Outdated
Wrapped() http.ResponseWriter | ||
SetHeaders(h map[string][]*CustomHeader) | ||
GetHeaders() map[string][]*CustomHeader | ||
StatusCode() 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.
Is this actually used?
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 found the issue in this PR while I was working at the logging requests feature. So, this is not needed now, but it is needed then.
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 are right, this is not needed. Fixing it in both PRs. Thanks!
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.
Looking very close!
sdk/logical/request.go
Outdated
@@ -203,7 +203,7 @@ type Request struct { | |||
|
|||
// ResponseWriter if set can be used to stream a response value to the http | |||
// request that generated this logical.Request object. | |||
ResponseWriter *HTTPResponseWriter `json:"-" sentinel:""` | |||
ResponseWriter *http.ResponseWriter `json:"-" sentinel:""` |
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'd rather use the explicit type here than the interface, since there aren't any cases where we'll be using anything other than that type.
@@ -127,8 +128,9 @@ func TestCustomResponseHeadersConfigInteractUiConfig(t *testing.T) { | |||
t.Fatalf("custom header config should be configured in core") | |||
} | |||
|
|||
w := httptest.NewRecorder() | |||
hw := logical.NewHTTPResponseWriter(w) | |||
hw := func(w http.ResponseWriter) *http.ResponseWriter { |
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.
This is a rather complicated way to avoid defining a variable.
http/handler.go
Outdated
statusCode: 200, | ||
headers: listenerCustomHeaders.StatusCodeHeaderMap, | ||
} | ||
nw.SetHeaders(listenerCustomHeaders.StatusCodeHeaderMap) |
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.
Sorry, I'm not following. What would break if we got rid of SetHeaders and instead assigned listenerCustomHeaders.StatusCodeHeaderMap to a local var here? Then passed that var as a 2nd arg to logical.NewStatusHeaderResponseWriter?
My primary goal here is to minimize mutable state in the type.
sdk/logical/response.go
Outdated
written *uint32 | ||
} | ||
|
||
func NewStatusHeaderResponseWriter (w http.ResponseWriter) *StatusHeaderResponseWriter { |
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.
func NewStatusHeaderResponseWriter (w http.ResponseWriter) *StatusHeaderResponseWriter { | |
func NewStatusHeaderResponseWriter(w http.ResponseWriter) *StatusHeaderResponseWriter { |
* Unify NewHTTPResponseWriter ant NewStatusHeaderResponseWriter to fix ResponseWriter issues * adding changelog * removing unnecessary function from the WrappingResponseWriter interface * changing logical requests responseWriter type * reverting change to HTTPResponseWriter
…ys/monitor endpoint (#13200) (#13260) * Unify HTTPResponseWriter and StatusHeaderResponseWriter (#13200) * Unify NewHTTPResponseWriter ant NewStatusHeaderResponseWriter to fix ResponseWriter issues * adding changelog * removing unnecessary function from the WrappingResponseWriter interface * changing logical requests responseWriter type * reverting change to HTTPResponseWriter * Update changelog/13200.txt * Update changelog/13200.txt
There are a number of interfaces that implement http.ResponseWriter. For that, wrapping http.ResponseWriter needs a lot of care.
StatusHeaderResponseWriter is instantiated in the http layer which wraps http.ResponseWriter. Then, HTTPResponseWriter wraps the already wrapped ResponseWriter. This causes issues as for example in the
sys/monitor
, thehttp.Flusher
cannot be asserted and calling the endpoint returnsstream not supported