package server import ( "encoding/json" "fmt" "log/slog" "net/http" "github.com/gorilla/mux" "git.riou.xyz/jriou/coller/internal" ) func HealthHandler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "OK") } type CreateNoteHandler struct { logger *slog.Logger db *Database maxUploadSize int64 } type CreateNotePayload struct { Content string `json:"content"` EncryptionKey string `json:"encryption_key"` Encrypted bool `json:"encrypted"` Expiration int `json:"expiration"` DeleteAfterRead bool `json:"delete_after_read"` Language string `json:"language"` } type CreateNoteResponse struct { ID string `json:"id"` } func (h *CreateNoteHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") bodyReader := http.MaxBytesReader(w, r.Body, h.maxUploadSize) defer r.Body.Close() var body CreateNotePayload err := json.NewDecoder(bodyReader).Decode(&body) if err != nil { WriteError(w, "could not decode payload to create note", err) return } content, err := internal.Decode(body.Content) if err != nil { WriteError(w, "could not decode content", err) return } note, err := h.db.Create(content, body.EncryptionKey, body.Encrypted, body.Expiration, body.DeleteAfterRead, body.Language) if err != nil { WriteError(w, "could not create note", err) return } w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(CreateNoteResponse{ID: note.ID}) } type GetNoteHandler struct { logger *slog.Logger db *Database } func (h *GetNoteHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "text/plain; charset=utf-8") id := mux.Vars(r)["id"] note, err := h.db.Get(id) if err != nil { WriteError(w, "could not get note", err) } else if note == nil { w.WriteHeader(http.StatusNotFound) } else { if note.Encrypted { w.Header().Set("Content-Type", "application/octet-stream") } w.WriteHeader(http.StatusOK) fmt.Fprint(w, string(note.Content)) } } type GetEncryptedNoteHandler struct { logger *slog.Logger db *Database } func (h *GetEncryptedNoteHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "text/plain; charset=utf-8") vars := mux.Vars(r) id := vars["id"] encryptionKey := vars["encryptionKey"] note, err := h.db.Get(id) if err != nil { WriteError(w, "could not get note", err) return } else if note == nil { w.WriteHeader(http.StatusNotFound) return } if encryptionKey != "" && note.Encrypted { note.Content, err = internal.Decrypt(note.Content, encryptionKey) if err != nil { WriteError(w, "could not decrypt note", err) return } } w.WriteHeader(http.StatusOK) fmt.Fprint(w, string(note.Content)) } type ClientHandler struct { logger *slog.Logger version string } func (h *ClientHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { h.logger.Debug("rendering client redirection") vars := mux.Vars(r) os := vars["os"] arch := vars["arch"] clientName := vars["clientName"] if !internal.InSlice(supportedOSes, os) || !internal.InSlice(supportedArches, arch) || !internal.InSlice(supportedClients, clientName) { w.WriteHeader(http.StatusNotFound) return } version := h.version if version == "" { version = "latest" } http.Redirect(w, r, fmt.Sprintf("https://git.riou.xyz/jriou/%s/releases/download/%s/%s-%s-%s", clientName, version, clientName, os, arch), http.StatusMovedPermanently) }