Compare commits
2 commits
fa0d5183cd
...
1be09be9db
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1be09be9db | ||
|
|
9d9f8ae0a9 |
|
|
@ -22,4 +22,4 @@ Commits follow a Conventional Commits prefix (`fix:`, `refactor:`) in imperative
|
|||
Document expected locations for `yt-dlp`, cookies, and OPML files when altering defaults. If a change requires bgutil or other external services, provide startup commands and update the sample `config.json`. Ensure new options degrade gracefully for existing configs and call out migration steps in the PR description.
|
||||
|
||||
## HTTP API
|
||||
Enable the intake server with `http_api.enable` (binds to `127.0.0.1:4416`). Set `auth_token` for bearer auth and `queue_file` to persist pending jobs. Example: `curl -H "Authorization: Bearer $TOKEN" -d '{"url":"https://youtu.be/ID","out_dir":"Channel"}' http://127.0.0.1:4416/v1/videos`. Inspect the queue with `curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:4416/status`.
|
||||
Enable the intake server with `http_api.enable` (binds to `127.0.0.1:4416`). Set `auth_token` or point `auth_token_file` at a mounted secret, and use `queue_file` to persist pending jobs. Example: `curl -H "Authorization: Bearer $TOKEN" -d '{"url":"https://youtu.be/ID","out_dir":"Channel"}' http://127.0.0.1:4416/v1/videos`. Inspect the queue with `curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:4416/status`.
|
||||
|
|
|
|||
|
|
@ -51,6 +51,12 @@ COPY <<-EOT /data/config.json
|
|||
"daemon": true,
|
||||
"dry_run": false,
|
||||
"out_dir": "/data/vids",
|
||||
"http_api": {
|
||||
"enable": true,
|
||||
"listen": "127.0.0.1:4416",
|
||||
"auth_token_file": "/run/secrets/subsyt-token",
|
||||
"queue_file": "/data/api-queue.json"
|
||||
},
|
||||
"provider": {
|
||||
"youtube": {
|
||||
"verbose": false,
|
||||
|
|
|
|||
|
|
@ -273,7 +273,7 @@ OPML export.
|
|||
"http_api": {
|
||||
"enable": true,
|
||||
"listen": "127.0.0.1:4416",
|
||||
"auth_token": "super-secret",
|
||||
"auth_token_file": "/run/secrets/subsyt-token",
|
||||
"queue_file": "./tmp/api-queue.json"
|
||||
}
|
||||
}
|
||||
|
|
@ -283,7 +283,7 @@ Submit new downloads with bearer authentication:
|
|||
|
||||
```
|
||||
curl \
|
||||
-H "Authorization: Bearer super-secret" \
|
||||
-H "Authorization: Bearer $(cat /run/secrets/subsyt-token)" \
|
||||
-H "Content-Type: application/json" \
|
||||
--data '{"url":"https://youtu.be/VIDEO","out_dir":"Channel"}' \
|
||||
http://127.0.0.1:4416/v1/videos
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ type Http_api struct {
|
|||
Enable bool
|
||||
Listen string
|
||||
Auth_token string
|
||||
Auth_token_file string
|
||||
Queue_file string
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import (
|
|||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
|
@ -22,15 +23,28 @@ type Server struct {
|
|||
defaultOutDir string
|
||||
httpServer *http.Server
|
||||
shutdownSignal chan struct{}
|
||||
authToken string
|
||||
}
|
||||
|
||||
func NewServer(cfg config.Http_api, defaultOutDir string, queue *Queue) *Server {
|
||||
return &Server{
|
||||
srv := &Server{
|
||||
cfg: cfg,
|
||||
queue: queue,
|
||||
defaultOutDir: defaultOutDir,
|
||||
shutdownSignal: make(chan struct{}),
|
||||
}
|
||||
|
||||
srv.authToken = strings.TrimSpace(cfg.Auth_token)
|
||||
|
||||
if srv.authToken == "" && cfg.Auth_token_file != "" {
|
||||
if token, err := os.ReadFile(cfg.Auth_token_file); err == nil {
|
||||
srv.authToken = strings.TrimSpace(string(token))
|
||||
} else {
|
||||
log.Printf("failed to read auth token file %s: %v", cfg.Auth_token_file, err)
|
||||
}
|
||||
}
|
||||
|
||||
return srv
|
||||
}
|
||||
|
||||
func (s *Server) Start(ctx context.Context) error {
|
||||
|
|
@ -156,7 +170,7 @@ func (s *Server) handleStatus(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
func (s *Server) authorize(header string) bool {
|
||||
required := strings.TrimSpace(s.cfg.Auth_token)
|
||||
required := s.authToken
|
||||
if required == "" {
|
||||
return true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,7 +87,13 @@ func TestHandleStatus(t *testing.T) {
|
|||
t.Fatalf("new queue: %v", err)
|
||||
}
|
||||
|
||||
s := NewServer(config.Http_api{Auth_token: "secret"}, "/videos", queue)
|
||||
tmp := t.TempDir()
|
||||
tokenPath := filepath.Join(tmp, "token.txt")
|
||||
if err := os.WriteFile(tokenPath, []byte("secret"), 0o600); err != nil {
|
||||
t.Fatalf("write token file: %v", err)
|
||||
}
|
||||
|
||||
s := NewServer(config.Http_api{Auth_token_file: tokenPath}, "/videos", queue)
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/status", nil)
|
||||
rec := httptest.NewRecorder()
|
||||
|
|
|
|||
Loading…
Reference in a new issue