关于dart:实现Dart版本对象存储COS插件

45次阅读

共计 2963 个字符,预计需要花费 8 分钟才能阅读完成。

前言

在 Flutter Web 在《一起漫部》的性能优化摸索与实际 一文中,
在做加载优化时须要实现资源文件 cdn 化,意味着要将资源文件上传到腾讯的 COS 或者阿里的 OSS 这样的第三方对象存储服务器。目前公司应用的是腾讯的对象存储 (COS),本来想用官网提供的 SDK 去实现资源上传性能,然而官网并没有提供 Dart 版本的 SDK,去pub.dev 搜了下对于 cos 的相干插件,也没有找到性能绝对欠缺的插件,于是便打算手写一个 Dart 版本对象存储 (COS) 插件。

简介

在官网提供的 API 性能过于丰盛和工夫无限的状况下,只实现了局部性能:

  • 反对 Bucket 接口的基本操作,减少、删除、查问存储桶等
  • 反对 Bucket 接口的访问控制(acl)
  • 反对 Bucket 接口的跨域资源共享(cors)
  • 反对 Bucket 接口的防盗链(referer)
  • 反对 Object 接口的基本操作,上传、删除、查问存储对象等
  • 反对 Object 接口的访问控制(acl)

构造

工程次要包含示例 (example)、外围代码(lib) 和单元测试 (test) 三局部

├── CHANGELOG.md
├── LICENSE
├── README.md
├── analysis_options.yaml
├── example                                         // 示例
├── lib                                             // 外围代码
│   ├── src
│   │   ├── api
│   │   ├── client
│   │   ├── model
│   │   └── src.dart
│   └── tencent_cos_plus.dart
├── pubspec.lock
├── pubspec.yaml
├── tencent_cos_plus.iml
└── test                                            // 单元测试

示例

示例目前仅包含 tencent_cos_plus_example.dart 文件,次要是介绍如何应用插件,包含初始化配置、存储桶 Api 调用和存储对象 Api 调用。

├── example
│   └── tencent_cos_plus_example.dart

外围代码

外围代码 (lib) 局部由 clientapimodel三层形成:

  • client层封装了 http 申请和接口签名性能
  • api层实现了存储桶 (bucket) 和存储对象 (object) 局部 api 的调用
  • model层负责 xml 数据和实体对象的解析
├── api
│   ├── api.dart
│   ├── cos_abstract_api.dart
│   ├── cos_api_factory.dart
│   ├── cos_api_mixin.dart
│   ├── cos_bucket_api.dart
│   └── cos_object_api.dart
├── client
│   ├── client.dart
│   └── cos_client.dart
├── model
│   ├── common
│   │   ├── cos_access_control_policy.dart
│   │   ├── cos_common.dart
│   │   ├── cos_config.dart
│   │   ├── cos_cors_configuration.dart
│   │   ├── cos_exception.dart
│   │   └── cos_referer_configuration.dart
│   ├── model.dart
│   ├── request
│   │   ├── cos_bucket_acl_header.dart
│   │   ├── cos_create_bucket_configuration.dart
│   │   ├── cos_delete.dart
│   │   ├── cos_get_object.dart
│   │   └── cos_restore_request.dart
│   └── response
│       ├── cos_copy_object_result.dart
│       ├── cos_delete_result.dart
│       ├── cos_list_all_my_buckets_result.dart
│       ├── cos_list_bucket_result.dart
│       └── cos_list_versions_result.dart

单元测试

单元测试包含 cos_bucket_api_test.dartcos_object_api_test.dart两个文件,次要是笼罩了存储桶 (bucket)
和存储对象 (object) 局部 api 的单元测试

└── test
    ├── cos_bucket_api_test.dart
    └── cos_object_api_test.dart

应用阐明

对于如何应用,请参考 README

碰到的问题

在开发过程中,实现须要提交 xml 数据的接口时,呈现 签名不匹配 的问题。

<?xml version='1.0' encoding='utf-8' ?>
<Error>
    <Code>SignatureDoesNotMatch</Code>
    <Message>The Signature you specified is invalid.</Message>
    <StringToSign>sha1
1666158568;1666218568
488ab174d5f7a6ec0966aeeb82600e185114d7d1
</StringToSign>
    <FormatString>put
/
cors=
content-length=454&amp;content-md5=DfuiC7IOBwIeiVanWPG%2FKg%3D%3D&amp;content-type=application%2Fxml%3B%20charset%3Dutf-8&amp;date=Wed%2C%2019%20Oct%202022%2005%3A49%3A28%20GMT&amp;host=test-app-1251021022.cos.ap-guangzhou.myqcloud.com
</FormatString>
    <Resource>/</Resource>
    <RequestId>NjM0ZjhmZThfNDgzNjQwMGJfMTMwZWFfNDhmODEyZg==</RequestId>
    <TraceId>OGVmYzZiMmQzYjA2OWNhODk0NTRkMTBiOWVmMDAxODc0OWRkZjk0ZDM1NmI1M2E2MTRlY2MzZDhmNmI5MWI1OTBjYzE2MjAxN2M1MzJiOTdkZjMxMDVlYTZjN2FiMmI0MjFmNzE4ZjVmM2M0ZTcxNjYwMmQ3N2QzYjA3NzYyNmM=</TraceId>
</Error>

呈现这个问题后,先是确认了签名文档提供的签名规定是否统一,而后应用 COS 签名工具
去验证签名后果是否统一,发现在都没有问题。最初通过 api 接口返回的错误信息,发现参加签名的 content-type 和提交给 api 的 content-type
不统一,导致签名不匹配。

通过断点调试,排查到是应用的 http 插件造成的,在设置 body 时如果 content-type 没有 charset 时会赋值默认的charset,问题找到了。

其它

  • 目前有余的是上传文件和下载文件时,没有进度的回调

总结

整个插件实现起来不难,次要须要花工夫浏览腾讯对象存储 (COS) 文档,依据 Api 文档进行封装和测试,这里开源进去给须要的人提供帮忙。

  • pub: tencent_cos_plus
  • git: tencent_cos_plus

正文完
 0