cookie based routes
All checks were successful
Build and Publish / BuildAndDeployAmd64 (push) Successful in 34s
Build and Publish / BuildAndDeploy (push) Successful in 2m21s

This commit is contained in:
matst80
2024-11-16 12:02:16 +01:00
parent 75796e7da1
commit d77b1edacb

View File

@@ -8,7 +8,6 @@ import (
"net/http" "net/http"
"os" "os"
"strconv" "strconv"
"strings"
"time" "time"
messages "git.tornberg.me/go-cart-actor/proto" messages "git.tornberg.me/go-cart-actor/proto"
@@ -27,20 +26,17 @@ func NewPoolServer(pool GrainPool, pod_name string) *PoolServer {
} }
} }
func (s *PoolServer) HandleGet(w http.ResponseWriter, r *http.Request) error { func (s *PoolServer) HandleGet(w http.ResponseWriter, r *http.Request, id CartId) error {
id := r.PathValue("id") data, err := s.pool.Get(id)
data, err := s.pool.Get(ToCartId(id))
if err != nil { if err != nil {
return err return err
} }
return s.WriteResult(w, data) return s.WriteResult(w, data)
} }
func (s *PoolServer) HandleAddSku(w http.ResponseWriter, r *http.Request) error { func (s *PoolServer) HandleAddSku(w http.ResponseWriter, r *http.Request, id CartId) error {
id := r.PathValue("id")
sku := r.PathValue("sku") sku := r.PathValue("sku")
data, err := s.pool.Process(ToCartId(id), Message{ data, err := s.pool.Process(id, Message{
Type: AddRequestType, Type: AddRequestType,
Content: &messages.AddRequest{Sku: sku, Quantity: 1}, Content: &messages.AddRequest{Sku: sku, Quantity: 1},
}) })
@@ -81,14 +77,14 @@ func (s *PoolServer) WriteResult(w http.ResponseWriter, result *FrameWithPayload
return err return err
} }
func (s *PoolServer) HandleDeleteItem(w http.ResponseWriter, r *http.Request) error { func (s *PoolServer) HandleDeleteItem(w http.ResponseWriter, r *http.Request, id CartId) error {
id := r.PathValue("id")
itemIdString := r.PathValue("itemId") itemIdString := r.PathValue("itemId")
itemId, err := strconv.Atoi(itemIdString) itemId, err := strconv.Atoi(itemIdString)
if err != nil { if err != nil {
return err return err
} }
data, err := s.pool.Process(ToCartId(id), Message{ data, err := s.pool.Process(id, Message{
Type: RemoveItemType, Type: RemoveItemType,
Content: &messages.RemoveItem{Id: int64(itemId)}, Content: &messages.RemoveItem{Id: int64(itemId)},
}) })
@@ -103,14 +99,14 @@ type SetDelivery struct {
Items []int64 `json:"items"` Items []int64 `json:"items"`
} }
func (s *PoolServer) HandleSetDelivery(w http.ResponseWriter, r *http.Request) error { func (s *PoolServer) HandleSetDelivery(w http.ResponseWriter, r *http.Request, id CartId) error {
id := r.PathValue("id")
delivery := SetDelivery{} delivery := SetDelivery{}
err := json.NewDecoder(r.Body).Decode(&delivery) err := json.NewDecoder(r.Body).Decode(&delivery)
if err != nil { if err != nil {
return err return err
} }
data, err := s.pool.Process(ToCartId(id), Message{ data, err := s.pool.Process(id, Message{
Type: SetDeliveryType, Type: SetDeliveryType,
Content: &messages.SetDelivery{ Content: &messages.SetDelivery{
Provider: delivery.Provider, Provider: delivery.Provider,
@@ -123,8 +119,8 @@ func (s *PoolServer) HandleSetDelivery(w http.ResponseWriter, r *http.Request) e
return s.WriteResult(w, data) return s.WriteResult(w, data)
} }
func (s *PoolServer) HandleSetPickupPoint(w http.ResponseWriter, r *http.Request) error { func (s *PoolServer) HandleSetPickupPoint(w http.ResponseWriter, r *http.Request, id CartId) error {
id := r.PathValue("id")
deliveryIdString := r.PathValue("deliveryId") deliveryIdString := r.PathValue("deliveryId")
deliveryId, err := strconv.Atoi(deliveryIdString) deliveryId, err := strconv.Atoi(deliveryIdString)
if err != nil { if err != nil {
@@ -135,7 +131,7 @@ func (s *PoolServer) HandleSetPickupPoint(w http.ResponseWriter, r *http.Request
if err != nil { if err != nil {
return err return err
} }
reply, err := s.pool.Process(ToCartId(id), Message{ reply, err := s.pool.Process(id, Message{
Type: SetPickupPointType, Type: SetPickupPointType,
Content: &messages.SetPickupPoint{ Content: &messages.SetPickupPoint{
DeliveryId: int64(deliveryId), DeliveryId: int64(deliveryId),
@@ -153,14 +149,14 @@ func (s *PoolServer) HandleSetPickupPoint(w http.ResponseWriter, r *http.Request
return s.WriteResult(w, reply) return s.WriteResult(w, reply)
} }
func (s *PoolServer) HandleRemoveDelivery(w http.ResponseWriter, r *http.Request) error { func (s *PoolServer) HandleRemoveDelivery(w http.ResponseWriter, r *http.Request, id CartId) error {
id := r.PathValue("id")
deliveryIdString := r.PathValue("deliveryId") deliveryIdString := r.PathValue("deliveryId")
deliveryId, err := strconv.Atoi(deliveryIdString) deliveryId, err := strconv.Atoi(deliveryIdString)
if err != nil { if err != nil {
return err return err
} }
reply, err := s.pool.Process(ToCartId(id), Message{ reply, err := s.pool.Process(id, Message{
Type: RemoveDeliveryType, Type: RemoveDeliveryType,
Content: &messages.RemoveDelivery{Id: int64(deliveryId)}, Content: &messages.RemoveDelivery{Id: int64(deliveryId)},
}) })
@@ -170,15 +166,13 @@ func (s *PoolServer) HandleRemoveDelivery(w http.ResponseWriter, r *http.Request
return s.WriteResult(w, reply) return s.WriteResult(w, reply)
} }
func (s *PoolServer) HandleQuantityChange(w http.ResponseWriter, r *http.Request) error { func (s *PoolServer) HandleQuantityChange(w http.ResponseWriter, r *http.Request, id CartId) error {
id := r.PathValue("id")
changeQuantity := messages.ChangeQuantity{} changeQuantity := messages.ChangeQuantity{}
err := json.NewDecoder(r.Body).Decode(&changeQuantity) err := json.NewDecoder(r.Body).Decode(&changeQuantity)
if err != nil { if err != nil {
return err return err
} }
reply, err := s.pool.Process(ToCartId(id), Message{ reply, err := s.pool.Process(id, Message{
Type: ChangeQuantityType, Type: ChangeQuantityType,
Content: &changeQuantity, Content: &changeQuantity,
}) })
@@ -188,15 +182,13 @@ func (s *PoolServer) HandleQuantityChange(w http.ResponseWriter, r *http.Request
return s.WriteResult(w, reply) return s.WriteResult(w, reply)
} }
func (s *PoolServer) HandleAddRequest(w http.ResponseWriter, r *http.Request) error { func (s *PoolServer) HandleAddRequest(w http.ResponseWriter, r *http.Request, id CartId) error {
id := r.PathValue("id")
addRequest := messages.AddRequest{} addRequest := messages.AddRequest{}
err := json.NewDecoder(r.Body).Decode(&addRequest) err := json.NewDecoder(r.Body).Decode(&addRequest)
if err != nil { if err != nil {
return err return err
} }
reply, err := s.pool.Process(ToCartId(id), Message{ reply, err := s.pool.Process(id, Message{
Type: AddRequestType, Type: AddRequestType,
Content: &addRequest, Content: &addRequest,
}) })
@@ -211,10 +203,9 @@ var (
APIPassword = os.Getenv("KLARNA_API_PASSWORD") APIPassword = os.Getenv("KLARNA_API_PASSWORD")
) )
func (s *PoolServer) HandleCheckout(w http.ResponseWriter, r *http.Request) error { func (s *PoolServer) HandleCheckout(w http.ResponseWriter, r *http.Request, id CartId) error {
id := r.PathValue("id")
reply, err := s.pool.Process(ToCartId(id), Message{ reply, err := s.pool.Process(id, Message{
Type: CreateCheckoutOrderType, Type: CreateCheckoutOrderType,
Content: &messages.CreateCheckoutOrder{ Content: &messages.CreateCheckoutOrder{
Terms: "https://tornberg.me/terms", Terms: "https://tornberg.me/terms",
@@ -261,48 +252,60 @@ func NewCartId() CartId {
return ToCartId(fmt.Sprintf("%d", id)) return ToCartId(fmt.Sprintf("%d", id))
} }
func (a *PoolServer) RewritePath(w http.ResponseWriter, r *http.Request) { func CookieCartIdHandler(fn func(w http.ResponseWriter, r *http.Request, cartId CartId) error) func(w http.ResponseWriter, r *http.Request) error {
var cartId CartId return func(w http.ResponseWriter, r *http.Request) error {
if strings.Contains(r.URL.Path, ".") { var cartId CartId
http.NotFound(w, r) cartIdCookie := r.CookiesNamed("cartid")
return if cartIdCookie == nil || len(cartIdCookie) == 0 {
cartId = NewCartId()
http.SetCookie(w, &http.Cookie{
Name: "cartid",
Value: cartId.String(),
Path: "/",
SameSite: http.SameSiteLaxMode,
})
} else {
cartId = ToCartId(cartIdCookie[0].Value)
}
return fn(w, r, cartId)
} }
cartIdCookie := r.CookiesNamed("cartid") }
if cartIdCookie == nil || len(cartIdCookie) == 0 {
cartId = NewCartId() func CartIdHandler(fn func(w http.ResponseWriter, r *http.Request, cartId CartId) error) func(w http.ResponseWriter, r *http.Request) error {
http.SetCookie(w, &http.Cookie{ return func(w http.ResponseWriter, r *http.Request) error {
Name: "cartid", cartId := ToCartId(r.PathValue("id"))
Value: cartId.String(), return fn(w, r, cartId)
Path: "/",
SameSite: http.SameSiteLaxMode,
})
} else {
cartId = ToCartId(cartIdCookie[0].Value)
} }
adjustedPath := strings.Replace(r.URL.Path, "/cart", "", 1)
location := fmt.Sprintf("/cart/%s%s", cartId, strings.TrimRight(adjustedPath, "/"))
w.Header().Set("Location", location)
w.WriteHeader(http.StatusMovedPermanently)
} }
func (s *PoolServer) Serve() *http.ServeMux { func (s *PoolServer) Serve() *http.ServeMux {
mux := http.NewServeMux() mux := http.NewServeMux()
mux.HandleFunc("/", s.RewritePath) //mux.HandleFunc("/", s.RewritePath)
mux.HandleFunc("OPTIONS /", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("OPTIONS /", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE") w.Header().Set("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type") w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
}) })
mux.HandleFunc("GET /{id}", ErrorHandler(s.HandleGet)) mux.HandleFunc("GET /{id}", ErrorHandler(CartIdHandler(s.HandleGet)))
mux.HandleFunc("GET /{id}/add/{sku}", ErrorHandler(s.HandleAddSku)) mux.HandleFunc("GET /{id}/add/{sku}", ErrorHandler(CartIdHandler(s.HandleAddSku)))
mux.HandleFunc("POST /{id}", ErrorHandler(s.HandleAddRequest)) mux.HandleFunc("POST /{id}", ErrorHandler(CartIdHandler(s.HandleAddRequest)))
mux.HandleFunc("DELETE /{id}/{itemId}", ErrorHandler(s.HandleDeleteItem)) mux.HandleFunc("DELETE /{id}/{itemId}", ErrorHandler(CartIdHandler(s.HandleDeleteItem)))
mux.HandleFunc("PUT /{id}", ErrorHandler(s.HandleQuantityChange)) mux.HandleFunc("PUT /{id}", ErrorHandler(CartIdHandler(s.HandleQuantityChange)))
mux.HandleFunc("POST /{id}/delivery", ErrorHandler(s.HandleSetDelivery)) mux.HandleFunc("POST /{id}/delivery", ErrorHandler(CartIdHandler(s.HandleSetDelivery)))
mux.HandleFunc("DELETE /{id}/delivery/{deliveryId}", ErrorHandler(s.HandleRemoveDelivery)) mux.HandleFunc("DELETE /{id}/delivery/{deliveryId}", ErrorHandler(CartIdHandler(s.HandleRemoveDelivery)))
mux.HandleFunc("PUT /{id}/delivery/{deliveryId}/pickupPoint", ErrorHandler(s.HandleSetPickupPoint)) mux.HandleFunc("PUT /{id}/delivery/{deliveryId}/pickupPoint", ErrorHandler(CartIdHandler(s.HandleSetPickupPoint)))
mux.HandleFunc("GET /{id}/checkout", ErrorHandler(s.HandleCheckout)) mux.HandleFunc("GET /{id}/checkout", ErrorHandler(CartIdHandler(s.HandleCheckout)))
mux.HandleFunc("GET /", ErrorHandler(CookieCartIdHandler(s.HandleGet)))
mux.HandleFunc("GET /add/{sku}", ErrorHandler(CookieCartIdHandler(s.HandleAddSku)))
mux.HandleFunc("POST /", ErrorHandler(CookieCartIdHandler(s.HandleAddRequest)))
mux.HandleFunc("DELETE /{itemId}", ErrorHandler(CookieCartIdHandler(s.HandleDeleteItem)))
mux.HandleFunc("PUT /", ErrorHandler(CookieCartIdHandler(s.HandleQuantityChange)))
mux.HandleFunc("POST /delivery", ErrorHandler(CookieCartIdHandler(s.HandleSetDelivery)))
mux.HandleFunc("DELETE /delivery/{deliveryId}", ErrorHandler(CookieCartIdHandler(s.HandleRemoveDelivery)))
mux.HandleFunc("PUT /delivery/{deliveryId}/pickupPoint", ErrorHandler(CookieCartIdHandler(s.HandleSetPickupPoint)))
mux.HandleFunc("GET /checkout", ErrorHandler(CookieCartIdHandler(s.HandleCheckout)))
return mux return mux
} }