asset_delivery

package module
v0.0.0-...-04ab03e Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 17, 2022 License: MIT Imports: 26 Imported by: 0

README

Asset Delivery

Delivers resized assets (images) in response to HTTP requests. It contains two parts:

  • Delivery server
  • Resizing routine

Delivery Server

The delivery server attempts to find an existing resized file from a storage location. If the resized file is found it returns the resized file. Otherwise, it will deliver the original file and send an instruction to create a resized version of said file.

HTTP Request

Each request needs to have the following as URL parameters:

  • width
  • location
  • encoding (e.g., webp, jpeg, png)

For example, if you want a version of https://host/path with width=100 and encoding=webp, the resulting request would be https://[host]?width=100&url=https://host/path&encoding=webp

Environment Variables
  • BUCKET: GCP Storage bucket name
  • HOST: GCP Storage host (optional). You can fill this in if an emulator is being used.
Command-Line Arguments
  • ADDRESS: Address to bind to. Defaults to: 0.0.0.0:80
  • credentials: The location of the Google JWT file.
  • allowedHosts: A comma separated list of domain hosts. This is used to filter requests by the host in the "urL" query param (above). Only "url"s that contain one of the provided hosts will be resized. An empty value allows any.
  • project-id: Google Project ID (for logging & pubsub)
TODO:
  • Externalize the PubSub topic in an environment variable

Resizing

Resizing is done through GcfResize function which is meant to be run as a Google Cloud Function.

Environment Variables
  • PROJECTID: Google Project ID (used for logging)
  • BUCKET: GCP Storage bucket name

Documentation

Index

Constants

View Source
const MaxImageDimension = 4096
View Source
const ResizeTopic = "asset-delivery-resize"

PubSub topic for sending and receiving resize request

Variables

View Source
var (
	ErrFileNotHandled = errors.New("file type not handled")
	ErrInvalidBounds  = errors.New("invalid image bounds")
)
View Source
var ErrNoFile = errors.New("no file")

Functions

func DefaultImageDecode

func DefaultImageDecode(r io.Reader) (image.Image, error)

func GcfResize

func GcfResize(ctx context.Context, m PubSubMessage) error

GcfResize is meant to run on Google Cloud Functions

func GetImage

func GetImage(url string) ([]byte, string, error)

func ImageToBytes

func ImageToBytes(i image.Image, hint string, quality int) (*bytes.Buffer, error)

func NewGCloudLogger

func NewGCloudLogger(project, name string, opts ...option.ClientOption) (*logging.Client, *logger.Google, error)

func ReaderToImage

func ReaderToImage(r io.ReadSeeker, hint string) (image.Image, error)

Reader to image will try to read the image

func Resize

func Resize(fs FileSystem, opts ResizeOptions) error

func ResizeImage

func ResizeImage(img image.Image, target uint) (image.Image, error)

func WriteError

func WriteError(w http.ResponseWriter, err error)

Types

type FileInfo

type FileInfo interface {
	FileInfoWrite
	FileInfoRead
}

type FileInfoRead

type FileInfoRead interface {
	Created() time.Time
}

type FileInfoWrite

type FileInfoWrite interface {
	CacheControl() string
}

type FileSystem

type FileSystem interface {
	FromVolume(string) FileSystem
	ObjectURL(string) string
	Info(string) (FileInfo, error)
	ReadCloser(string) (io.ReadCloser, error)
	Write(string, io.Reader, FileInfoWrite) error
	Delete(string) error
}

type GCloudFileInfo

type GCloudFileInfo struct {
	// contains filtered or unexported fields
}

func (*GCloudFileInfo) CacheControl

func (i *GCloudFileInfo) CacheControl() string

func (*GCloudFileInfo) Created

func (i *GCloudFileInfo) Created() time.Time

type GCloudFileSystem

type GCloudFileSystem struct {
	Client *storage.Client
	Host   string
	Bucket string
	// contains filtered or unexported fields
}

func NewGCloudFileSystem

func NewGCloudFileSystem(opts ...option.ClientOption) (*GCloudFileSystem, error)

func (*GCloudFileSystem) Delete

func (fs *GCloudFileSystem) Delete(filename string) error

func (*GCloudFileSystem) FromVolume

func (fs *GCloudFileSystem) FromVolume(name string) FileSystem

func (*GCloudFileSystem) GetBucket

func (fs *GCloudFileSystem) GetBucket(bucket string) *storage.BucketHandle

func (*GCloudFileSystem) Info

func (fs *GCloudFileSystem) Info(filename string) (FileInfo, error)

func (*GCloudFileSystem) ObjectURL

func (fs *GCloudFileSystem) ObjectURL(filename string) string

func (*GCloudFileSystem) ReadCloser

func (fs *GCloudFileSystem) ReadCloser(filename string) (io.ReadCloser, error)

func (*GCloudFileSystem) Write

func (fs *GCloudFileSystem) Write(filename string, r io.Reader, info FileInfoWrite) error

type GCloudPubSub

type GCloudPubSub struct {
	logger.Logger
	*pubsub.Client
}

func NewGCloudPubSub

func NewGCloudPubSub(projectId string, opts ...option.ClientOption) (*GCloudPubSub, error)

func (*GCloudPubSub) Publish

func (p *GCloudPubSub) Publish(subj string, data []byte) error

type HTTPError

type HTTPError interface {
	Status() int
	Error() string
}

type Messager

type Messager interface {
	Publisher
	Subscriber
	Close()
}

type ParamError

type ParamError struct {
	Param     string
	Detail    string
	RootError error
}

func (*ParamError) Error

func (err *ParamError) Error() string

func (*ParamError) Root

func (err *ParamError) Root() error

func (*ParamError) Status

func (err *ParamError) Status() int

type PubSubMessage

type PubSubMessage struct {
	Data []byte `json:"data,omitempty"`
}

PubSubMessage is the payload of a Pub/Sub event. Data is strictly ResizeOptions. See the documentation for more details: https://cloud.google.com/pubsub/docs/reference/rest/v1/PubsubMessage

type Publisher

type Publisher interface {
	Publish(subj string, data []byte) error
}

type ResizeOptions

type ResizeOptions struct {
	Width        uint
	Location     string
	HashSum      string
	Encoding     string
	Prefix       string
	CacheControl string
}

func (*ResizeOptions) DesiredEncoding

func (opts *ResizeOptions) DesiredEncoding() string

func (*ResizeOptions) ObjectKey

func (opts *ResizeOptions) ObjectKey() string

func (*ResizeOptions) PopulateHash

func (opts *ResizeOptions) PopulateHash()

type ResizeOptionsProcessed

type ResizeOptionsProcessed struct {
	ResizeOptions
	URL   *url.URL
	Force bool
}

func NewResizeOptionsFromQuery

func NewResizeOptionsFromQuery(m map[string][]string) (ResizeOptionsProcessed, error)

type RootError

type RootError interface {
	Root() error
}

type Subscriber

type Subscriber interface {
	Subscribe(subj string, h func([]byte)) (Subscription, error)
}

type Subscription

type Subscription interface {
	Unsubscribe()
}

type SystemError

type SystemError struct {
	RootError error
	Detail    string
}

func (*SystemError) Error

func (err *SystemError) Error() string

func (*SystemError) Root

func (err *SystemError) Root() error

func (*SystemError) Status

func (err *SystemError) Status() int

type WriteInfo

type WriteInfo struct {
	// contains filtered or unexported fields
}

func (*WriteInfo) CacheControl

func (i *WriteInfo) CacheControl() string

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL