Add timeout to requests
This commit is contained in:
parent
6c885d25c2
commit
b7c7c2bf23
@ -1,7 +1,6 @@
|
|||||||
package front
|
package front
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@ -9,6 +8,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/rickb777/date"
|
"github.com/rickb777/date"
|
||||||
hm "gitlab.codemonkeysoftware.net/b/hatmill"
|
hm "gitlab.codemonkeysoftware.net/b/hatmill"
|
||||||
@ -33,12 +33,14 @@ type handler struct {
|
|||||||
store *back.Store
|
store *back.Store
|
||||||
title string
|
title string
|
||||||
baseURL string
|
baseURL string
|
||||||
|
timeout time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
type HandlerParams struct {
|
type HandlerParams struct {
|
||||||
Title string
|
Title string
|
||||||
Store *back.Store
|
Store *back.Store
|
||||||
BaseURL string
|
BaseURL string
|
||||||
|
Timeout time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHandler(params HandlerParams) http.Handler {
|
func NewHandler(params HandlerParams) http.Handler {
|
||||||
@ -47,18 +49,23 @@ func NewHandler(params HandlerParams) http.Handler {
|
|||||||
title: params.Title,
|
title: params.Title,
|
||||||
baseURL: params.BaseURL,
|
baseURL: params.BaseURL,
|
||||||
mux: http.NewServeMux(),
|
mux: http.NewServeMux(),
|
||||||
|
timeout: params.Timeout,
|
||||||
}
|
}
|
||||||
h.mux.HandleFunc(pathRoot, h.handleRoot)
|
h.handleFunc(pathRoot, h.handleRoot)
|
||||||
h.mux.HandleFunc(pathCreate, h.handleCreate)
|
h.handleFunc(pathCreate, h.handleCreate)
|
||||||
h.mux.HandleFunc(pathDoCreate, h.handleDoCreate)
|
h.handleFunc(pathDoCreate, h.handleDoCreate)
|
||||||
h.mux.HandleFunc(pathAdmin, h.handleAdmin)
|
h.handleFunc(pathAdmin, h.handleAdmin)
|
||||||
h.mux.HandleFunc(pathVote, h.handleVote)
|
h.handleFunc(pathVote, h.handleVote)
|
||||||
h.mux.HandleFunc(pathDoVote, h.handleDoVote)
|
h.handleFunc(pathDoVote, h.handleDoVote)
|
||||||
h.mux.HandleFunc(pathVoteSuccess, h.handleVoteSuccess)
|
h.handleFunc(pathVoteSuccess, h.handleVoteSuccess)
|
||||||
h.mux.HandleFunc(pathCreateSuccess, h.handleCreateSuccess)
|
h.handleFunc(pathCreateSuccess, h.handleCreateSuccess)
|
||||||
return h
|
return h
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *handler) handleFunc(pattern string, handler func(http.ResponseWriter, *http.Request)) {
|
||||||
|
h.mux.Handle(pattern, http.TimeoutHandler(http.HandlerFunc(handler), h.timeout, ""))
|
||||||
|
}
|
||||||
|
|
||||||
func (h *handler) handleRoot(w http.ResponseWriter, r *http.Request) {
|
func (h *handler) handleRoot(w http.ResponseWriter, r *http.Request) {
|
||||||
body := hm.Terms{
|
body := hm.Terms{
|
||||||
e.A(a.Href(pathCreate))(
|
e.A(a.Href(pathCreate))(
|
||||||
@ -154,7 +161,7 @@ func internalServerError(w http.ResponseWriter, err error) bool {
|
|||||||
|
|
||||||
func (h *handler) handleVote(w http.ResponseWriter, r *http.Request) {
|
func (h *handler) handleVote(w http.ResponseWriter, r *http.Request) {
|
||||||
eventAlphaID := r.URL.Query().Get(fieldNameEventID)
|
eventAlphaID := r.URL.Query().Get(fieldNameEventID)
|
||||||
event, err := h.store.GetEventMetadata(context.Background(), back.GetEventMetadataQuery{
|
event, err := h.store.GetEventMetadata(r.Context(), back.GetEventMetadataQuery{
|
||||||
EventID: eventAlphaID,
|
EventID: eventAlphaID,
|
||||||
})
|
})
|
||||||
if notFound(w, err, "Event not found") || internalServerError(w, err) {
|
if notFound(w, err, "Event not found") || internalServerError(w, err) {
|
||||||
@ -284,7 +291,7 @@ func (h *handler) handleDoCreate(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
description := r.FormValue(fieldNameDescription)
|
description := r.FormValue(fieldNameDescription)
|
||||||
|
|
||||||
event, err := h.store.CreateEvent(context.Background(), back.CreateEventCommand{
|
event, err := h.store.CreateEvent(r.Context(), back.CreateEventCommand{
|
||||||
Name: eventName,
|
Name: eventName,
|
||||||
Description: description,
|
Description: description,
|
||||||
Earliest: earliest,
|
Earliest: earliest,
|
||||||
@ -305,7 +312,7 @@ func (h *handler) blockUnauthorizedAdmin(w http.ResponseWriter, r *http.Request)
|
|||||||
eventID := r.URL.Query().Get(fieldNameEventID)
|
eventID := r.URL.Query().Get(fieldNameEventID)
|
||||||
adminCode := r.URL.Query().Get(fieldNameAdminCode)
|
adminCode := r.URL.Query().Get(fieldNameAdminCode)
|
||||||
|
|
||||||
err := h.store.AuthorizeEventAdmin(context.Background(), back.CheckEventAdminCodeQuery{
|
err := h.store.AuthorizeEventAdmin(r.Context(), back.CheckEventAdminCodeQuery{
|
||||||
EventID: eventID,
|
EventID: eventID,
|
||||||
AdminCode: adminCode,
|
AdminCode: adminCode,
|
||||||
})
|
})
|
||||||
@ -377,14 +384,14 @@ func (h *handler) handleAdmin(w http.ResponseWriter, r *http.Request) {
|
|||||||
query := r.URL.Query()
|
query := r.URL.Query()
|
||||||
eventID := query.Get(fieldNameEventID)
|
eventID := query.Get(fieldNameEventID)
|
||||||
|
|
||||||
metadata, err := h.store.GetEventMetadata(context.Background(), back.GetEventMetadataQuery{
|
metadata, err := h.store.GetEventMetadata(r.Context(), back.GetEventMetadataQuery{
|
||||||
EventID: eventID,
|
EventID: eventID,
|
||||||
})
|
})
|
||||||
if notFound(w, err, "Event not found") || internalServerError(w, err) {
|
if notFound(w, err, "Event not found") || internalServerError(w, err) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
summary, err := h.store.GetEventResponseSummary(context.Background(), back.GetEventResponseSummaryQuery{
|
summary, err := h.store.GetEventResponseSummary(r.Context(), back.GetEventResponseSummaryQuery{
|
||||||
EventID: eventID,
|
EventID: eventID,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
3
main.go
3
main.go
@ -4,6 +4,7 @@ import (
|
|||||||
"flag"
|
"flag"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
"gitlab.codemonkeysoftware.net/b/henwen/internal/back"
|
"gitlab.codemonkeysoftware.net/b/henwen/internal/back"
|
||||||
"gitlab.codemonkeysoftware.net/b/henwen/internal/front"
|
"gitlab.codemonkeysoftware.net/b/henwen/internal/front"
|
||||||
@ -14,6 +15,7 @@ func main() {
|
|||||||
title := flag.String("title", "Henwen", "website title")
|
title := flag.String("title", "Henwen", "website title")
|
||||||
baseURL := flag.String("baseURL", "http://localhost:8080", "base URL for HTTP routes")
|
baseURL := flag.String("baseURL", "http://localhost:8080", "base URL for HTTP routes")
|
||||||
dbFileName := flag.String("db", "./henwen.db", "name of database file")
|
dbFileName := flag.String("db", "./henwen.db", "name of database file")
|
||||||
|
httpTimeout := flag.Int("httpTimeout", 5000, "HTTP server timeout in ms")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
store, err := back.NewStore(*dbFileName, back.SecureGenString)
|
store, err := back.NewStore(*dbFileName, back.SecureGenString)
|
||||||
@ -27,6 +29,7 @@ func main() {
|
|||||||
Store: store,
|
Store: store,
|
||||||
Title: *title,
|
Title: *title,
|
||||||
BaseURL: *baseURL,
|
BaseURL: *baseURL,
|
||||||
|
Timeout: time.Millisecond * time.Duration(*httpTimeout),
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1
todo.txt
1
todo.txt
@ -5,7 +5,6 @@ Add a schema ID to the DB
|
|||||||
Require earliest and latest dates for creation
|
Require earliest and latest dates for creation
|
||||||
Ensure latest date is at least earliest date
|
Ensure latest date is at least earliest date
|
||||||
Ensure date span is within a maximum
|
Ensure date span is within a maximum
|
||||||
Add timeout to request context
|
|
||||||
Prevent blank event names and guest names
|
Prevent blank event names and guest names
|
||||||
|
|
||||||
Cleanup:
|
Cleanup:
|
||||||
|
Loading…
Reference in New Issue
Block a user