Packages

A unified S3-compatible object storage library for Elixir with multi-CDN support.

Current section

Files

Jump to
ex_oss lib ex_oss.ex
Raw

lib/ex_oss.ex

defmodule ExOss do
@moduledoc """
A unified S3-compatible object storage library with multi-CDN support.
Supports AWS S3, Qiniu S3, and any S3-compatible service (MinIO, DigitalOcean Spaces,
Cloudflare R2, etc.) with optional CDN integration (CloudFront, Qiniu CDN).
## Quick Start
# 1. Define a storage module
defmodule MyApp.Storage do
use ExOss, otp_app: :my_app
end
# 2. Add configuration
config :my_app, MyApp.Storage,
provider: :aws,
access_key_id: "your-access-key",
secret_access_key: "your-secret-key",
region: "us-east-1"
# 3. Use it
MyApp.Storage.upload_credential("bucket", "path/file.jpg", 3600)
MyApp.Storage.authorize_download_url("bucket", "path/file.jpg", 3600)
## Multiple Clients
Define separate modules for different storage providers:
defmodule MyApp.AWSStorage do
use ExOss, otp_app: :my_app
end
defmodule MyApp.MinIOStorage do
use ExOss, otp_app: :my_app
end
config :my_app, MyApp.AWSStorage, provider: :aws, access_key_id: "...", ...
config :my_app, MyApp.MinIOStorage,
provider: :custom,
endpoint: "http://localhost:9000",
bucket_addressing: :path,
access_key_id: "minioadmin",
secret_access_key: "minioadmin"
Or build clients programmatically:
aws = ExOss.Client.new(provider: :aws, access_key_id: "...", ...)
minio = ExOss.Client.new(provider: :custom, endpoint: "...", ...)
ExOss.Runner.upload_credential(aws, "bucket", "key")
ExOss.Runner.public_url(minio, "bucket", "key")
## CDN Configuration
config :my_app, MyApp.Storage,
provider: :aws,
access_key_id: "...",
secret_access_key: "...",
cdn: [
provider: :cloudfront,
endpoint: "https://d123456789.cloudfront.net",
aws_key_id: "K2XXXXXXXXXXXXX",
aws_private_key: "-----BEGIN RSA PRIVATE KEY-----\\n..."
]
"""
defmacro __using__(opts) do
quote bind_quoted: [opts: opts] do
app = Keyword.fetch!(opts, :otp_app)
defp client do
storage_config()
|> Keyword.merge(unquote(opts))
|> ExOss.Client.new()
end
defp storage_config do
Application.fetch_env!(unquote(app), __MODULE__)
end
@doc """
Retrieves metadata for a file.
Returns `{:ok, %{file_size: integer, mime_type: string}}` or `{:error, :no_metadata}`.
"""
def metadata(bucket, res_key) do
ExOss.Runner.metadata(client(), bucket, res_key)
end
@doc """
Generates a signed download URL.
Options:
* `:att_name` - Download filename for Content-Disposition header
"""
def authorize_download_url(bucket, res_key, expires_in \\ 3600, opts \\ []) do
ExOss.Runner.authorize_download_url(client(), bucket, res_key, expires_in, opts)
end
@doc """
Generates upload credentials. Returns an `ExOss.UploadCredential` struct.
"""
def upload_credential(bucket, res_key, expires_in \\ 3600) do
ExOss.Runner.upload_credential(client(), bucket, res_key, expires_in)
end
@doc """
Executes a storage task (upload, copy, delete, etc.).
"""
def run(task) do
ExOss.Runner.run(client(), task)
end
@doc """
Generates index content for mkzip operations.
"""
def mkzip_index_content(items) do
ExOss.Runner.mkzip_index_content(client(), items)
end
@doc """
Generates a public (unsigned) URL.
"""
def public_url(bucket, res_key) do
ExOss.Runner.public_url(client(), bucket, res_key)
end
end
end
end