feat: serve clients binaries from a local directory
All checks were successful
/ pre-commit (push) Successful in 1m18s

Fixes #44.

Signed-off-by: Julien Riou <julien@riou.xyz>
This commit is contained in:
Julien Riou 2025-10-10 12:30:32 +02:00
commit ab6b03a6d4
Signed by: jriou
GPG key ID: 9A099EDA51316854
4 changed files with 13 additions and 5 deletions

View file

@ -41,6 +41,7 @@ The file format is **JSON**:
* **tls_key_file** (string): Path to TLS key file to enable HTTPS * **tls_key_file** (string): Path to TLS key file to enable HTTPS
* **ace_directory** (string): Serve [Ace](hhttps://ace.c9.io/) assets from this local directory (ex: "./node_modules/ace-builds"). See **Dependencies** for details. * **ace_directory** (string): Serve [Ace](hhttps://ace.c9.io/) assets from this local directory (ex: "./node_modules/ace-builds"). See **Dependencies** for details.
* **bootstrap_directory** (string): Serve [Bootstrap](https://getbootstrap.com/) assets from this local directory (ex: "./node_modules/bootstrap/dist"). See **Dependencies** for details. * **bootstrap_directory** (string): Serve [Bootstrap](https://getbootstrap.com/) assets from this local directory (ex: "./node_modules/bootstrap/dist"). See **Dependencies** for details.
* **clients_directory** (string): Serve clients binaries from this local directory (ex: "./releases/1.2.0")
* **disable_editor** (bool): Disable Ace editor. * **disable_editor** (bool): Disable Ace editor.
The configuration file is not required but the service might not be exposed to the public. The configuration file is not required but the service might not be exposed to the public.

View file

@ -34,6 +34,7 @@ type Config struct {
AceDirectory string `json:"ace_directory"` AceDirectory string `json:"ace_directory"`
BootstrapDirectory string `json:"bootstrap_directory"` BootstrapDirectory string `json:"bootstrap_directory"`
DisableEditor bool `json:"disable_editor"` DisableEditor bool `json:"disable_editor"`
ClientsDirectory string `json:"clients_directory"`
} }
func NewConfig() *Config { func NewConfig() *Config {

View file

@ -232,8 +232,9 @@ func (h *GetProtectedNoteHandler) ServeHTTP(w http.ResponseWriter, r *http.Reque
} }
type ClientHandler struct { type ClientHandler struct {
logger *slog.Logger logger *slog.Logger
version string version string
directory string
} }
func (h *ClientHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (h *ClientHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
@ -253,5 +254,9 @@ func (h *ClientHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
version = "latest" version = "latest"
} }
http.Redirect(w, r, fmt.Sprintf("https://git.riou.xyz/jriou/coller/releases/download/%s/%s-%s-%s", version, clientName, os, arch), http.StatusMovedPermanently) if h.directory != "" {
http.ServeFile(w, r, h.directory+"/"+fmt.Sprintf("%s-%s-%s", clientName, os, arch))
} else {
http.Redirect(w, r, fmt.Sprintf("https://git.riou.xyz/jriou/coller/releases/download/%s/%s-%s-%s", version, clientName, os, arch), http.StatusMovedPermanently)
}
} }

View file

@ -133,8 +133,9 @@ func (s *Server) Start() error {
r.Path("/clients.html").Handler(clientsHandler).Methods("GET") r.Path("/clients.html").Handler(clientsHandler).Methods("GET")
clientHandler := &ClientHandler{ clientHandler := &ClientHandler{
logger: s.logger, logger: s.logger,
version: p.Version, version: p.Version,
directory: s.config.ClientsDirectory,
} }
r.Path("/clients/{os:[a-z]+}-{arch:[a-z0-9]+}/{clientName:[a-z]+}").Handler(clientHandler).Methods("GET") r.Path("/clients/{os:[a-z]+}-{arch:[a-z0-9]+}/{clientName:[a-z]+}").Handler(clientHandler).Methods("GET")