2021-01-20 04:47:43 +03:00
// Copyright 2021 The Gitea Authors. All rights reserved.
2022-11-27 21:20:29 +03:00
// SPDX-License-Identifier: MIT
2021-01-20 04:47:43 +03:00
package context
2021-04-14 15:57:18 +03:00
import (
"net/http"
)
2021-01-20 04:47:43 +03:00
// ResponseWriter represents a response writer for HTTP
type ResponseWriter interface {
http . ResponseWriter
Flush ( )
Status ( ) int
2021-01-26 18:36:53 +03:00
Before ( func ( ResponseWriter ) )
2021-01-27 20:46:35 +03:00
Size ( ) int
2021-01-20 04:47:43 +03:00
}
2022-01-20 20:46:10 +03:00
var _ ResponseWriter = & Response { }
2021-01-20 04:47:43 +03:00
// Response represents a response
type Response struct {
http . ResponseWriter
2021-01-27 20:46:35 +03:00
written int
2021-01-26 18:36:53 +03:00
status int
befores [ ] func ( ResponseWriter )
beforeExecuted bool
2021-01-20 04:47:43 +03:00
}
2021-01-27 20:46:35 +03:00
// Size return written size
func ( r * Response ) Size ( ) int {
return r . written
}
2021-01-20 04:47:43 +03:00
// Write writes bytes to HTTP endpoint
func ( r * Response ) Write ( bs [ ] byte ) ( int , error ) {
2021-01-26 18:36:53 +03:00
if ! r . beforeExecuted {
for _ , before := range r . befores {
before ( r )
}
r . beforeExecuted = true
}
2021-01-20 04:47:43 +03:00
size , err := r . ResponseWriter . Write ( bs )
2021-01-27 20:46:35 +03:00
r . written += size
2021-01-20 04:47:43 +03:00
if err != nil {
2021-01-27 20:46:35 +03:00
return size , err
2021-01-20 04:47:43 +03:00
}
if r . status == 0 {
2021-05-14 11:05:50 +03:00
r . status = http . StatusOK
2021-01-20 04:47:43 +03:00
}
return size , nil
}
// WriteHeader write status code
func ( r * Response ) WriteHeader ( statusCode int ) {
2021-01-26 18:36:53 +03:00
if ! r . beforeExecuted {
for _ , before := range r . befores {
before ( r )
}
r . beforeExecuted = true
}
2021-04-14 15:57:18 +03:00
if r . status == 0 {
r . status = statusCode
r . ResponseWriter . WriteHeader ( statusCode )
}
2021-01-20 04:47:43 +03:00
}
// Flush flush cached data
func ( r * Response ) Flush ( ) {
if f , ok := r . ResponseWriter . ( http . Flusher ) ; ok {
f . Flush ( )
}
}
// Status returned status code written
func ( r * Response ) Status ( ) int {
return r . status
}
2021-01-26 18:36:53 +03:00
// Before allows for a function to be called before the ResponseWriter has been written to. This is
// useful for setting headers or any other operations that must happen before a response has been written.
func ( r * Response ) Before ( f func ( ResponseWriter ) ) {
r . befores = append ( r . befores , f )
}
2021-01-20 04:47:43 +03:00
// NewResponse creates a response
func NewResponse ( resp http . ResponseWriter ) * Response {
if v , ok := resp . ( * Response ) ; ok {
return v
}
2021-01-26 18:36:53 +03:00
return & Response {
ResponseWriter : resp ,
status : 0 ,
befores : make ( [ ] func ( ResponseWriter ) , 0 ) ,
}
2021-01-20 04:47:43 +03:00
}