diff --git a/main.go b/main.go index f4d6edb..0d80eaa 100644 --- a/main.go +++ b/main.go @@ -256,40 +256,47 @@ func statusCheck(w http.ResponseWriter, r *http.Request) { return } - // Parse request body to extract ID var request struct { Id string `json:"Id"` } err := json.NewDecoder(r.Body).Decode(&request) - if err != nil || request.Id == "" { - http.Error(w, "Invalid request body", http.StatusBadRequest) + if err != nil { + http.Error(w, "Invalid JSON format", http.StatusBadRequest) return } - // Check if ID exists in Redis - value, err := redisClient.Get(ctx, request.Id).Result() - var message Message - if errors.Is(err, redis.Nil) { - message = Message{Id: request.Id, Name: "", Image: "", Status: "none", Timestamp: ""} - fmt.Println("Returning: ", message) - } else if err != nil { - http.Error(w, "Redis error", http.StatusInternalServerError) + if request.Id == "" { + http.Error(w, "Missing or empty Id field", http.StatusBadRequest) return - } else { - err = json.Unmarshal([]byte(value), &message) - fmt.Printf("Returning %s,%s,%s,%s\n", message.Id, message.Status, message.Name, message.Timestamp) + } + + value, err := redisClient.Get(ctx, request.Id).Result() + if errors.Is(err, redis.Nil) { + message := Message{Id: request.Id, Status: "none", Timestamp: time.Now().Format(time.RFC3339)} + w.Header().Set("Content-Type", "application/json") + err := json.NewEncoder(w).Encode(message) if err != nil { - http.Error(w, "Failed to parse message data", http.StatusInternalServerError) return } + return + } else if err != nil { + log.Printf("Redis error: %v", err) + http.Error(w, "Error connecting to Redis", http.StatusInternalServerError) + return + } + + var message Message + err = json.Unmarshal([]byte(value), &message) + if err != nil { + log.Printf("Failed to decode Redis data for Id: %s - %v", request.Id, err) + http.Error(w, "Failed to parse data", http.StatusInternalServerError) + return } - // Send JSON response with full Message struct w.Header().Set("Content-Type", "application/json") err = json.NewEncoder(w).Encode(message) if err != nil { - http.Error(w, "Failed to encode message data", http.StatusInternalServerError) - return + http.Error(w, "Failed to encode response", http.StatusInternalServerError) } } @@ -299,48 +306,56 @@ func setState(w http.ResponseWriter, r *http.Request, s *Server) { return } - // Decode the incoming JSON to a Message struct var message Message err := json.NewDecoder(r.Body).Decode(&message) - fmt.Println("Message: ", message) - if err != nil || message.Id == "" || message.Status == "" { - http.Error(w, "Invalid request body", http.StatusBadRequest) + http.Error(w, "Invalid request format", http.StatusBadRequest) return } - // If Status is "none", delete the record and broadcast expiration + if message.Status == "none" { - err = redisClient.Del(ctx, message.Id).Err() - if err != nil { - fmt.Printf("Error deleting message: %v\n", err) + if err := redisClient.Del(ctx, message.Id).Err(); err != nil { + log.Printf("Error deleting key from Redis: %v", err) + http.Error(w, "Failed to delete key from Redis", http.StatusInternalServerError) return } - // Broadcast the expiration event to all clients broadcastRemovedRecords(s, message.Id) w.WriteHeader(http.StatusOK) return - } else { - // Otherwise, store the updated message in Redis - msgJSON, err := json.Marshal(message) - if err != nil { - http.Error(w, "Failed to encode message", http.StatusInternalServerError) - return - } + } - // Set a timeout based on the status (can be customized as needed) - timeout := 20 * time.Second - err = redisClient.Set(ctx, message.Id, msgJSON, timeout).Err() - if err != nil { - log.Println("Failed to store payload in Redis:", err) - http.Error(w, "Failed to store message in Redis", http.StatusInternalServerError) - return - } - - // Broadcast all records to all clients - broadcastAllRecords(s) - w.WriteHeader(http.StatusOK) + msgJSON, err := json.Marshal(message) + if err != nil { + http.Error(w, "Failed to encode message", http.StatusInternalServerError) return } + + timeout := 20 * time.Second + err = redisClient.Set(ctx, message.Id, msgJSON, timeout).Err() + if err != nil { + log.Printf("Failed to set key in Redis: %v", err) + http.Error(w, "Failed to store data", http.StatusInternalServerError) + return + } + + broadcastAllRecords(s) + w.WriteHeader(http.StatusOK) +} + +func enableCORS(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Access-Control-Allow-Origin", "*") // Allow all origins + w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS") + w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization") + + // Allow preflight requests for the OPTIONS method + if r.Method == http.MethodOptions { + w.WriteHeader(http.StatusOK) + return + } + + next.ServeHTTP(w, r) + }) } func main() { @@ -355,13 +370,14 @@ func main() { router.HandleFunc("/set", func(w http.ResponseWriter, r *http.Request) { setState(w, r, server) }).Methods("POST") + corsRouter := enableCORS(router) // Start server and other necessary goroutines go server.listenForExpirationEvents() // Pass the mux router to ListenAndServe fmt.Println("Server started on :8080") - err := http.ListenAndServe(":8080", router) + err := http.ListenAndServe(":8080", corsRouter) if err != nil { fmt.Printf("Server error: %v\n", err) }