s3

package module
v1.1.2 Latest Latest
Warning

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

Go to latest
Published: Apr 16, 2026 License: MIT Imports: 9 Imported by: 0

README

pkg/s3

Универсальный S3‑клиент для Go‑микросервисов SSO Easy. Построен поверх aws-sdk-go-v2. Совместим с любым S3‑совместимым хранилищем: AWS S3, Yandex Object Storage, MinIO, Tinkoff Cloud и другими.

Возможности

  • Простой и идиоматичный API
  • Поддержка path‑style URL (необходимо для MinIO и большинства non‑AWS хранилищ)
  • Предподписанные ссылки (pre‑signed URLs) с кэшированием клиента
  • Частичная выгрузка (Range запросы) для стриминга
  • Автоматическая пагинация при получении списка объектов
  • Структурированные ошибки с использованием общего пакета errors

Установка

go get github.com/ssoeasy-dev/pkg/s3@latest

Использование

Создание клиента
import s3pkg "github.com/ssoeasy-dev/pkg/s3"

cfg := &s3pkg.Config{
    Endpoint:       "https://storage.yandexcloud.net",
    Region:         "ru-central1",
    AccessKey:      os.Getenv("S3_ACCESS_KEY"),
    SecretKey:      os.Getenv("S3_SECRET_KEY"),
    Bucket:         "my-bucket",
    ForcePathStyle: true, // обязательно для не-AWS хранилищ
}
client, err := s3pkg.NewClient(cfg)
if err != nil {
    log.Fatal(err)
}
Загрузка объекта (Put)
ctx := context.Background()
key := "videos/abc.mp4"
r := strings.NewReader("hello world")
contentType := "text/plain"

res, err := client.Put(ctx, key, r, &contentType)
if err != nil {
    log.Fatal(err)
}
fmt.Println("ETag:", res.ETag)
Скачивание объекта (Get)
body, meta, err := client.Get(ctx, key, nil) // nil = весь объект
if err != nil {
    log.Fatal(err)
}
defer body.Close()

data, _ := io.ReadAll(body)
fmt.Printf("Размер: %d, тип: %s\n", meta.ContentLength, meta.ContentType)
Частичная выгрузка (Range)
rangeHeader := "bytes=0-1023"
body, meta, err := client.Get(ctx, key, &rangeHeader)
// ...
Получение метаданных без тела (Head)
meta, err := client.Head(ctx, key)
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Размер: %d, ETag: %s\n", meta.ContentLength, meta.ETag)
Список объектов по префиксу (List)

Автоматически обрабатывает пагинацию.

items, err := client.List(ctx, "videos/")
for _, item := range items {
    fmt.Printf("%s — %d байт, обновлён %s\n", item.Key, item.Size, item.UpdatedAt)
}
Генерация предподписанной ссылки (Presign)
url, err := client.Presign(ctx, key, 15*time.Minute)
if err != nil {
    log.Fatal(err)
}
// ссылка действительна 15 минут

Обработка ошибок

Все ошибки, возвращаемые пакетом, можно анализировать с помощью errors.Is и предопределённых типов из общего пакета github.com/ssoeasy-dev/pkg/errors:

Sentinel Когда возвращается
errors.ErrInvalidArgument Некорректные аргументы (пустой ключ, nil reader и т.п.)
errors.ErrNotFound Запрашиваемый объект не существует.
errors.ErrCreationFailed Не удалось создать или загрузить объект.
errors.ErrGetFailed Не удалось получить или перечислить объекты.

Пример:

if errors.Is(err, errors.ErrNotFound) {
    // обработка отсутствия объекта
}
Типы
// PutResult возвращается при успешной загрузке
type PutResult struct {
    ETag string // ETag загруженного объекта
}

// ObjectMetadata содержит метаданные объекта
type ObjectMetadata struct {
    ETag          string // ETag объекта
    ContentType   string // MIME-тип
    ContentLength int64  // размер в байтах
    Range         string // возвращённый диапазон (только при Range‑запросе)
}

// ListResult представляет один объект в списке
type ListResult struct {
    Key       string    // ключ объекта
    Size      int64     // размер в байтах
    ETag      string    // ETag
    UpdatedAt time.Time // время последнего изменения
}

Конфигурация

Поле Тип Описание
Endpoint string URL хранилища. Пусто для AWS S3.
Region string Регион. Например "ru-central1", "us-east-1".
AccessKey string Access key для аутентификации.
SecretKey string Secret key для аутентификации.
Bucket string Имя бакета.
ForcePathStyle bool Path-style URLs. Требуется для MinIO и большинства non-AWS.

Тестирование

  • Модульные тесты: go test ./... Проверяют валидацию аргументов и логику без внешних зависимостей.

  • Интеграционные тесты: go test -tags=integration ./... Запускают контейнер MinIO через testcontainers и выполняют реальные операции. Для стабильности CI используется t.Setenv("TESTCONTAINERS_RYUK_DISABLED", "true").

Лицензия

MIT — см. LICENSE.

Контакты

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

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

Client is a generic S3 client that works with any S3-compatible storage.

func NewClient

func NewClient(cfg *Config) (*Client, error)

NewClient creates a new S3 client with the given configuration.

func NewClientWithContext added in v1.1.0

func NewClientWithContext(ctx context.Context, cfg *Config) (*Client, error)

NewClientWithContext creates a new S3 client with the given configuration and context.

func (*Client) Get

func (c *Client) Get(ctx context.Context, key string, rangeHeader *string) (io.ReadCloser, *ObjectMetadata, error)

Get retrieves an object from the bucket. If rangeHeader is not nil, it must be a valid HTTP Range header (e.g., "bytes=0-1023"). The caller is responsible for closing the returned ReadCloser.

func (*Client) Head

func (c *Client) Head(ctx context.Context, key string) (*ObjectMetadata, error)

Head returns metadata about an object without downloading its body.

func (*Client) List added in v1.0.1

func (c *Client) List(ctx context.Context, prefix string) ([]ListResult, error)

List returns all objects with the given prefix, automatically handling pagination. Warning: for buckets with millions of objects, this method may consume a lot of memory. For such cases, consider using ListPages for iterative processing.

func (*Client) ListPages added in v1.1.0

func (c *Client) ListPages(ctx context.Context, prefix string, fn func([]ListResult) bool) error

ListPages iterates over objects with the given prefix, calling the provided function for each page of results. The function should return true to continue, false to stop. This method is memory-efficient for large buckets.

func (*Client) Presign added in v1.0.3

func (c *Client) Presign(ctx context.Context, key string, ttl time.Duration) (string, error)

Presign generates a pre-signed URL for the given object, valid for the specified duration.

func (*Client) Put

func (c *Client) Put(ctx context.Context, key string, r io.Reader, contentType *string) (*PutResult, error)

type Config

type Config struct {
	// Endpoint — URL хранилища. Оставьте пустым для AWS S3.
	// Пример: "https://storage.yandexcloud.net"
	Endpoint string

	// Region — регион хранилища. Например: "ru-central1", "us-east-1".
	Region string

	// AccessKey — access key для аутентификации.
	AccessKey string

	// SecretKey — secret key для аутентификации.
	SecretKey string

	// Bucket — имя бакета, с которым работает клиент.
	Bucket string

	// ForcePathStyle — использовать path-style URLs вместо virtual-hosted-style.
	// Требуется для MinIO и большинства S3-совместимых хранилищ.
	ForcePathStyle bool
}

Config содержит настройки подключения к S3-совместимому хранилищу.

type ListResult added in v1.0.1

type ListResult struct {
	Key       string
	Size      int64
	ETag      string
	UpdatedAt time.Time
}

ListResult represents a single object returned by List.

type ObjectMetadata added in v1.1.0

type ObjectMetadata struct {
	ETag          string
	ContentType   string
	ContentLength int64
	Range         string // only present when a range was requested
}

ObjectMetadata contains metadata about an S3 object.

type PutResult added in v1.1.0

type PutResult struct {
	ETag string
}

Jump to

Keyboard shortcuts

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