certificate_cache.go 2.0 KB

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