aqua

package module
v1.0.3 Latest Latest
Warning

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

Go to latest
Published: Jul 24, 2026 License: MIT Imports: 16 Imported by: 0

README

🌊 Aqua

Go Reference Go Version Zero Dependencies License

Aqua 是一个极简、高性能、零第三方依赖的 Go 语言 S3 客户端 SDK

原生实现了 AWS Signature Version 4 (SigV4) 签名算法,为核心S3 API 轻量化场景打造


✨ 核心优势

  • 零第三方依赖 (Zero Dependencies):仅基于 Go 标准库实现,没有庞大的 SDK 依赖包。

📥 安装

go get github.com/purus-dev/aqua

🚀 快速开始

1. 初始化客户端

package main

import (
	"context"
	"fmt"
	"log"

	"github.com/purus-dev/aqua"
)

func main() {
	config := aqua.Config{
		AccessKeyID:     "your-access-key-id",
		AccessKeySecret: "your-access-key-secret",
		Bucket:          "my-bucket",
		Endpoint:        "s3.us-east-1.amazonaws.com",
		Region:          "us-east-1",
		UseSSL:          true,
	}
	client := aqua.NewClient(&config)
}


💡 API 使用示例

📤 上传与下载文件

content := strings.NewReader("Hello Aqua S3 SDK!")
err := client.UploadFile(ctx, "docs/hello.txt", content, "text/plain")
if err != nil {
	log.Fatalf("上传文件失败: %v", err)
}

data, err := client.DownloadFile(ctx, "docs/hello.txt")
if err != nil {
	log.Fatalf("下载文件失败: %v", err)
}
fmt.Println("文件内容:", string(data))

stream, err := client.DownloadStream(ctx, "videos/sample.mp4")
if err != nil {
	log.Fatalf("打开下载流失败: %v", err)
}
defer stream.Close()

io.Copy(localFile, stream)

🔍 元数据与断点续传 (Range Download)

headers, err := client.HeadObject(ctx, "docs/hello.txt")
if err == nil {
	fmt.Println("文件大小:", headers.Get("Content-Length"))
	fmt.Println("文件类型:", headers.Get("Content-Type"))
}

partData, err := client.DownloadFileWithRange(ctx, "docs/hello.txt", "bytes=0-10")
if err != nil {
	log.Fatalf("分段下载失败: %v", err)
}

🧩 分片上传大文件 (Multipart Upload)

objectName := "bigdata/archive.zip"

uploadID, err := client.InitiateMultipartUpload(ctx, objectName, "application/zip")
if err != nil {
	log.Fatalf("初始化分片上传失败: %v", err)
}

part1Reader := strings.NewReader("part-1-data...")
etag1, err := client.UploadPart(ctx, objectName, uploadID, 1, part1Reader, "application/zip")

part2Reader := strings.NewReader("part-2-data...")
etag2, err := client.UploadPart(ctx, objectName, uploadID, 2, part2Reader, "application/zip")

parts := []aqua.Part{
	{PartNumber: 1, ETag: etag1},
	{PartNumber: 2, ETag: etag2},
}
err = client.CompleteMultipartUpload(ctx, objectName, uploadID, parts)
if err != nil {
	client.AbortMultipartUpload(ctx, objectName, uploadID)
	log.Fatalf("合并分片上传失败: %v", err)
}

🔗 SigV4 预签名链接生成 (Presigned URL)

无需暴露密钥,生成带私有签名的临时访问链接供前端或第三方使用:

downloadURL, err := client.GetPresignedURL("photos/avatar.png", 3600)
if err != nil {
	log.Fatalf("生成下载链接失败: %v", err)
}
fmt.Println("临时下载链接:", downloadURL)

uploadURL, err := client.PutObjectPresign("photos/upload.png", 1800, "image/png")
if err != nil {
	log.Fatalf("生成上传链接失败: %v", err)
}
fmt.Println("临时上传链接:", uploadURL)

🧪 运行测试

仓库包含了完整的单元与集成测试用例,可配合 MinIO 或公有云 S3 运行:

export S3_ACCESS_KEY_ID="minioadmin"
export S3_ACCESS_KEY_SECRET="minioadmin"
export S3_BUCKET="test-bucket"
export S3_ENDPOINT="127.0.0.1:9000"
export S3_USE_SSL="false"

go test -v .

Documentation

Index

Constants

View Source
const (
	DefaultRegion       = "auto"
	DefaultUseSSL       = true
	MaxPresignedExpires = 7 * 24 * 60 * 60 // 7 days
	// UnsignedPayload 是 AWS SigV4 规范中定义的官方特殊常量
	// 当使用 HTTPS 传输时,向 S3 声明 "UNSIGNED-PAYLOAD" 可以跳过客户端对文件内容的全量 SHA-256 计算
	// 这样能实现 O(1) 内存占用,极大提升大文件与流式上传的传输性能,同时由于现代Https/TLS协议的安全性,无需担心数据完整性问题
	UnsignedPayload = "UNSIGNED-PAYLOAD"
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

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

func NewClient

func NewClient(config *Config) *Client

func (*Client) AbortMultipartUpload

func (c *Client) AbortMultipartUpload(ctx context.Context, objectName, uploadID string) error

func (*Client) CompleteMultipartUpload

func (c *Client) CompleteMultipartUpload(ctx context.Context, objectName, uploadID string, parts []Part) error

func (*Client) DeleteFile

func (c *Client) DeleteFile(ctx context.Context, objectName string) error

func (*Client) DownloadFile

func (c *Client) DownloadFile(ctx context.Context, objectName string) ([]byte, error)

func (*Client) DownloadFileWithRange

func (c *Client) DownloadFileWithRange(ctx context.Context, objectName, rangeHeader string) ([]byte, error)

func (*Client) DownloadStream

func (c *Client) DownloadStream(ctx context.Context, objectName string) (io.ReadCloser, error)

func (*Client) GetPresignedURL

func (c *Client) GetPresignedURL(objectName string, expiresIn int64) (string, error)

GetPresignedURL 生成带签名的临时下载链接

func (*Client) HeadObject

func (c *Client) HeadObject(ctx context.Context, objectName string) (http.Header, error)

func (*Client) InitiateMultipartUpload

func (c *Client) InitiateMultipartUpload(ctx context.Context, objectName, contentType string) (string, error)

func (*Client) PutObjectPresign

func (c *Client) PutObjectPresign(objectName string, expiresIn int64, contentType string) (string, error)

PutObjectPresign 生成带签名的预上传链接

func (*Client) UploadFile

func (c *Client) UploadFile(
	ctx context.Context,
	objectName string,
	data io.Reader,
	contentType string,
) error

----------------------------------------------------------------------------- Core Object API -----------------------------------------------------------------------------

func (*Client) UploadPart

func (c *Client) UploadPart(
	ctx context.Context,
	objectName, uploadID string,
	partNumber int,
	data io.Reader,
	contentType string,
) (string, error)

type CompleteMultipartUpload

type CompleteMultipartUpload struct {
	XMLName xml.Name `xml:"CompleteMultipartUpload"`
	Parts   []Part   `xml:"Part"`
}

type Config

type Config struct {
	AccessKeyID     string
	AccessKeySecret string
	Bucket          string
	Region          string
	Endpoint        string
	UseSSL          bool
	UsePathStyle    bool // 是否使用<路径模式> (默认<虚拟主机模式>)
}

----------------------------------------------------------------------------- 配置与客户端定义 (Config & Client) -----------------------------------------------------------------------------

func (*Config) FromEnv

func (c *Config) FromEnv() error

func (*Config) Validate

func (c *Config) Validate() error

type Part

type Part struct {
	PartNumber int    `xml:"PartNumber"`
	ETag       string `xml:"ETag"`
}

Jump to

Keyboard shortcuts

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