package engine import ( "bufio" "net" "net/http" "go_dreamfactory/lego/sys/log" ) const ( noWritten = -1 defaultStatus = http.StatusOK ) type IResponseWriter interface { http.ResponseWriter http.Hijacker http.Flusher http.CloseNotifier /* 返回当前请求的 HTTP 响应状态码。 */ Status() int /* 大小返回已经写入响应 http 正文的字节数 */ Size() int /* WriteHeaderNow 强制写入 http 标头(状态码 + 标头)。 */ WriteHeaderNow() } type ResponseWriter struct { http.ResponseWriter log log.ILogger size int status int } func (this *ResponseWriter) reset(writer http.ResponseWriter) { this.ResponseWriter = writer this.size = noWritten this.status = defaultStatus } func (this *ResponseWriter) WriteHeader(code int) { if code > 0 && this.status != code { if this.Written() { this.log.Warnf("Headers were already written. Wanted to override status code %d with %d", this.status, code) } this.status = code } } func (this *ResponseWriter) Status() int { return this.status } func (this *ResponseWriter) Size() int { return this.size } func (this *ResponseWriter) Written() bool { return this.size != noWritten } // Hijack implements the http.Hijacker interface. func (this *ResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { if this.size < 0 { this.size = 0 } return this.ResponseWriter.(http.Hijacker).Hijack() } func (this *ResponseWriter) CloseNotify() <-chan bool { return this.ResponseWriter.(http.CloseNotifier).CloseNotify() } func (this *ResponseWriter) Flush() { this.WriteHeaderNow() this.ResponseWriter.(http.Flusher).Flush() } func (this *ResponseWriter) WriteHeaderNow() { if !this.Written() { this.size = 0 this.ResponseWriter.WriteHeader(this.status) } } func (this *ResponseWriter) Pusher() (pusher http.Pusher) { if pusher, ok := this.ResponseWriter.(http.Pusher); ok { return pusher } return nil }