Documentation
¶
Index ¶
- Constants
- Variables
- type Config
- type FileMetadata
- type FileTooLargeError
- type HTTPHandler
- type LocalContentHandler
- type Service
- func (s *Service) Delete(ctx context.Context, key string) error
- func (s *Service) Download(ctx context.Context, key string) (io.ReadCloser, string, error)
- func (s *Service) DownloadURL(ctx context.Context, key string) (string, int64, error)
- func (s *Service) GetDownloadURL(ctx context.Context, key string) (string, error)
- func (s *Service) Save(ctx context.Context, filename, mime string, body io.Reader, size int64) (*FileMetadata, error)
- func (s *Service) Upload(ctx context.Context, filename string, size int64, mime string) (*FileMetadata, error)
- type ServiceOption
- type StorageDriver
Constants ¶
const ( TypeLocal = "local" TypeS3 = "s3" )
Supported Config.Type values.
Variables ¶
var ( // ErrInvalidSize is returned by Upload for a size that is not positive. ErrInvalidSize = errors.New("storage: size must be greater than 0") // ErrContentTypeNotAllowed is returned by Upload for a MIME type outside // the list set with WithAllowedUploadTypes. ErrContentTypeNotAllowed = errors.New("storage: content type not allowed") )
var ErrInvalidKey = errors.New("storage: invalid key")
ErrInvalidKey is returned when a key is not one Upload could have created. Callers can use errors.Is(err, storage.ErrInvalidKey) to detect it.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
// Type is the storage backend: "local" or "s3".
Type string `yaml:"type"`
// Local is used when Type == "local".
Local drivers.LocalConfig `yaml:"local"`
// S3 is used when Type == "s3".
S3 drivers.S3Config `yaml:"s3"`
// PresignTTLSeconds is how long a presigned upload/download URL stays
// valid, in seconds. Required for both backends. Expressed in seconds
// (rather than time.Duration) so it decodes cleanly from YAML.
PresignTTLSeconds int `yaml:"presignTTLSeconds"`
}
Config selects a storage backend via Type and carries each backend's own settings. Only the config for the selected Type is read. Rather than flattening every backend's settings into one struct, Config embeds each driver's own Config (drivers.LocalConfig, drivers.S3Config) verbatim — so each driver keeps ownership of its config shape and validation.
Config and the backend Config types it embeds carry yaml struct tags, so it can be embedded in a larger application config struct and populated generically (e.g. via yaml.Unmarshal) rather than constructed by hand.
type FileMetadata ¶
type FileMetadata struct {
ID string `json:"id"`
Name string `json:"name"`
Key string `json:"key"`
URL string `json:"url,omitempty"`
UploadURL string `json:"upload_url,omitempty"`
Size int64 `json:"size"`
MimeType string `json:"mime_type"`
}
FileMetadata represents the metadata of an uploaded file
type FileTooLargeError ¶ added in v0.3.0
type FileTooLargeError struct {
Limit int64
}
FileTooLargeError is returned by Upload for a file larger than the limit.
func (*FileTooLargeError) Error ¶ added in v0.3.0
func (e *FileTooLargeError) Error() string
type HTTPHandler ¶
type HTTPHandler struct {
Service *Service
}
func NewHTTPHandler ¶
func NewHTTPHandler(service *Service) *HTTPHandler
func (*HTTPHandler) Delete ¶
func (h *HTTPHandler) Delete(w http.ResponseWriter, r *http.Request)
func (*HTTPHandler) Download ¶
func (h *HTTPHandler) Download(w http.ResponseWriter, r *http.Request)
func (*HTTPHandler) Upload ¶
func (h *HTTPHandler) Upload(w http.ResponseWriter, r *http.Request)
type LocalContentHandler ¶ added in v0.3.0
type LocalContentHandler struct {
// contains filtered or unexported fields
}
LocalContentHandler serves the routes the local driver's upload and download URLs point at, standing in for S3 in local development. It is separate from HTTPHandler because it only exists for the local driver, and the app builds it only when that is the driver it chose.
The routes take no other auth: like an S3 presigned URL, each request must carry the token the driver signed for that key and operation.
func NewLocalContentHandler ¶ added in v0.3.0
func NewLocalContentHandler(driver *drivers.LocalFSDriver) *LocalContentHandler
func (*LocalContentHandler) RegisterRoutes ¶ added in v0.3.0
func (h *LocalContentHandler) RegisterRoutes(mux *http.ServeMux)
RegisterRoutes serves PUT and GET on the driver's ContentPattern, the path the driver builds its URLs from.
type Service ¶
type Service struct {
Driver StorageDriver
// contains filtered or unexported fields
}
Service coordinates file storage operations and manages metadata
func NewService ¶
func NewService(driver StorageDriver, opts ...ServiceOption) *Service
func (*Service) DownloadURL ¶ added in v0.3.0
DownloadURL is GetDownloadURL plus the time, in unix seconds, at which the URL stops working.
func (*Service) GetDownloadURL ¶
GetDownloadURL generates a time-limited or presigned URL for the given key
func (*Service) Save ¶ added in v0.3.0
func (s *Service) Save(ctx context.Context, filename, mime string, body io.Reader, size int64) (*FileMetadata, error)
Save stores content the caller already holds under a new key and returns its metadata. Persist the returned Key: Save stores only the bytes and the content type, so the key is the only way to find the file again.
Unlike Upload, there is no URL for anyone to upload to, and the Service's upload limits (WithAllowedUploadTypes, WithMaxUploadSize) don't apply: they govern what clients may upload, and a service decides for itself what it stores.
size is recorded in the returned metadata as given; Save doesn't count or check it. body is passed to the driver as is. For S3 over plain HTTP (e.g. a local MinIO), pass a seekable reader such as *bytes.Reader or *os.File.
func (*Service) Upload ¶
func (s *Service) Upload(ctx context.Context, filename string, size int64, mime string) (*FileMetadata, error)
Upload handles the preparation of a file upload by generating a unique key and a presigned/upload URL via the storage driver. The size and type are checked against the Service's limits here, because the presigned URL is what binds the upload to them.
type ServiceOption ¶ added in v0.3.0
type ServiceOption func(*Service)
ServiceOption configures a Service.
func WithAllowedUploadTypes ¶ added in v0.3.0
func WithAllowedUploadTypes(types ...string) ServiceOption
WithAllowedUploadTypes limits Upload to the given MIME types; any other type is rejected with ErrContentTypeNotAllowed. Called with no types, it rejects every upload. Without it, Upload accepts any type. It does not apply to Save.
func WithMaxUploadSize ¶ added in v0.3.0
func WithMaxUploadSize(n int64) ServiceOption
WithMaxUploadSize sets the largest file, in bytes, that Upload accepts. Without it the limit is 32MB. It panics if n is not positive. It does not apply to Save.
type StorageDriver ¶
type StorageDriver interface {
// Save writes the content to the storage under key
Save(ctx context.Context, key string, body io.Reader, contentType string) error
// Get returns a ReadCloser to stream the file back and its content type
Get(ctx context.Context, key string) (io.ReadCloser, string, error)
// Delete removes the file
Delete(ctx context.Context, key string) error
// GetDownloadURL returns a presigned or time-limited URL for downloading
GetDownloadURL(ctx context.Context, key string) (string, error)
// GetUploadURL returns a presigned URL for uploading a file directly to storage
GetUploadURL(ctx context.Context, key string, contentType string, maxSizeBytes int64) (string, error)
}
StorageDriver defines how we interact with the binary storage
func NewStorageFromConfig ¶
func NewStorageFromConfig(ctx context.Context, cfg Config) (StorageDriver, error)
NewStorageFromConfig creates a storage instance based on the provided configuration. It validates cfg first, so the type switch below only ever sees a supported Type.