1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: Apache-2.0
11 const sniffBytes = 1024
13 type ResponseWriter interface {
20 // responseWriter wraps http.ResponseWriter and exposes the status
21 // sent, the number of bytes sent to the client, and the last write
23 type responseWriter struct {
25 wroteStatus int // First status given to WriteHeader()
26 wroteBodyBytes int // Bytes successfully written
27 err error // Last error returned from Write()
31 func WrapResponseWriter(orig http.ResponseWriter) ResponseWriter {
32 return &responseWriter{ResponseWriter: orig}
35 func (w *responseWriter) CloseNotify() <-chan bool {
36 if cn, ok := w.ResponseWriter.(http.CloseNotifier); ok {
37 return cn.CloseNotify()
42 func (w *responseWriter) WriteHeader(s int) {
43 if w.wroteStatus == 0 {
46 // ...else it's too late to change the status seen by the
47 // client -- but we call the wrapped WriteHeader() anyway so
48 // it can log a warning.
49 w.ResponseWriter.WriteHeader(s)
52 func (w *responseWriter) Write(data []byte) (n int, err error) {
53 if w.wroteStatus == 0 {
54 w.WriteHeader(http.StatusOK)
55 } else if w.wroteStatus >= 400 {
58 n, err = w.ResponseWriter.Write(data)
64 func (w *responseWriter) WroteStatus() int {
68 func (w *responseWriter) WroteBodyBytes() int {
69 return w.wroteBodyBytes
72 func (w *responseWriter) Err() error {
76 func (w *responseWriter) sniff(data []byte) {
77 max := sniffBytes - len(w.sniffed)
80 } else if max < len(data) {
83 w.sniffed = append(w.sniffed, data...)
86 func (w *responseWriter) Sniffed() []byte {