~evanj/cms

ref: 5ea155bcf5f48d777fb2e6b6d66d34e60119d24e cms/internal/c/file/file.go -rw-r--r-- 1.2 KiB
5ea155bcEvan J Feat(dynamic): Dynamic content pages have been added (rather than 2 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package file

import (
	"context"
	"log"
	"net/http"
	"strings"

	"git.sr.ht/~evanj/cms/internal/c"
	"git.sr.ht/~evanj/cms/internal/m/user"
)

type File struct {
	*c.Controller
	log     *log.Logger
	db      dber
	e3      E3er
	baseURL string
}

type dber interface {
	UserGet(ctx context.Context, username, password string) (user.User, error)
	UserGetFromToken(ctx context.Context, token string) (user.User, error)
	FileExists(ctx context.Context, URL string) (bool, error)
}

type E3er interface {
	Proxy(ctx context.Context, objectURL string) ([]byte, error)
	URL() string
}

func New(c *c.Controller, log *log.Logger, db dber, e3 E3er, baseURL string) *File {
	return &File{c, log, db, e3, baseURL}
}

func (f *File) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	ok, err := f.db.FileExists(r.Context(), f.baseURL+r.URL.Path)
	if !ok || err != nil {
		f.ErrorString(w, r, http.StatusNotFound, "file does not exist")
		return
	}

	full := strings.TrimRight(f.e3.URL(), "api") + strings.TrimLeft(r.URL.Path, "/file") // TODO: Cleanup, this is hacky.
	bytes, err := f.e3.Proxy(r.Context(), full)
	if err != nil {
		f.ErrorString(w, r, http.StatusInternalServerError, "failed to serve file")
		return
	}

	w.WriteHeader(http.StatusOK)
	w.Write(bytes)
}