package main import ( "context" "log" "net/http" "strings" "git.k6n.net/go-cart-actor/pkg/cart" "git.k6n.net/go-cart-actor/pkg/checkout" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/metric" ) func getOriginalHost(r *http.Request) string { proxyHost := r.Header.Get("X-Forwarded-Host") if proxyHost != "" { return proxyHost } return r.Host } func getClientIp(r *http.Request) string { ip := r.Header.Get("X-Forwarded-For") if ip == "" { ip = r.RemoteAddr } return ip } func getCurrency(country string) string { if country == "no" { return "NOK" } return "SEK" } func getLocale(country string) string { if country == "no" { return "nb-no" } return "sv-se" } func getCountryFromHost(host string) string { if strings.Contains(strings.ToLower(host), "-no") { return "no" } if strings.Contains(strings.ToLower(host), "-se") { return "se" } return "" } func (a *CheckoutPoolServer) reserveInventory(ctx context.Context, grain *checkout.CheckoutGrain) error { if a.inventoryService != nil { inventoryRequests := getInventoryRequests(grain.CartState.Items) _, err := a.inventoryService.ReservationCheck(ctx, inventoryRequests...) if err != nil { logger.WarnContext(ctx, "placeorder inventory check failed") return err } } return nil } func CheckoutIdHandler(fn func(checkoutId checkout.CheckoutId, w http.ResponseWriter, r *http.Request) error) func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) { var id checkout.CheckoutId raw := r.PathValue("id") if raw == "" { id = checkout.CheckoutId(cart.MustNewCartId()) w.Header().Set("Set-Checkout-Id", id.String()) } else { if parsedId, ok := cart.ParseCartId(raw); !ok { w.WriteHeader(http.StatusBadRequest) w.Write([]byte("checkout id is invalid")) return } else { id = checkout.CheckoutId(parsedId) } } err := fn(id, w, r) if err != nil { log.Printf("Server error, not remote error: %v\n", err) w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) } } } func (s *CheckoutPoolServer) ProxyHandler(fn func(w http.ResponseWriter, r *http.Request, checkoutId checkout.CheckoutId) error) func(checkoutId checkout.CheckoutId, w http.ResponseWriter, r *http.Request) error { return func(checkoutId checkout.CheckoutId, w http.ResponseWriter, r *http.Request) error { if ownerHost, ok := s.OwnerHost(uint64(checkoutId)); ok { ctx, span := tracer.Start(r.Context(), "proxy") defer span.End() span.SetAttributes(attribute.String("checkoutid", checkoutId.String())) hostAttr := attribute.String("other host", ownerHost.Name()) span.SetAttributes(hostAttr) logger.InfoContext(ctx, "checkout proxyed", "result", ownerHost.Name()) proxyCalls.Add(ctx, 1, metric.WithAttributes(hostAttr)) handled, err := ownerHost.Proxy(uint64(checkoutId), w, r, nil) grainLookups.Inc() if err == nil && handled { return nil } } _, span := tracer.Start(r.Context(), "own") span.SetAttributes(attribute.String("checkoutid", checkoutId.String())) defer span.End() return fn(w, r, checkoutId) } }