Crate xt_oss

source ·
Expand description

§XT - Aliyun OSS SDK

Crates.io MSRV Crates.io Total Downloads maintenance-status Crates.io License (version)

Rust语言编写的阿里云OSS的SDK,依据官方文档并参考了其他语言的实现。

  • 基于tokio-rs异步运行时与流行的reqwest库实现.
  • 尽量完整的OSS数据结构描述(structenum).
  • Builder设计模式的传参风格.
  • 实现常用的大部分API.
  • 完整Examples演示.

xtoss-1

[dependencies]
tokio = {version = "1.36.0", features = ["full"]}
xt-oss = "0.5.7"
#example 可选 dirs = "5.0.1" 
#example 可选 dotenv = "0.15.0"
#example 可选 serde_json = "1.0.114"
//! `cargo run --example api_region_describe -q`
//! 调用DescribeRegions接口查询所有支持地域或者指定地域对应的Endpoint信息,
use dotenv;
use std::process;
use xt_oss::{
    oss::entities::region::RegionInfo,
    prelude::*,
};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
  dotenv::dotenv().ok();
  // 从环境生成 oss::Options;
  let options = util::options_from_env();
  // builder oss::Options
  // let options = oss::Options::new()
  //     .with_access_key_id("-- your access_key_id --")
  //     .with_access_key_secret("-- your access_key_secret --");
  // 创建oss::Client
  let client = oss::Client::new(options);

  match client
    .DescribeRegions()
    // 可选参数
    // .with_region("oss-us-east-1")
    .execute()
    .await
    // 处理可能的reqwest错误
    .unwrap_or_else(|reqwest_error| {
        println!("reqweset error: {}", reqwest_error);
        process::exit(-1);
    }) {
    // 请求正常返回结果
    Ok(oss_data) => {
        let regions: Vec<RegionInfo> = oss_data.content().region_info;
        for e in regions {
            println!("{:>20} | {}", e.region, e.internet_endpoint);
        }
    }
    // 请求正常,返回oss错误消息
    Err(error_message) => {
        // let message = error_message.content();
        println!("request id: {}", &error_message.request_id());
        println!("oss error: {}", &error_message.content());
    }
  }
  Ok(())
}

§一、 Example

§二、 Options 配置

  • access_key_id 通过阿里云控制台创建的AccessKey ID
  • access_key_secret 通过阿里云控制台创建的AccessKey Secret
  • sts_token 使用临时授权方式
  • bucket 通过控制台或PutBucket创建的Bucket
  • endpoint OSS访问域名。
  • region Bucket所在的区域,默认值为oss-cn-hangzhou
  • internal 是否使用阿里云内网访问,默认值为false
  • cname 是否支持上传自定义域名,默认值为false
  • is_request_pay Bucket是否开启请求者付费模,默认值为false
  • secure 设置secure为true,则使用HTTPS;设置secure为false,则使用HTTP
  • timeout 超时时间,默认值为60秒

cname为true时,endpoint,bucket为必填,否则产生panic错误. 当internal为true时,忽略cname与endpoint 无论是否使用cname正确的设置region(location)与bucket

§构建方式生成oss::Options

use xt_oss::prelude::*;
// 构建方式
let options = oss::Options::new()
    .with_access_key_id("access_key_id")
    .with_access_key_secret("access_key_secret")
    .with_region("oss-cn-shanghai")
    .with_bucket("xtoss-ex")
    .with_secret(true)
    .with_internal(false);

let root_url = "https://oss-cn-hangzhou.aliyuncs.com";
let base_url = "https://xtoss-ex.oss-cn-shanghai.aliyuncs.com";

assert_eq!(options.root_url(), root_url);
assert_eq!(options.base_url(), base_url);

let client = oss::Client::new(options);

§环境变量生成oss::Options,格式参见 .env.example

use xt_oss::prelude::*;
// ...
dotenv::dotenv().ok();
let options = util::options_from_env();
let client = oss::Client::new(options);
// ...

§三、 Api方法与参数构建

xtoss-2

api方法命名遵循官方文档,例如 ListObjectsV2,DescribeRegions,熟悉官方文档并结合 代码提示将给库的使用带来方便.

  • 参数构建分为简单方式,直接在方法内传参数例如.HeadObject("mp3/Audio_0.4mb.mp3")
  • with_ 传参数,例如:. PutSymlink("tmp/test.txt").with_symlink_target("target.txt")
  • 参数builder构建 例如:
 // 构建参数
let index_document = IndexDocumentBuilder::new()
    .with_suffix("index.html")
    .with_support_sub_dir(true)
    .with_type(0)
    .build();
let error_document = ErrorDocumentBuilder::new()
    .with_http_status(StatusCode::NOT_FOUND)
    .with_key("error.html")
    .build();
let config = WebsiteConfigurationBuilder::new()
    .with_index_document(index_document)
    .with_error_document(error_document)
    // .with_routing_rules(rules)
    .build();
// 发出请求
let result = client
    .PutBucketWebsite()
    .with_config(config)
    .execute()
    .await
// ...

§四、 返回与错误处理

pub type ApiResponse<T> = Result<ApiData<T>, ApiData<ErrorMessage>>;
pub type ApiResult<T = ()> = Result<ApiResponse<T>, reqwest::Error>;
//...
match client
    .GetObjectTagging("excel/Spreadsheet-1000-rows.xls")
    .execute()
    .await
{
    Ok(Ok(data)) => {
        // data:ApiData<Tagging>
        println!("{}", data.request_id());
        println!("{:#?}", data.headers());
        println!("{:#?}", data.content());
    }
    Ok(Err(message)) => {
        // message: ApiData<ErrorMessage>
        println!("{}", message.request_id());
        println!("{:#?}", message.headers());
        println!("{:#?}", message.content());
    }
    Err(reqwest_error) => println!("{}", reqwest_error),
}
//...

§五、util提供一些工具方法

  • fn utc_to_gmt(datetime:DateTime<Utc>) -> String
  • fn local_to_gmt(local_datetime: DateTime<Local>) -> String
  • fn options_from_env() -> oss::Options<'static>
  • fn oss_file_md5
  • fn oss_md5
  • struct ByteRange

§关于ByteRange

提供了HTTP Range构造方法

assert_eq!(ByteRange::new().to_string(), "bytes=0-");
assert_eq!(ByteRange::new().with_amount(500).to_string(), "bytes=0-499");
assert_eq!(ByteRange::new().with_amount(-500).to_string(), "bytes=-500");
assert_eq!(ByteRange::new().with_start(100).to_string(), "bytes=100-");
// 通过元组生成
assert_eq!(ByteRange::from((100, 500)).to_string(), "bytes=100-599");
assert_eq!(ByteRange::from((100, -500)).to_string(), "bytes=0-99");
assert_eq!(ByteRange::from((100, -50)).to_string(), "bytes=50-99");

§六、 TODO

  • 完成剩下的api,修复bug
  • 逐步完善文档
  • 提供一些开箱即用的utils功能

§七、 欢迎提bug和需求

欢迎大家提出bug报告和功能需求。如果你在使用过程中遇到了任何问题或者有任何改进的建议,都可以在Issues中告知。


§附录:实现的Api

下面是计划中要实现的Api,★ 已经实现 ☆ 未实现.

§关于Service/Region

§Bucket - 基础操作

§合规保留策略(WORM)

§Bucket 权限控制(ACL)

§Bucket 生命周期(Lifecycle)

§Bucket 传输加速(TransferAcceleration)

§Bucket 版本控制(Versioning)

§Bucket 授权策略(Policy)

§Bucket 日志管理(Logging)

§Bucket 静态网站(Website)

§Bucket 防盗链(Referer)

§Bucket 标签(Tags)

§Bucket 加密(Encryption)

§Bucket 请求者付费(RequestPayment)

§Bucket 跨域资源共享(CORS)

§Bucket 自定义域名(CNAME)

§Bucket 图片样式(Style)

§Object 基础操作 Stand

§Object 分片上传(MultipartUpload)

§Object 权限控制(ACL)

§Object 标签(Tagging)

§关于LiveChannel的操作

Modules§