mirror of
https://github.com/yusing/godoxy.git
synced 2025-07-02 21:34:24 +02:00
tweak(entrypoint): introducing ResponseRecorder specialized for access logger for better throughput
This commit is contained in:
parent
f179de9231
commit
e906b358fa
2 changed files with 73 additions and 9 deletions
|
@ -8,7 +8,6 @@ import (
|
||||||
|
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
"github.com/yusing/go-proxy/internal/logging/accesslog"
|
"github.com/yusing/go-proxy/internal/logging/accesslog"
|
||||||
gphttp "github.com/yusing/go-proxy/internal/net/gphttp"
|
|
||||||
"github.com/yusing/go-proxy/internal/net/gphttp/middleware"
|
"github.com/yusing/go-proxy/internal/net/gphttp/middleware"
|
||||||
"github.com/yusing/go-proxy/internal/net/gphttp/middleware/errorpage"
|
"github.com/yusing/go-proxy/internal/net/gphttp/middleware/errorpage"
|
||||||
"github.com/yusing/go-proxy/internal/route/routes"
|
"github.com/yusing/go-proxy/internal/route/routes"
|
||||||
|
@ -69,19 +68,17 @@ func (ep *Entrypoint) SetAccessLogger(parent task.Parent, cfg *accesslog.Request
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ep *Entrypoint) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (ep *Entrypoint) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if ep.accessLogger != nil {
|
||||||
|
w = accesslog.NewResponseRecorder(w)
|
||||||
|
defer ep.accessLogger.Log(r, w.(*accesslog.ResponseRecorder).Response())
|
||||||
|
}
|
||||||
mux, err := ep.findRouteFunc(r.Host)
|
mux, err := ep.findRouteFunc(r.Host)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if ep.accessLogger != nil {
|
|
||||||
w = gphttp.NewModifyResponseWriter(w, r, func(resp *http.Response) error {
|
|
||||||
ep.accessLogger.Log(r, resp)
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if ep.middleware != nil {
|
if ep.middleware != nil {
|
||||||
ep.middleware.ServeHTTP(mux.ServeHTTP, w, routes.WithRouteContext(r, mux))
|
ep.middleware.ServeHTTP(mux.ServeHTTP, w, routes.WithRouteContext(r, mux))
|
||||||
return
|
} else {
|
||||||
|
mux.ServeHTTP(w, r)
|
||||||
}
|
}
|
||||||
mux.ServeHTTP(w, r)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Why use StatusNotFound instead of StatusBadRequest or StatusBadGateway?
|
// Why use StatusNotFound instead of StatusBadRequest or StatusBadGateway?
|
||||||
|
|
67
internal/logging/accesslog/response_recorder.go
Normal file
67
internal/logging/accesslog/response_recorder.go
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
package accesslog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ResponseRecorder struct {
|
||||||
|
w http.ResponseWriter
|
||||||
|
|
||||||
|
resp http.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewResponseRecorder(w http.ResponseWriter) *ResponseRecorder {
|
||||||
|
return &ResponseRecorder{
|
||||||
|
w: w,
|
||||||
|
resp: http.Response{
|
||||||
|
StatusCode: http.StatusOK,
|
||||||
|
Header: w.Header(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *ResponseRecorder) Unwrap() http.ResponseWriter {
|
||||||
|
return w.w
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *ResponseRecorder) Response() *http.Response {
|
||||||
|
return &w.resp
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *ResponseRecorder) Header() http.Header {
|
||||||
|
return w.w.Header()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *ResponseRecorder) Write(b []byte) (int, error) {
|
||||||
|
n, err := w.w.Write(b)
|
||||||
|
w.resp.ContentLength += int64(n)
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *ResponseRecorder) WriteHeader(code int) {
|
||||||
|
w.w.WriteHeader(code)
|
||||||
|
|
||||||
|
if code >= http.StatusContinue && code < http.StatusOK {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.resp.StatusCode = code
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hijack hijacks the connection.
|
||||||
|
func (w *ResponseRecorder) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
||||||
|
if h, ok := w.w.(http.Hijacker); ok {
|
||||||
|
return h.Hijack()
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil, fmt.Errorf("not a hijacker: %T", w.w)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flush sends any buffered data to the client.
|
||||||
|
func (w *ResponseRecorder) Flush() {
|
||||||
|
if flusher, ok := w.w.(http.Flusher); ok {
|
||||||
|
flusher.Flush()
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue