package api import ( "encoding/json" "io" "net/http" "os" "path/filepath" "github.com/gorilla/mux" "github.com/sirupsen/logrus" ) type APIHandler struct { dataDir string log *logrus.Logger } func NewAPIHandler(dataDir string, log *logrus.Logger) *APIHandler { return &APIHandler{ dataDir: dataDir, log: log, } } func (h *APIHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { switch r.Method { case http.MethodGet: h.handleGet(w, r) case http.MethodPost: h.handlePost(w, r) case http.MethodPut: h.handlePut(w, r) case http.MethodDelete: h.handleDelete(w, r) default: h.writeError(w, http.StatusMethodNotAllowed, "method not allowed") } } func (h *APIHandler) handleGet(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) filename := vars["filename"] h.log.Infof("GET request for file: %s", filename) filepath := filepath.Join(h.dataDir, filename) content, err := os.ReadFile(filepath) if err != nil { h.log.Errorf("Error reading file %s: %v", filename, err) h.writeError(w, http.StatusNotFound, "file not found") return } w.Header().Set("Content-Type", "text/plain") w.Write(content) } func (h *APIHandler) handlePost(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) filename := vars["filename"] h.log.Infof("POST request for file: %s", filename) filepath := filepath.Join(h.dataDir, filename) content, err := io.ReadAll(r.Body) if err != nil { h.log.Errorf("Error reading request body: %v", err) h.writeError(w, http.StatusBadRequest, "invalid request body") return } if err := os.WriteFile(filepath, content, 0644); err != nil { h.log.Errorf("Error writing file %s: %v", filename, err) h.writeError(w, http.StatusInternalServerError, "failed to create file") return } w.WriteHeader(http.StatusCreated) } func (h *APIHandler) handlePut(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) filename := vars["filename"] h.log.Infof("PUT request for file: %s", filename) filepath := filepath.Join(h.dataDir, filename) content, err := io.ReadAll(r.Body) if err != nil { h.log.Errorf("Error reading request body: %v", err) h.writeError(w, http.StatusBadRequest, "invalid request body") return } if err := os.WriteFile(filepath, content, 0644); err != nil { h.log.Errorf("Error writing file %s: %v", filename, err) h.writeError(w, http.StatusInternalServerError, "failed to update file") return } w.WriteHeader(http.StatusOK) } func (h *APIHandler) handleDelete(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) filename := vars["filename"] h.log.Infof("DELETE request for file: %s", filename) filepath := filepath.Join(h.dataDir, filename) if err := os.Remove(filepath); err != nil { h.log.Errorf("Error deleting file %s: %v", filename, err) h.writeError(w, http.StatusNotFound, "file not found") return } w.WriteHeader(http.StatusNoContent) } func (h *APIHandler) writeError(w http.ResponseWriter, statusCode int, message string) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(statusCode) json.NewEncoder(w).Encode(map[string]string{"error": message}) }