~adnano/go-gemini

ref: v0.2.2 go-gemini/middleware.go -rw-r--r-- 1.3 KiB
3d2110d9Adnan Maolood mux: Tweak documentation 6 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package gemini

import (
	"context"
	"log"
)

// LoggingMiddleware returns a handler that wraps h and logs Gemini requests
// and their responses to the log package's standard logger.
// Requests are logged with the format "gemini: {host} {URL} {status code} {bytes written}".
func LoggingMiddleware(h Handler) Handler {
	return HandlerFunc(func(ctx context.Context, w ResponseWriter, r *Request) {
		lw := &logResponseWriter{rw: w}
		h.ServeGemini(ctx, lw, r)
		host := r.ServerName()
		log.Printf("gemini: %s %q %d %d", host, r.URL, lw.Status, lw.Wrote)
	})
}

type logResponseWriter struct {
	Status      Status
	Wrote       int
	rw          ResponseWriter
	mediatype   string
	wroteHeader bool
}

func (w *logResponseWriter) SetMediaType(mediatype string) {
	w.mediatype = mediatype
}

func (w *logResponseWriter) Write(b []byte) (int, error) {
	if !w.wroteHeader {
		meta := w.mediatype
		if meta == "" {
			// Use default media type
			meta = defaultMediaType
		}
		w.WriteHeader(StatusSuccess, meta)
	}
	n, err := w.rw.Write(b)
	w.Wrote += n
	return n, err
}

func (w *logResponseWriter) WriteHeader(status Status, meta string) {
	if w.wroteHeader {
		return
	}
	w.wroteHeader = true
	w.Status = status
	w.Wrote += len(meta) + 5
	w.rw.WriteHeader(status, meta)
}

func (w *logResponseWriter) Flush() error {
	return nil
}