Skip to content

Commit

Permalink
Starting metadata object
Browse files Browse the repository at this point in the history
  • Loading branch information
chriskuehl committed Sep 8, 2024
1 parent 4ef6628 commit b0dcf31
Show file tree
Hide file tree
Showing 9 changed files with 55 additions and 25 deletions.
2 changes: 1 addition & 1 deletion server/assets/assets_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func TestAssetURLProd(t *testing.T) {
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
conf.ObjectURLPattern = *url
conf.ObjectURLPattern = url
conf.DevMode = false

got, err := assets.AssetURL(conf, "img/favicon.ico")
Expand Down
20 changes: 13 additions & 7 deletions server/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ type Config struct {
AbuseContactEmail string
MaxUploadBytes int64
MaxMultipartMemoryBytes int64
HomeURL url.URL
ObjectURLPattern url.URL
HTMLURLPattern url.URL
HomeURL *url.URL
ObjectURLPattern *url.URL
HTMLURLPattern *url.URL
ForbiddenFileExtensions map[string]struct{}

// Runtime options.
Expand All @@ -49,13 +49,19 @@ func (conf *Config) Validate() []string {
if conf.MaxMultipartMemoryBytes <= 0 {
errs = append(errs, "MaxMultipartMemoryBytes must be greater than 0")
}
if strings.HasSuffix(conf.HomeURL.Path, "/") {
if conf.HomeURL == nil {
errs = append(errs, "HomeURL must not be nil")
} else if strings.HasSuffix(conf.HomeURL.Path, "/") {
errs = append(errs, "HomeURL must not end with a slash")
}
if !strings.Contains(conf.ObjectURLPattern.Path, ":path:") {
if conf.ObjectURLPattern == nil {
errs = append(errs, "ObjectURLPattern must not be nil")
} else if !strings.Contains(conf.ObjectURLPattern.Path, ":path:") {
errs = append(errs, "ObjectURLPattern must contain a ':path:' placeholder")
}
if !strings.Contains(conf.HTMLURLPattern.Path, ":path:") {
if conf.HTMLURLPattern == nil {
errs = append(errs, "HTMLURLPattern must not be nil")
} else if !strings.Contains(conf.HTMLURLPattern.Path, ":path:") {
errs = append(errs, "HTMLURLPattern must contain a ':path:' placeholder")
}
if conf.ForbiddenFileExtensions == nil {
Expand All @@ -75,5 +81,5 @@ func (conf *Config) Validate() []string {
func (conf *Config) ObjectURL(path string) *url.URL {
url := conf.ObjectURLPattern
url.Path = strings.Replace(url.Path, ":path:", path, -1)
return &url
return url
}
6 changes: 3 additions & 3 deletions server/config/loader/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,21 +60,21 @@ func LoadConfigTOML(conf *config.Config, path string) error {
if err != nil {
return fmt.Errorf("parsing HomeURL: %w", err)
}
conf.HomeURL = *u
conf.HomeURL = u
}
if cfg.ObjectURLPattern != "" {
u, err := url.ParseRequestURI(cfg.ObjectURLPattern)
if err != nil {
return fmt.Errorf("parsing ObjectURLPattern: %w", err)
}
conf.ObjectURLPattern = *u
conf.ObjectURLPattern = u
}
if cfg.HTMLURLPattern != "" {
u, err := url.ParseRequestURI(cfg.HTMLURLPattern)
if err != nil {
return fmt.Errorf("parsing HTMLURLPattern: %w", err)
}
conf.HTMLURLPattern = *u
conf.HTMLURLPattern = u
}
for _, ext := range cfg.ForbiddenFileExtensions {
conf.ForbiddenFileExtensions[ext] = struct{}{}
Expand Down
6 changes: 3 additions & 3 deletions server/config/loader/loader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ func TestLoadConfigTOMLWithEverything(t *testing.T) {
AbuseContactEmail: "abuse@foo.com",
MaxUploadBytes: 123,
MaxMultipartMemoryBytes: 456,
HomeURL: url.URL{Scheme: "http", Host: "foo.com"},
ObjectURLPattern: url.URL{Scheme: "http", Host: "i.foo.com", Path: "/o/:path:"},
HTMLURLPattern: url.URL{Scheme: "http", Host: "i.foo.com", Path: "/h/:path:"},
HomeURL: &url.URL{Scheme: "http", Host: "foo.com"},
ObjectURLPattern: &url.URL{Scheme: "http", Host: "i.foo.com", Path: "/o/:path:"},
HTMLURLPattern: &url.URL{Scheme: "http", Host: "i.foo.com", Path: "/h/:path:"},
ForbiddenFileExtensions: map[string]struct{}{"foo": {}, "bar": {}},
Host: "192.168.1.100",
Port: 5555,
Expand Down
6 changes: 3 additions & 3 deletions server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ func NewConfig() *config.Config {
AbuseContactEmail: "abuse@example.com",
MaxUploadBytes: 1024 * 1024 * 10, // 10 MiB
MaxMultipartMemoryBytes: 1024 * 1024 * 10, // 10 MiB
HomeURL: url.URL{Scheme: "http", Host: "localhost:8080"},
ObjectURLPattern: url.URL{Scheme: "http", Host: "localhost:8080", Path: "/dev/storage/object/:path:"},
HTMLURLPattern: url.URL{Scheme: "http", Host: "localhost:8080", Path: "/dev/storage/html/:path:"},
HomeURL: &url.URL{Scheme: "http", Host: "localhost:8080"},
ObjectURLPattern: &url.URL{Scheme: "http", Host: "localhost:8080", Path: "/dev/storage/object/:path:"},
HTMLURLPattern: &url.URL{Scheme: "http", Host: "localhost:8080", Path: "/dev/storage/html/:path:"},
ForbiddenFileExtensions: make(map[string]struct{}),
Host: "127.0.0.1",
Port: 8080,
Expand Down
5 changes: 3 additions & 2 deletions server/storage/storagedata/storagedata.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ package storagedata

import (
"io"
"net/url"
)

type Object struct {
Key string
Links []string
MetadataURL string
Links []*url.URL
MetadataURL *url.URL
Reader io.Reader
Bytes int64
}
4 changes: 2 additions & 2 deletions server/uploads/uploads.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ var (
}
)

func genUniqueObjectID() (string, error) {
func GenUniqueObjectID() (string, error) {
var s strings.Builder
for i := 0; i < storedFileNameLength; i++ {
r, err := rand.Int(rand.Reader, big.NewInt(int64(len(storedFileNameChars))))
Expand Down Expand Up @@ -74,7 +74,7 @@ func (s SanitizedKey) String() string {
func SanitizeUploadName(name string, forbiddenExtensions map[string]struct{}) (*SanitizedKey, error) {
name = strings.ReplaceAll(name, string(filepath.Separator), "/")
name = name[strings.LastIndex(name, "/")+1:]
id, err := genUniqueObjectID()
id, err := GenUniqueObjectID()
if err != nil {
return nil, fmt.Errorf("generating unique object ID: %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion server/uploads/uploads_x_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
)

func TestGetUniqueObjectID(t *testing.T) {
got, err := genUniqueObjectID()
got, err := GenUniqueObjectID()
if err != nil {
t.Fatalf("genUniqueObjectID() error = %v", err)
}
Expand Down
29 changes: 26 additions & 3 deletions server/views.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"html/template"
"mime/multipart"
"net/http"
"net/url"
"strings"

"github.com/chriskuehl/fluffy/server/assets"
Expand Down Expand Up @@ -157,7 +158,7 @@ type uploadResponse struct {
errorResponse
Redirect string `json:"redirect"`
Metadata string `json:"metadata"`
UploadedFiles map[string]uploadedFile `json:"uploadedFiles"`
UploadedFiles map[string]uploadedFile `json:"uploaded_files"`
}

func objectFromFileHeader(
Expand Down Expand Up @@ -234,7 +235,29 @@ func handleUpload(conf *config.Config, logger logging.Logger) http.HandlerFunc {
return
}

errs := uploads.UploadObjects(r.Context(), logger, conf, objs)
metadataKey, err := uploads.GenUniqueObjectID()
if err != nil {
logger.Error(r.Context(), "generating unique object ID", "error", err)
userError{http.StatusInternalServerError, "Failed to generate unique object ID."}.output(w)
return
}
metadataObject := storagedata.Object{
Key: metadataKey + ".json",
Reader: strings.NewReader("TODO"),
Bytes: int64(len("TODO")),
}
metadataURL := conf.ObjectURL(metadataObject.Key)
uploadObjs := append([]storagedata.Object{metadataObject}, objs...)
links := make([]*url.URL, len(uploadObjs))
for i, obj := range uploadObjs {
links[i] = conf.ObjectURL(obj.Key)
}
for _, obj := range uploadObjs {
obj.MetadataURL = metadataURL
obj.Links = links
}

errs := uploads.UploadObjects(r.Context(), logger, conf, uploadObjs)

if len(errs) > 0 {
logger.Error(r.Context(), "uploading objects failed", "errors", errs)
Expand All @@ -261,7 +284,7 @@ func handleUpload(conf *config.Config, logger logging.Logger) http.HandlerFunc {
Success: true,
},
Redirect: redirect,
Metadata: "TODO",
Metadata: metadataURL.String(),
UploadedFiles: uploadedFiles,
}
w.Header().Set("Content-Type", "application/json")
Expand Down

0 comments on commit b0dcf31

Please sign in to comment.