certificate_cache.go 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. // SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
  2. // SPDX-License-Identifier: Apache-2.0
  3. package storage // import "miniflux.app/v2/internal/storage"
  4. import (
  5. "context"
  6. "database/sql"
  7. "golang.org/x/crypto/acme/autocert"
  8. )
  9. // Making sure that we're adhering to the autocert.Cache interface.
  10. var _ autocert.Cache = (*certificateCache)(nil)
  11. // certificateCache provides a SQL backend to the autocert cache.
  12. type certificateCache struct {
  13. storage *Storage
  14. }
  15. // NewCertificateCache creates an cache instance that can be used with autocert.Cache.
  16. // It returns any errors that could happen while connecting to SQL.
  17. func NewCertificateCache(storage *Storage) *certificateCache {
  18. return &certificateCache{
  19. storage: storage,
  20. }
  21. }
  22. // Get returns a certificate data for the specified key.
  23. // If there's no such key, Get returns ErrCacheMiss.
  24. func (c *certificateCache) Get(ctx context.Context, key string) ([]byte, error) {
  25. query := `SELECT data::bytea FROM acme_cache WHERE key = $1`
  26. var data []byte
  27. err := c.storage.db.QueryRowContext(ctx, query, key).Scan(&data)
  28. if err == sql.ErrNoRows {
  29. return nil, autocert.ErrCacheMiss
  30. }
  31. return data, err
  32. }
  33. // Put stores the data in the cache under the specified key.
  34. func (c *certificateCache) Put(ctx context.Context, key string, data []byte) error {
  35. query := `INSERT INTO acme_cache (key, data, updated_at) VALUES($1, $2::bytea, now())
  36. ON CONFLICT (key) DO UPDATE SET data = $2::bytea, updated_at = now()`
  37. _, err := c.storage.db.ExecContext(ctx, query, key, data)
  38. if err != nil {
  39. return err
  40. }
  41. return nil
  42. }
  43. // Delete removes a certificate data from the cache under the specified key.
  44. // If there's no such key in the cache, Delete returns nil.
  45. func (c *certificateCache) Delete(ctx context.Context, key string) error {
  46. query := `DELETE FROM acme_cache WHERE key = $1`
  47. _, err := c.storage.db.ExecContext(ctx, query, key)
  48. if err != nil {
  49. return err
  50. }
  51. return nil
  52. }