Merge pull request #830 from aaronlehmann/no-closenotifier-panic
Don't panic when a http.ResponseWriter does not implement CloseNotifiermaster
						commit
						ec77b836dd
					
				|  | @ -103,17 +103,21 @@ func GetRequestID(ctx Context) string { | ||||||
| // WithResponseWriter returns a new context and response writer that makes
 | // WithResponseWriter returns a new context and response writer that makes
 | ||||||
| // interesting response statistics available within the context.
 | // interesting response statistics available within the context.
 | ||||||
| func WithResponseWriter(ctx Context, w http.ResponseWriter) (Context, http.ResponseWriter) { | func WithResponseWriter(ctx Context, w http.ResponseWriter) (Context, http.ResponseWriter) { | ||||||
| 	closeNotifier, ok := w.(http.CloseNotifier) | 	irw := instrumentedResponseWriter{ | ||||||
| 	if !ok { |  | ||||||
| 		panic("the ResponseWriter does not implement CloseNotifier") |  | ||||||
| 	} |  | ||||||
| 	irw := &instrumentedResponseWriter{ |  | ||||||
| 		ResponseWriter: w, | 		ResponseWriter: w, | ||||||
| 		CloseNotifier:  closeNotifier, |  | ||||||
| 		Context:        ctx, | 		Context:        ctx, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return irw, irw | 	if closeNotifier, ok := w.(http.CloseNotifier); ok { | ||||||
|  | 		irwCN := &instrumentedResponseWriterCN{ | ||||||
|  | 			instrumentedResponseWriter: irw, | ||||||
|  | 			CloseNotifier:              closeNotifier, | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		return irwCN, irwCN | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return &irw, &irw | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // GetResponseWriter returns the http.ResponseWriter from the provided
 | // GetResponseWriter returns the http.ResponseWriter from the provided
 | ||||||
|  | @ -263,11 +267,19 @@ func (ctx *muxVarsContext) Value(key interface{}) interface{} { | ||||||
| 	return ctx.Context.Value(key) | 	return ctx.Context.Value(key) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // instrumentedResponseWriterCN provides response writer information in a
 | ||||||
|  | // context. It implements http.CloseNotifier so that users can detect
 | ||||||
|  | // early disconnects.
 | ||||||
|  | type instrumentedResponseWriterCN struct { | ||||||
|  | 	instrumentedResponseWriter | ||||||
|  | 	http.CloseNotifier | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // instrumentedResponseWriter provides response writer information in a
 | // instrumentedResponseWriter provides response writer information in a
 | ||||||
| // context.
 | // context. This variant is only used in the case where CloseNotifier is not
 | ||||||
|  | // implemented by the parent ResponseWriter.
 | ||||||
| type instrumentedResponseWriter struct { | type instrumentedResponseWriter struct { | ||||||
| 	http.ResponseWriter | 	http.ResponseWriter | ||||||
| 	http.CloseNotifier |  | ||||||
| 	Context | 	Context | ||||||
| 
 | 
 | ||||||
| 	mu      sync.Mutex | 	mu      sync.Mutex | ||||||
|  |  | ||||||
|  | @ -110,13 +110,6 @@ func (trw *testResponseWriter) Header() http.Header { | ||||||
| 	return trw.header | 	return trw.header | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // CloseNotify is only here to make the testResponseWriter implement the
 |  | ||||||
| // http.CloseNotifier interface, which WithResponseWriter expects to be
 |  | ||||||
| // implemented.
 |  | ||||||
| func (trw *testResponseWriter) CloseNotify() <-chan bool { |  | ||||||
| 	return make(chan bool) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (trw *testResponseWriter) Write(p []byte) (n int, err error) { | func (trw *testResponseWriter) Write(p []byte) (n int, err error) { | ||||||
| 	if trw.status == 0 { | 	if trw.status == 0 { | ||||||
| 		trw.status = http.StatusOK | 		trw.status = http.StatusOK | ||||||
|  |  | ||||||
|  | @ -29,7 +29,7 @@ func copyFullPayload(responseWriter http.ResponseWriter, r *http.Request, destWr | ||||||
| 	if notifier, ok := responseWriter.(http.CloseNotifier); ok { | 	if notifier, ok := responseWriter.(http.CloseNotifier); ok { | ||||||
| 		clientClosed = notifier.CloseNotify() | 		clientClosed = notifier.CloseNotify() | ||||||
| 	} else { | 	} else { | ||||||
| 		panic("the ResponseWriter does not implement CloseNotifier") | 		ctxu.GetLogger(context).Warn("the ResponseWriter does not implement CloseNotifier") | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Read in the data, if any.
 | 	// Read in the data, if any.
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue