gmifs/gemini/interceptor.go
2021-07-10 12:42:52 +08:00

77 lines
1.9 KiB
Go

package gemini
import (
"bytes"
)
// Interceptor is a ResponseWriter wrapper that may be used as buffer.
//
// A middleware may pass it to the next handlers ServeGemini method as a drop in replacement for the
// response writer. See the logger and cache middlewares for examples.
//
// Note that the body being written two times and the complete caching of the body in the memory.
type Interceptor struct {
// ResponseWriter is the underlying response writer that is wrapped by Interceptor
responseWriter ResponseWriter
// Interceptor is the underlying io.Writer that buffers the response body
Body bytes.Buffer
// <STATUS><SPACE><META><CR><LF>
// Code is the status code.
Code int
// Meta is the header addition, such as the mimetype.
Meta string
hasHeader bool
hasBody bool
}
// NewInterceptor creates a new Interceptor by wrapping the given response writer.
func NewInterceptor(responseWriter ResponseWriter) (m *Interceptor) {
m = &Interceptor{}
m.responseWriter = responseWriter
return
}
// WriteHeader writes the cached status code and tracks this call as change
func (m *Interceptor) WriteHeader(code int, message string) (int, error) {
m.hasHeader = true
m.Code = code
m.Meta = message
return 0, nil
}
// Write writes to the underlying buffer and tracks this call as change
func (m *Interceptor) Write(body []byte) (int, error) {
m.hasBody = true
return m.Body.Write(body)
}
func (m *Interceptor) HasHeader() bool {
return m.hasHeader
}
func (m *Interceptor) HasBody() bool {
return m.hasBody
}
// FlushAll flushes headers, status code and body to the underlying ResponseWriter.
func (m *Interceptor) Flush() {
m.FlushHeader()
m.FlushBody()
}
// FlushBody flushes to the underlying responsewriter.
func (m *Interceptor) FlushBody() {
m.responseWriter.Write(m.Body.Bytes())
}
// FlushHeader writes the header to the underlying ResponseWriter.
func (m *Interceptor) FlushHeader() {
m.responseWriter.WriteHeader(m.Code, m.Meta)
}