feat: add env vars to disable render endpoints
BLOCKY_DISABLE_GLB/PNG/GIF/MP4 return 403 when set to true
This commit is contained in:
parent
ce511e1a85
commit
f8947fdcc4
5 changed files with 110 additions and 7 deletions
16
CLAUDE.md
16
CLAUDE.md
|
|
@ -25,9 +25,9 @@ BlockyServer is an HTTP API for rendering Hytale character models. It wraps the
|
|||
```
|
||||
HTTP Request → api.Handlers → service.MergeService → blockymodel-merger pkg
|
||||
↓
|
||||
render.RenderPNG/GIF (for image endpoints)
|
||||
render.RenderPNG/GIF/MP4 (for image/video endpoints)
|
||||
↓
|
||||
HTTP Response (GLB/PNG/GIF)
|
||||
HTTP Response (GLB/PNG/GIF/MP4)
|
||||
```
|
||||
|
||||
### Package Structure
|
||||
|
|
@ -49,6 +49,17 @@ Server requires these directories at runtime (relative to working directory):
|
|||
- `assets/` - Character models (.blockymodel), textures
|
||||
- `data/` - JSON registry files (accessories, colors, gradients)
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `BLOCKY_DISABLE_GLB` | `false` | Disable `/render/glb` endpoint (returns 403) |
|
||||
| `BLOCKY_DISABLE_PNG` | `false` | Disable `/render/png` endpoint (returns 403) |
|
||||
| `BLOCKY_DISABLE_GIF` | `false` | Disable `/render/gif` endpoint (returns 403) |
|
||||
| `BLOCKY_DISABLE_MP4` | `false` | Disable `/render/mp4` endpoint (returns 403) |
|
||||
|
||||
Set to `true`, `1`, or `yes` to disable an endpoint.
|
||||
|
||||
### API Endpoints
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
|
|
@ -56,6 +67,7 @@ Server requires these directories at runtime (relative to working directory):
|
|||
| `/render/glb` | POST | Character JSON → GLB binary |
|
||||
| `/render/png` | POST | Character JSON + options → PNG image |
|
||||
| `/render/gif` | POST | Character JSON + options → Animated GIF |
|
||||
| `/render/mp4` | POST | Character JSON + options → MP4 video (requires FFmpeg) |
|
||||
| `/docs` | GET | Swagger UI |
|
||||
| `/openapi.json` | GET | OpenAPI spec |
|
||||
| `/health` | GET | Health check |
|
||||
|
|
|
|||
22
README.md
22
README.md
|
|
@ -4,7 +4,7 @@
|
|||
> Not affiliated with Hypixel Studios.
|
||||
> All trademarks and assets are property of their respective owners.
|
||||
|
||||
HTTP API for rendering Hytale character models as GLB, PNG, or animated GIF.
|
||||
HTTP API for rendering Hytale character models as GLB, PNG, animated GIF, or MP4 video.
|
||||
|
||||
Built on top of [blockymodel-merger](https://github.com/hytale-tools/blockymodel-merger) by [JackGamesFTW](https://github.com/JackGamesFTW), special thanks to him!
|
||||
|
||||
|
|
@ -14,6 +14,7 @@ Built on top of [blockymodel-merger](https://github.com/hytale-tools/blockymodel
|
|||
- Export as GLB (glTF binary)
|
||||
- Render to PNG with configurable rotation and background
|
||||
- Render to animated rotating GIF
|
||||
- Render to MP4 video (requires FFmpeg)
|
||||
- Swagger UI documentation
|
||||
|
||||
## Requirements
|
||||
|
|
@ -69,6 +70,24 @@ go build -o blockyserver.exe .
|
|||
./blockyserver.exe -port 3000
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `BLOCKY_DISABLE_GLB` | `false` | Disable `/render/glb` endpoint |
|
||||
| `BLOCKY_DISABLE_PNG` | `false` | Disable `/render/png` endpoint |
|
||||
| `BLOCKY_DISABLE_GIF` | `false` | Disable `/render/gif` endpoint |
|
||||
| `BLOCKY_DISABLE_MP4` | `false` | Disable `/render/mp4` endpoint |
|
||||
|
||||
Set to `true`, `1`, or `yes` to disable. Disabled endpoints return `403 Forbidden`.
|
||||
|
||||
```bash
|
||||
# Example: disable GIF and MP4 endpoints
|
||||
BLOCKY_DISABLE_GIF=true BLOCKY_DISABLE_MP4=true ./blockyserver.exe
|
||||
```
|
||||
|
||||
## Docker
|
||||
|
||||
### Using Docker Compose (recommended)
|
||||
|
|
@ -99,6 +118,7 @@ docker run -d -p 8080:8080 \
|
|||
| `/render/glb` | POST | Returns GLB binary |
|
||||
| `/render/png` | POST | Returns PNG image |
|
||||
| `/render/gif` | POST | Returns animated GIF |
|
||||
| `/render/mp4` | POST | Returns MP4 video |
|
||||
| `/docs` | GET | Swagger UI |
|
||||
| `/openapi.json` | GET | OpenAPI specification |
|
||||
| `/health` | GET | Health check |
|
||||
|
|
|
|||
35
internal/api/middleware.go
Normal file
35
internal/api/middleware.go
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"blockyserver/internal/config"
|
||||
)
|
||||
|
||||
// EndpointGuard creates middleware that returns 403 if endpoint is disabled
|
||||
func EndpointGuard(enabled bool, endpointName string) func(http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if !enabled {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
json.NewEncoder(w).Encode(ErrorResponse{
|
||||
Error: endpointName + " endpoint is disabled",
|
||||
})
|
||||
return
|
||||
}
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// NewEndpointGuards creates guards for all render endpoints based on config
|
||||
func NewEndpointGuards(cfg *config.EndpointConfig) map[string]func(http.Handler) http.Handler {
|
||||
return map[string]func(http.Handler) http.Handler{
|
||||
"glb": EndpointGuard(cfg.GLBEnabled, "/render/glb"),
|
||||
"png": EndpointGuard(cfg.PNGEnabled, "/render/png"),
|
||||
"gif": EndpointGuard(cfg.GIFEnabled, "/render/gif"),
|
||||
"mp4": EndpointGuard(cfg.MP4Enabled, "/render/mp4"),
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ import (
|
|||
"net/http"
|
||||
"time"
|
||||
|
||||
"blockyserver/internal/config"
|
||||
"blockyserver/internal/service"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
|
|
@ -19,6 +20,10 @@ func NewServer(svc *service.MergeService) http.Handler {
|
|||
r.Use(middleware.Recoverer)
|
||||
r.Use(middleware.Timeout(60 * time.Second))
|
||||
|
||||
// Load endpoint config
|
||||
cfg := config.LoadEndpointConfig()
|
||||
guards := NewEndpointGuards(cfg)
|
||||
|
||||
// Create handlers
|
||||
h := NewHandlers(svc)
|
||||
|
||||
|
|
@ -26,10 +31,10 @@ func NewServer(svc *service.MergeService) http.Handler {
|
|||
r.Get("/health", h.HandleHealth)
|
||||
r.Get("/openapi.json", h.HandleOpenAPISpec)
|
||||
r.Get("/docs", h.HandleSwaggerUI)
|
||||
r.Post("/render/glb", h.HandleGLB)
|
||||
r.Post("/render/png", h.HandlePNG)
|
||||
r.Post("/render/gif", h.HandleGIF)
|
||||
r.Post("/render/mp4", h.HandleMP4)
|
||||
r.With(guards["glb"]).Post("/render/glb", h.HandleGLB)
|
||||
r.With(guards["png"]).Post("/render/png", h.HandlePNG)
|
||||
r.With(guards["gif"]).Post("/render/gif", h.HandleGIF)
|
||||
r.With(guards["mp4"]).Post("/render/mp4", h.HandleMP4)
|
||||
|
||||
return r
|
||||
}
|
||||
|
|
|
|||
31
internal/config/config.go
Normal file
31
internal/config/config.go
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// EndpointConfig holds enable/disable flags for render endpoints
|
||||
type EndpointConfig struct {
|
||||
GLBEnabled bool
|
||||
PNGEnabled bool
|
||||
GIFEnabled bool
|
||||
MP4Enabled bool
|
||||
}
|
||||
|
||||
// LoadEndpointConfig reads endpoint configuration from environment variables.
|
||||
// All endpoints are enabled by default.
|
||||
// Set BLOCKY_DISABLE_GLB=true, BLOCKY_DISABLE_PNG=true, etc. to disable.
|
||||
func LoadEndpointConfig() *EndpointConfig {
|
||||
return &EndpointConfig{
|
||||
GLBEnabled: !isDisabled("BLOCKY_DISABLE_GLB"),
|
||||
PNGEnabled: !isDisabled("BLOCKY_DISABLE_PNG"),
|
||||
GIFEnabled: !isDisabled("BLOCKY_DISABLE_GIF"),
|
||||
MP4Enabled: !isDisabled("BLOCKY_DISABLE_MP4"),
|
||||
}
|
||||
}
|
||||
|
||||
func isDisabled(envVar string) bool {
|
||||
val := strings.ToLower(os.Getenv(envVar))
|
||||
return val == "true" || val == "1" || val == "yes"
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue