1
0
Fork 0

Roll all Redirect logic into single function

master
Philip O'Toole 10 months ago
parent 3a0f776e57
commit e9a0a9ebfa

@ -502,12 +502,6 @@ func (s *Service) handleRemove(w http.ResponseWriter, r *http.Request) {
return
}
redirect, err := isRedirect(r)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
b, err := io.ReadAll(r.Body)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
@ -543,13 +537,7 @@ func (s *Service) handleRemove(w http.ResponseWriter, r *http.Request) {
err = s.store.Remove(rn)
if err != nil {
if err == store.ErrNotLeader {
if redirect {
redirect, err := s.FormRedirect(r)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
http.Redirect(w, r, redirect, http.StatusMovedPermanently)
if s.DoRedirect(w, r) {
return
}
@ -605,11 +593,6 @@ func (s *Service) handleBackup(w http.ResponseWriter, r *http.Request) {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
redirect, err := isRedirect(r)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
format, err := backupFormat(w, r)
if err != nil {
@ -638,13 +621,7 @@ func (s *Service) handleBackup(w http.ResponseWriter, r *http.Request) {
err = s.store.Backup(br, w)
if err != nil {
if err == store.ErrNotLeader {
if redirect {
redirect, err := s.FormRedirect(r)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
http.Redirect(w, r, redirect, http.StatusMovedPermanently)
if s.DoRedirect(w, r) {
return
}
@ -716,12 +693,6 @@ func (s *Service) handleLoad(w http.ResponseWriter, r *http.Request) {
return
}
redirect, err := isRedirect(r)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
chunkSz, err := chunkSizeParam(r, defaultChunkSize)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
@ -761,13 +732,9 @@ func (s *Service) handleLoad(w http.ResponseWriter, r *http.Request) {
results, err := s.store.Execute(er)
if err != nil {
if err == store.ErrNotLeader {
redirect, err := s.FormRedirect(r)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
if s.DoRedirect(w, r) {
return
}
http.Redirect(w, r, redirect, http.StatusMovedPermanently)
return
}
resp.Error = err.Error()
} else {
@ -787,13 +754,7 @@ func (s *Service) handleLoad(w http.ResponseWriter, r *http.Request) {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
} else if err != nil && err == store.ErrNotLeader {
if redirect {
redirect, err := s.FormRedirect(r)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
http.Redirect(w, r, redirect, http.StatusMovedPermanently)
if s.DoRedirect(w, r) {
return
}
@ -1221,7 +1182,7 @@ func (s *Service) queuedExecute(w http.ResponseWriter, r *http.Request) {
func (s *Service) execute(w http.ResponseWriter, r *http.Request) {
resp := NewResponse()
timeout, isTx, timings, redirect, noRewriteRandom, err := reqParams(r, defaultTimeout)
timeout, isTx, timings, noRewriteRandom, err := reqParams(r, defaultTimeout)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
@ -1255,13 +1216,7 @@ func (s *Service) execute(w http.ResponseWriter, r *http.Request) {
results, resultsErr := s.store.Execute(er)
if resultsErr != nil && resultsErr == store.ErrNotLeader {
if redirect {
redirect, err := s.FormRedirect(r)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
http.Redirect(w, r, redirect, http.StatusMovedPermanently)
if s.DoRedirect(w, r) {
return
}
@ -1317,7 +1272,7 @@ func (s *Service) handleQuery(w http.ResponseWriter, r *http.Request) {
return
}
timeout, frsh, lvl, isTx, timings, redirect, noRewriteRandom, isAssoc, err := queryReqParams(r, defaultTimeout)
timeout, frsh, lvl, isTx, timings, noRewriteRandom, isAssoc, err := queryReqParams(r, defaultTimeout)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
@ -1355,13 +1310,7 @@ func (s *Service) handleQuery(w http.ResponseWriter, r *http.Request) {
results, resultsErr := s.store.Query(qr)
if resultsErr != nil && resultsErr == store.ErrNotLeader {
if redirect {
redirect, err := s.FormRedirect(r)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
http.Redirect(w, r, redirect, http.StatusMovedPermanently)
if s.DoRedirect(w, r) {
return
}
@ -1414,7 +1363,7 @@ func (s *Service) handleRequest(w http.ResponseWriter, r *http.Request) {
return
}
timeout, frsh, lvl, isTx, timings, redirect, noRewriteRandom, isAssoc, err := executeQueryReqParams(r, defaultTimeout)
timeout, frsh, lvl, isTx, timings, noRewriteRandom, isAssoc, err := executeQueryReqParams(r, defaultTimeout)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
@ -1454,13 +1403,7 @@ func (s *Service) handleRequest(w http.ResponseWriter, r *http.Request) {
results, resultErr := s.store.Request(eqr)
if resultErr != nil && resultErr == store.ErrNotLeader {
if redirect {
redirect, err := s.FormRedirect(r)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
http.Redirect(w, r, redirect, http.StatusMovedPermanently)
if s.DoRedirect(w, r) {
return
}
@ -1548,6 +1491,28 @@ func (s *Service) Addr() net.Addr {
return s.ln.Addr()
}
// DoRedirect checks if the request is a redirect, and if so, performs the redirect.
// Returns true caller can consider the request handled. Returns false if the request
// was not a redirect and the caller should continue processing the request.
func (s *Service) DoRedirect(w http.ResponseWriter, r *http.Request) bool {
redirect, err := isRedirect(r)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return true
}
if !redirect {
return false
}
rd, err := s.FormRedirect(r)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
} else {
http.Redirect(w, r, rd, http.StatusMovedPermanently)
}
return true
}
// FormRedirect returns the value for the "Location" header for a 301 response.
func (s *Service) FormRedirect(r *http.Request) (string, error) {
leaderAPIAddr := s.LeaderAPIAddr()
@ -1919,61 +1884,57 @@ func isQueue(req *http.Request) (bool, error) {
// reqParams is a convenience function to get a bunch of query params
// in one function call.
func reqParams(req *http.Request, def time.Duration) (timeout time.Duration, tx, timings, redirect, noRwRandom bool, err error) {
func reqParams(req *http.Request, def time.Duration) (timeout time.Duration, tx, timings, noRwRandom bool, err error) {
timeout, err = timeoutParam(req, def)
if err != nil {
return 0, false, false, false, true, err
return 0, false, false, true, err
}
tx, err = isTx(req)
if err != nil {
return 0, false, false, false, true, err
return 0, false, false, true, err
}
timings, err = isTimings(req)
if err != nil {
return 0, false, false, false, true, err
}
redirect, err = isRedirect(req)
if err != nil {
return 0, false, false, false, true, err
return 0, false, false, true, err
}
noRwRandom, err = noRewriteRandom(req)
if err != nil {
return 0, false, false, false, true, err
return 0, false, false, true, err
}
return timeout, tx, timings, redirect, noRwRandom, nil
return timeout, tx, timings, noRwRandom, nil
}
// queryReqParams is a convenience function to get a bunch of query params
// in one function call.
func queryReqParams(req *http.Request, def time.Duration) (timeout, frsh time.Duration, lvl command.QueryRequest_Level, isTx, timings, redirect, noRwRandom, isAssoc bool, err error) {
timeout, isTx, timings, redirect, noRwRandom, err = reqParams(req, defaultTimeout)
func queryReqParams(req *http.Request, def time.Duration) (timeout, frsh time.Duration, lvl command.QueryRequest_Level, isTx, timings, noRwRandom, isAssoc bool, err error) {
timeout, isTx, timings, noRwRandom, err = reqParams(req, defaultTimeout)
if err != nil {
return 0, 0, command.QueryRequest_QUERY_REQUEST_LEVEL_WEAK, false, false, false, false, false, err
return 0, 0, command.QueryRequest_QUERY_REQUEST_LEVEL_WEAK, false, false, false, false, err
}
lvl, err = level(req)
if err != nil {
return 0, 0, command.QueryRequest_QUERY_REQUEST_LEVEL_WEAK, false, false, false, false, false, err
return 0, 0, command.QueryRequest_QUERY_REQUEST_LEVEL_WEAK, false, false, false, false, err
}
frsh, err = freshness(req)
if err != nil {
return 0, 0, command.QueryRequest_QUERY_REQUEST_LEVEL_WEAK, false, false, false, false, false, err
return 0, 0, command.QueryRequest_QUERY_REQUEST_LEVEL_WEAK, false, false, false, false, err
}
isAssoc, err = isAssociative(req)
if err != nil {
return 0, 0, command.QueryRequest_QUERY_REQUEST_LEVEL_WEAK, false, false, false, false, false, err
return 0, 0, command.QueryRequest_QUERY_REQUEST_LEVEL_WEAK, false, false, false, false, err
}
return
}
func executeQueryReqParams(req *http.Request, def time.Duration) (timeout, frsh time.Duration, lvl command.QueryRequest_Level, isTx, timings, redirect, noRwRandom, isAssoc bool, err error) {
timeout, frsh, lvl, isTx, timings, redirect, noRwRandom, isAssoc, err = queryReqParams(req, defaultTimeout)
func executeQueryReqParams(req *http.Request, def time.Duration) (timeout, frsh time.Duration, lvl command.QueryRequest_Level, isTx, timings, noRwRandom, isAssoc bool, err error) {
timeout, frsh, lvl, isTx, timings, noRwRandom, isAssoc, err = queryReqParams(req, defaultTimeout)
if err != nil {
return 0, 0, command.QueryRequest_QUERY_REQUEST_LEVEL_WEAK, false, false, false, false, false, err
return 0, 0, command.QueryRequest_QUERY_REQUEST_LEVEL_WEAK, false, false, false, false, err
}
return timeout, frsh, lvl, isTx, timings, redirect, noRwRandom, isAssoc, nil
return timeout, frsh, lvl, isTx, timings, noRwRandom, isAssoc, nil
}
// noLeader returns whether processing should skip the leader check.

Loading…
Cancel
Save