Compare commits
3 commits
f2e52a18e5
...
eb0c264ad7
| Author | SHA1 | Date | |
|---|---|---|---|
| eb0c264ad7 | |||
| 6e56cefe6f | |||
| 06495fa358 |
3 changed files with 57 additions and 48 deletions
|
|
@ -6,8 +6,10 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
"forgejo.gwairfelin.com/max/gonotes/internal/conf"
|
"forgejo.gwairfelin.com/max/gonotes/internal/conf"
|
||||||
|
"forgejo.gwairfelin.com/max/gonotes/internal/middleware"
|
||||||
"forgejo.gwairfelin.com/max/gonotes/internal/notes/views"
|
"forgejo.gwairfelin.com/max/gonotes/internal/notes/views"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -24,12 +26,22 @@ func main() {
|
||||||
router := http.NewServeMux()
|
router := http.NewServeMux()
|
||||||
notesRouter := views.GetRoutes("/notes")
|
notesRouter := views.GetRoutes("/notes")
|
||||||
|
|
||||||
router.Handle("/", logger(http.RedirectHandler("/notes/", http.StatusFound)))
|
cacheExpiration, err := time.ParseDuration("24h")
|
||||||
router.Handle("/notes/", logger(http.StripPrefix("/notes", notesRouter)))
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
etag := middleware.NewETag("static", cacheExpiration)
|
||||||
|
|
||||||
|
router.Handle("/", middleware.LoggingMiddleware(http.RedirectHandler("/notes/", http.StatusFound)))
|
||||||
|
router.Handle("/notes/", middleware.LoggingMiddleware(http.StripPrefix("/notes", notesRouter)))
|
||||||
router.Handle(
|
router.Handle(
|
||||||
"/static/",
|
"/static/",
|
||||||
logger(
|
middleware.LoggingMiddleware(
|
||||||
http.FileServer(http.FS(conf.Static)),
|
middleware.StaticEtagMiddleware(
|
||||||
|
*etag,
|
||||||
|
http.FileServer(http.FS(conf.Static)),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -39,28 +51,3 @@ func main() {
|
||||||
}
|
}
|
||||||
log.Fatal(http.Serve(listener, router))
|
log.Fatal(http.Serve(listener, router))
|
||||||
}
|
}
|
||||||
|
|
||||||
type loggingResponseWriter struct {
|
|
||||||
http.ResponseWriter
|
|
||||||
statusCode int
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewLoggingResponseWriter(w http.ResponseWriter) *loggingResponseWriter {
|
|
||||||
return &loggingResponseWriter{w, http.StatusOK}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *loggingResponseWriter) WriteHeader(code int) {
|
|
||||||
w.statusCode = code
|
|
||||||
w.ResponseWriter.WriteHeader(code)
|
|
||||||
}
|
|
||||||
|
|
||||||
func logger(next http.Handler) http.Handler {
|
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
lwr := NewLoggingResponseWriter(w)
|
|
||||||
next.ServeHTTP(lwr, r)
|
|
||||||
|
|
||||||
if conf.Conf.LogAccess {
|
|
||||||
log.Printf("%s %s %s%s %d", r.RemoteAddr, r.Method, r.Host, r.URL.Path, lwr.statusCode)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
|
// Middleware to add naive caching headers
|
||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"hash/crc64"
|
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
@ -13,13 +13,10 @@ type ETag struct {
|
||||||
Name string
|
Name string
|
||||||
Value string
|
Value string
|
||||||
Expiration time.Duration
|
Expiration time.Duration
|
||||||
HashTime time.Duration
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var etags = make([]*ETag, 0)
|
|
||||||
|
|
||||||
func (etag *ETag) Header() string {
|
func (etag *ETag) Header() string {
|
||||||
return fmt.Sprintf("\"pb-%s-%s\"", etag.Name, etag.Value)
|
return fmt.Sprintf("\"gn-%s-%s\"", etag.Name, etag.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (etag *ETag) CacheControlHeader() string {
|
func (etag *ETag) CacheControlHeader() string {
|
||||||
|
|
@ -46,21 +43,10 @@ func StaticEtagMiddleware(etag ETag, next http.Handler) http.Handler {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenerateETagFromBuffer calculates etag value from one or more buffers (e.g. embedded files)
|
// GenerateETagFromBuffer calculates etag value from one or more buffers (e.g. embedded files)
|
||||||
func GenerateETagFromBuffer(name string, expiration time.Duration, buffers ...[]byte) (*ETag, error) {
|
func NewETag(name string, expiration time.Duration) *ETag {
|
||||||
start := time.Now()
|
return &ETag{
|
||||||
hash := crc64.New(crc64.MakeTable(crc64.ECMA))
|
|
||||||
for _, buffer := range buffers {
|
|
||||||
_, err := hash.Write(buffer)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("unable to generate etag from buffer: %w", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
etag := &ETag{
|
|
||||||
Name: name,
|
Name: name,
|
||||||
Expiration: expiration,
|
Expiration: expiration,
|
||||||
Value: fmt.Sprintf("%x", hash.Sum64()),
|
Value: fmt.Sprintf("%d", time.Now().Unix()),
|
||||||
HashTime: time.Since(start),
|
|
||||||
}
|
}
|
||||||
etags = append(etags, etag)
|
|
||||||
return etag, nil
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
36
internal/middleware/logger.go
Normal file
36
internal/middleware/logger.go
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
// Middleware to Log out requests and response status code
|
||||||
|
package middleware
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"forgejo.gwairfelin.com/max/gonotes/internal/conf"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Response writer that store the status code for logging
|
||||||
|
type loggingResponseWriter struct {
|
||||||
|
http.ResponseWriter
|
||||||
|
statusCode int
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewLoggingResponseWriter(w http.ResponseWriter) *loggingResponseWriter {
|
||||||
|
return &loggingResponseWriter{w, http.StatusOK}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *loggingResponseWriter) WriteHeader(code int) {
|
||||||
|
w.statusCode = code
|
||||||
|
w.ResponseWriter.WriteHeader(code)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Middleware to log out requests and response status code
|
||||||
|
func LoggingMiddleware(next http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
lwr := NewLoggingResponseWriter(w)
|
||||||
|
next.ServeHTTP(lwr, r)
|
||||||
|
|
||||||
|
if conf.Conf.LogAccess {
|
||||||
|
log.Printf("%s %s %s%s %d", r.RemoteAddr, r.Method, r.Host, r.URL.Path, lwr.statusCode)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue