Add timeout to requests

This commit is contained in:
Brandon Dyck 2020-10-11 17:55:27 -06:00
parent 6c885d25c2
commit b7c7c2bf23
3 changed files with 24 additions and 15 deletions

View File

@ -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 {

View File

@ -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),
}), }),
} }

View File

@ -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: