httpcache

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Apr 28, 2024 License: MIT Imports: 13 Imported by: 0

README

HTTP-Cache-Go

HttpClient wrapper to cache http response Body in storage or memory.

Example


client := httpcache.DefaultClient
resp, err := client.Get("https://example.com/content.json")

If it does not exist in storage, make an Http request, cache the result, and use it for the next time.

Custom

client := &httpcache.Client{
    Client: &http.Client{
        // 
    },
    Cache: httpcache.NewMemoryCache(),
    Handler: httpcache.NewOnceLatestHandler(),
}

Cache

You can choose local storage or memory for storage location.

httpcache.NewStorageCache("/tmp")
httpcache.NewMemoryCache()

Or implements Cache interface.


type Cache interface {
    Put(Object) error
    Query(Object) (io.Reader, error)
}
Handler

You may decide to use the cache or not.

// Always use the latest.
NewLatestHandler = func() *Handler
// Get the latest only once at the beginning.
NewOnceLatestHandler = func() *Handler
// If there is a cache, use it; if not, get the latest and save the cache.
NewDefaultHandler = func() *Handler
// Always use and save cache.
NewSimpleHandler = func() *Handler

Or your custom Handler

type Handler struct {
    mu   sync.Mutex
    keys []string
    Pre  func(Cache, Object) (io.Reader, error)
    Post func(Cache, Object) error
}

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// Always use the latest.
	NewLatestHandler = func() *Handler {
		return &Handler{
			Pre:  func(c Cache, o Object) (io.Reader, error) { return nil, nil },
			Post: func(c Cache, o Object) error { return c.Put(o) },
		}
	}
	// Get the latest only once at the beginning.
	NewOnceLatestHandler = func() *Handler {
		var hander Handler
		hander.keys = make([]string, 0, 1000)
		hander.Pre = func(c Cache, o Object) (io.Reader, error) {
			hander.mu.Lock()
			defer hander.mu.Unlock()

			if slices.Contains(hander.keys, o.Key()) {
				return c.Query(o)
			}
			return nil, nil
		}
		hander.Post = func(c Cache, o Object) error {
			hander.mu.Lock()
			defer hander.mu.Unlock()

			if slices.Contains(hander.keys, o.Key()) {
				return nil
			}
			hander.keys = append(hander.keys, o.Key())
			return c.Put(o)
		}
		return &hander
	}
	// If there is a cache, use it; if not, get the latest and save the cache.
	NewDefaultHandler = func() *Handler {
		var hander Handler
		hander.keys = make([]string, 0, 1000)
		hander.Pre = func(c Cache, o Object) (io.Reader, error) {
			hander.mu.Lock()
			defer hander.mu.Unlock()
			r, err := c.Query(o)
			if err != nil {
				return r, err
			}

			hander.keys = append(hander.keys, o.Key())
			return r, nil
		}
		hander.Post = func(c Cache, o Object) error {
			hander.mu.Lock()
			defer hander.mu.Unlock()

			if slices.Contains(hander.keys, o.Key()) {
				return nil
			}
			return c.Put(o)
		}
		return &hander
	}
	// Always use and save cache.
	NewSimpleHandler = func() *Handler {
		var hander Handler
		hander.Pre = func(c Cache, o Object) (io.Reader, error) {
			return c.Query(o)
		}
		hander.Post = func(c Cache, o Object) error {
			return c.Put(o)
		}
		return &hander
	}
)
View Source
var DefaultClient = &Client{
	Client:  http.DefaultClient,
	Cache:   DefaultStorageCache,
	Handler: NewDefaultHandler(),
}
View Source
var DefaultMemoryCache = &MemoryCache{}
View Source
var DefaultStorageCache = &StorageCache{}
View Source
var ErrNoCache = errors.New("no cache")

Functions

This section is empty.

Types

type Cache

type Cache interface {
	Put(Object) error
	Query(Object) (io.Reader, error)
}

type Client

type Client struct {
	*http.Client
	Cache   Cache
	Handler *Handler
}

func (*Client) Do

func (c *Client) Do(req *http.Request) (*http.Response, error)

func (*Client) Get

func (c *Client) Get(url string) (resp *http.Response, err error)

func (*Client) Post

func (c *Client) Post(url, contentType string, body io.Reader) (resp *http.Response, err error)

func (*Client) PostForm

func (c *Client) PostForm(url string, data url.Values) (resp *http.Response, err error)

type Handler

type Handler struct {
	Pre  func(Cache, Object) (io.Reader, error)
	Post func(Cache, Object) error
	// contains filtered or unexported fields
}

type HttpResponseObject

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

func NewHttpResponseObject

func NewHttpResponseObject(uri string) (*HttpResponseObject, error)

func (*HttpResponseObject) Key

func (o *HttpResponseObject) Key() string

func (*HttpResponseObject) Length

func (o *HttpResponseObject) Length() int64

func (*HttpResponseObject) NewReader

func (o *HttpResponseObject) NewReader() io.Reader

func (*HttpResponseObject) ReadResponse

func (o *HttpResponseObject) ReadResponse(resp *http.Response) error

type MemoryCache

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

func NewMemoryCache

func NewMemoryCache() *MemoryCache

func (*MemoryCache) Put

func (c *MemoryCache) Put(o Object) error

func (*MemoryCache) Query

func (c *MemoryCache) Query(o Object) (io.Reader, error)

type Object

type Object interface {
	Key() string
	NewReader() io.Reader
	Length() int64
}

type StorageCache

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

func NewStorageCache

func NewStorageCache(dir string) *StorageCache

func (*StorageCache) Put

func (c *StorageCache) Put(o Object) error

func (*StorageCache) Query

func (c *StorageCache) Query(o Object) (io.Reader, error)

Jump to

Keyboard shortcuts

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