activestorage_qinium 0.4.0 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e590bb1798ce61b646b065e247820d3febcc2eebb0efa5475e2240701ccbf14a
4
- data.tar.gz: 7711785ef96a898e174fa7157608a2b8f1e4d84a3b8e9a386ea0ff07fdf3c5f1
3
+ metadata.gz: 0b6ef8d150c7dfdd39e09884bd2938787b9000d04114104661c64ce69556fd32
4
+ data.tar.gz: 618db182e05524e22984995769199f38e9c4df22c9d4da1d8e6f0476daa4870f
5
5
  SHA512:
6
- metadata.gz: 0e53820bad4cb1197da14cef634b6476d11b35222321033b90a4c7b7d356de72418dd33ebb2d3daaf660c167a6b13af1f1498e6e1571e3cc29bbd794abf0c830
7
- data.tar.gz: a706dc0cb47e2b2e91832439d815e72e1a53ecce9426330ad28811860e61084dd99476d79f65f08034b1d57d5ee976c621ee58802096251f3ffb64c1f9724083
6
+ metadata.gz: 777126f04943c53249d89a478c8cdebf58d47ed8b79ab061c724342e7f1f5550cb987259acde03f0563bb5a3306cab7f4f7fd8923f30fb737e390b8f38a74882
7
+ data.tar.gz: a4b7f0c854eeb5962b27bcbd658794f9db49c0351ab5040fc58bda667a8a8f381143a0928dfbc9799437a99efa5372caef3adc4ac35e5484e0d35645e21efb60
data/CHANGELOG.md CHANGED
@@ -1,9 +1,68 @@
1
+ # Changelog
2
+
3
+ 所有对 `activestorage_qinium` 的显著更改都将记录在此文件中。
4
+
5
+ 格式基于 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.0.0/),
6
+ 并且本项目遵循 [语义化版本控制](https://semver.org/lang/zh-CN/)。
7
+
1
8
  ## [Unreleased]
2
9
 
3
- ## [0.1.0] - 2022-08-10
10
+ ## [0.4.2] - 2026-04-02
11
+
12
+ ### Added
13
+
14
+ - 完善测试覆盖:添加 `upload`、`download`、`delete`、`copy`、`fetch`、`exist?` 等核心方法的测试
15
+ - 更新 README:添加详细配置示例、使用说明、URL 参数详解
16
+ - 添加 WebMock 测试依赖
17
+
18
+ ### Fixed
19
+
20
+ - 修复 gemspec 中的拼写错误(muti-tenant -> multi-tenant)
21
+
22
+ ## [0.4.1] - 2024-03-15
23
+
24
+ ### Added
4
25
 
5
- - Initial release
26
+ - 增强 URL 生成功能:支持更多响应头参数自定义
27
+ - `response_content_type` - 自定义 Content-Type
28
+ - `response_cache_control` - 自定义 Cache-Control
29
+ - `response_content_disposition` - 自定义 Content-Disposition
30
+ - `response_content_encoding` - 自定义 Content-Encoding
31
+ - `response_content_language` - 自定义 Content-Language
32
+ - `response_expires` - 自定义 Expires
33
+ - `traffic_limit` - 下载限速
34
+ - 改进附件下载:使用 `attname` 和 `response-content-disposition` 双重参数确保浏览器正确下载
35
+ - 添加中文文件名下载支持
36
+
37
+ ### Changed
38
+
39
+ - 优化 `url` 方法:重构查询参数构建逻辑
40
+ - 改进 URL 编码:对 key 的路径部分正确编码
41
+ - 完善私有资源下载:将 fop 参数传递给授权 URL 生成
42
+
43
+ ## [0.4.0] - 2024-XX-XX
44
+
45
+ ### Added
46
+
47
+ - 支持多租户配置
48
+ - 添加 `QiniumImageAnalyzer` 自定义图片分析器
49
+ - 实现 `http_response_type_for_direct_upload` 方法
50
+ - 支持 `update_metadata` 方法(空实现,因七牛云不支持此操作)
6
51
 
7
52
  ## [0.2.1] - 2024-05-09
8
53
 
9
- - Support private download url
54
+ ### Added
55
+
56
+ - 支持私有空间下载 URL 生成
57
+ - 添加 `Qinium::Auth.authorize_download_url` 签名机制
58
+
59
+ ## [0.1.0] - 2022-08-10
60
+
61
+ ### Added
62
+
63
+ - 初始发布
64
+ - 实现 Active Storage 服务所有必需方法
65
+ - 支持七牛云公有空间
66
+ - 支持分块上传
67
+ - 支持直接上传(浏览器直传)
68
+ - 添加 `QiniumImageAnalyzer` 图片分析器
data/Gemfile.lock CHANGED
@@ -1,18 +1,109 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- activestorage_qinium (0.3.0)
5
- qinium (~> 0.3.0)
4
+ activestorage_qinium (0.4.2)
5
+ qinium (~> 0.4.0)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
+ actionpack (8.1.3)
11
+ actionview (= 8.1.3)
12
+ activesupport (= 8.1.3)
13
+ nokogiri (>= 1.8.5)
14
+ rack (>= 2.2.4)
15
+ rack-session (>= 1.0.1)
16
+ rack-test (>= 0.6.3)
17
+ rails-dom-testing (~> 2.2)
18
+ rails-html-sanitizer (~> 1.6)
19
+ useragent (~> 0.16)
20
+ actionview (8.1.3)
21
+ activesupport (= 8.1.3)
22
+ builder (~> 3.1)
23
+ erubi (~> 1.11)
24
+ rails-dom-testing (~> 2.2)
25
+ rails-html-sanitizer (~> 1.6)
26
+ activejob (8.1.3)
27
+ activesupport (= 8.1.3)
28
+ globalid (>= 0.3.6)
29
+ activemodel (8.1.3)
30
+ activesupport (= 8.1.3)
31
+ activerecord (8.1.3)
32
+ activemodel (= 8.1.3)
33
+ activesupport (= 8.1.3)
34
+ timeout (>= 0.4.0)
35
+ activestorage (8.1.3)
36
+ actionpack (= 8.1.3)
37
+ activejob (= 8.1.3)
38
+ activerecord (= 8.1.3)
39
+ activesupport (= 8.1.3)
40
+ marcel (~> 1.0)
41
+ activesupport (8.1.3)
42
+ base64
43
+ bigdecimal
44
+ concurrent-ruby (~> 1.0, >= 1.3.1)
45
+ connection_pool (>= 2.2.5)
46
+ drb
47
+ i18n (>= 1.6, < 2)
48
+ json
49
+ logger (>= 1.4.2)
50
+ minitest (>= 5.1)
51
+ securerandom (>= 0.3)
52
+ tzinfo (~> 2.0, >= 2.0.5)
53
+ uri (>= 0.13.1)
54
+ addressable (2.8.9)
55
+ public_suffix (>= 2.0.2, < 8.0)
10
56
  ast (2.4.2)
57
+ base64 (0.3.0)
58
+ bigdecimal (4.1.0)
59
+ builder (3.3.0)
60
+ concurrent-ruby (1.3.6)
61
+ connection_pool (3.0.2)
62
+ crack (1.0.1)
63
+ bigdecimal
64
+ rexml
65
+ crass (1.0.6)
11
66
  diff-lcs (1.5.0)
67
+ drb (2.2.3)
68
+ erubi (1.13.1)
69
+ globalid (1.3.0)
70
+ activesupport (>= 6.1)
71
+ hashdiff (1.2.1)
72
+ i18n (1.14.8)
73
+ concurrent-ruby (~> 1.0)
74
+ json (2.19.3)
75
+ logger (1.7.0)
76
+ loofah (2.25.1)
77
+ crass (~> 1.0.2)
78
+ nokogiri (>= 1.12.0)
79
+ marcel (1.1.0)
80
+ mini_portile2 (2.8.9)
81
+ minitest (6.0.3)
82
+ drb (~> 2.0)
83
+ prism (~> 1.5)
84
+ nokogiri (1.19.2)
85
+ mini_portile2 (~> 2.8.2)
86
+ racc (~> 1.4)
12
87
  parallel (1.22.1)
13
88
  parser (3.1.1.0)
14
89
  ast (~> 2.4.1)
15
- qinium (0.3.0)
90
+ prism (1.9.0)
91
+ public_suffix (7.0.2)
92
+ qinium (0.4.0)
93
+ racc (1.8.1)
94
+ rack (3.2.6)
95
+ rack-session (2.1.1)
96
+ base64 (>= 0.1.0)
97
+ rack (>= 3.0.0)
98
+ rack-test (2.2.0)
99
+ rack (>= 1.3)
100
+ rails-dom-testing (2.3.0)
101
+ activesupport (>= 5.0.0)
102
+ minitest
103
+ nokogiri (>= 1.6)
104
+ rails-html-sanitizer (1.7.0)
105
+ loofah (~> 2.25)
106
+ nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
16
107
  rainbow (3.1.1)
17
108
  rake (13.0.6)
18
109
  regexp_parser (2.5.0)
@@ -42,16 +133,28 @@ GEM
42
133
  rubocop-ast (1.17.0)
43
134
  parser (>= 3.1.1.0)
44
135
  ruby-progressbar (1.11.0)
136
+ securerandom (0.4.1)
137
+ timeout (0.6.1)
138
+ tzinfo (2.0.6)
139
+ concurrent-ruby (~> 1.0)
45
140
  unicode-display_width (2.1.0)
141
+ uri (1.1.1)
142
+ useragent (0.16.11)
143
+ webmock (3.26.1)
144
+ addressable (>= 2.8.0)
145
+ crack (>= 0.3.2)
146
+ hashdiff (>= 0.4.0, < 2.0.0)
46
147
 
47
148
  PLATFORMS
48
149
  ruby
49
150
 
50
151
  DEPENDENCIES
152
+ activestorage (>= 6.1)
51
153
  activestorage_qinium!
52
154
  rake (~> 13.0)
53
155
  rspec (~> 3.0)
54
156
  rubocop (~> 1.21)
157
+ webmock (~> 3.0)
55
158
 
56
159
  BUNDLED WITH
57
160
  2.3.9
data/README.md CHANGED
@@ -1,33 +1,202 @@
1
- # ActivestorageQinium
1
+ # ActiveStorage Qinium
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/activestorage_qinium.svg)](https://badge.fury.io/rb/activestorage_qinium)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ Active Storage 的七牛云存储服务扩展,支持多租户配置和图片分析器。
7
+
8
+ ## 功能特性
9
+
10
+ - **完整 Active Storage 支持**:实现所有必需的服务方法(upload、download、delete、url 等)
11
+ - **分块上传**:支持大文件分块上传,断点续传
12
+ - **公有/私有空间**:支持七牛云公有和私有 bucket 配置
13
+ - **自定义图片分析器**:利用七牛云 imageInfo API 获取图片元数据
14
+ - **直接上传**:支持浏览器直传七牛云,减轻服务器压力
15
+ - **URL 参数支持**:支持 disposition、content_type、fop 等参数自定义
16
+ - **多租户支持**:通过 qinium gem 实现灵活的多租户配置
17
+
18
+ ## 安装
19
+
20
+ 添加到你的 Gemfile:
21
+
22
+ ```ruby
23
+ gem 'activestorage_qinium', '~> 0.4'
24
+ ```
25
+
26
+ 然后执行:
27
+
28
+ ```bash
29
+ $ bundle install
30
+ ```
31
+
32
+ ## 配置
33
+
34
+ ### 基础配置
35
+
36
+ 在 `config/storage.yml` 中配置七牛云存储:
37
+
38
+ ```yaml
39
+ # 公有空间(适合图片、静态资源)
40
+ qiniu_public:
41
+ service: Qinium
42
+ public: true
43
+ bucket: your-public-bucket
44
+ domain: your-domain.clouddn.com
45
+ access_key: <%= ENV['QINIU_ACCESS_KEY'] %>
46
+ secret_key: <%= ENV['QINIU_SECRET_KEY'] %>
47
+ protocol: https
48
+ block_size: 4194304 # 可选,分块大小(字节),默认 4MB
49
+ expires_in: 3600 # 可选,私有 URL 过期时间(秒)
50
+
51
+ # 私有空间(适合敏感文件)
52
+ qiniu_private:
53
+ service: Qinium
54
+ public: false
55
+ bucket: your-private-bucket
56
+ domain: your-private-domain.clouddn.com
57
+ access_key: <%= ENV['QINIU_ACCESS_KEY'] %>
58
+ secret_key: <%= ENV['QINIU_SECRET_KEY'] %>
59
+ protocol: https
60
+ ```
61
+
62
+ ### 环境变量
63
+
64
+ ```bash
65
+ export QINIU_ACCESS_KEY=your_access_key
66
+ export QINIU_SECRET_KEY=your_secret_key
67
+ ```
68
+
69
+ ### 多租户配置
70
+
71
+ 通过 Qinium gem 的配置系统实现多租户:
72
+
73
+ ```ruby
74
+ # config/initializers/qinium.rb
75
+ Qinium.configure do |config|
76
+ config.tenant_settings = {
77
+ tenant_a: {
78
+ bucket: 'tenant-a-bucket',
79
+ access_key: ENV['TENANT_A_ACCESS_KEY'],
80
+ secret_key: ENV['TENANT_A_SECRET_KEY']
81
+ },
82
+ tenant_b: {
83
+ bucket: 'tenant-b-bucket',
84
+ access_key: ENV['TENANT_B_ACCESS_KEY'],
85
+ secret_key: ENV['TENANT_B_SECRET_KEY']
86
+ }
87
+ }
88
+ end
89
+ ```
90
+
91
+ ## 使用
92
+
93
+ ### 基本使用
94
+
95
+ ```ruby
96
+ # 存储文件
97
+ user.avatar.attach(io: File.open('/path/to/avatar.jpg'), filename: 'avatar.jpg')
98
+
99
+ # 获取 URL
100
+ user.avatar.url # 内联显示
101
+ user.avatar.url(disposition: :attachment) # 下载附件
102
+ user.avatar.url(disposition: :attachment, filename: "自定义文件名.jpg")
103
+
104
+ # 图片处理(fop 参数)
105
+ user.avatar.url(fop: 'imageView2/0/w/200/h/200')
106
+ ```
107
+
108
+ ### 直接上传(浏览器直传)
109
+
110
+ ```erb
111
+ <%= form_with model: @user, local: true do |form| %>
112
+ <%= form.file_field :avatar,
113
+ direct_upload: true,
114
+ data: {
115
+ direct_upload_url: rails_direct_uploads_url
116
+ } %>
117
+ <%= form.submit %>
118
+ <% end %>
119
+ ```
120
+
121
+ ### URL 参数详解
122
+
123
+ ```ruby
124
+ # 强制下载
125
+ blob.url(disposition: :attachment)
126
+ blob.url(disposition: :attachment, filename: "报告.pdf")
127
+
128
+ # 自定义响应头(仅公有资源支持)
129
+ blob.url(
130
+ response_content_type: "application/octet-stream",
131
+ response_cache_control: "max-age=3600",
132
+ response_content_disposition: "attachment; filename=doc.pdf"
133
+ )
134
+
135
+ # 下载限速(单位:bit/s,范围 819200 ~ 838860800)
136
+ blob.url(traffic_limit: 819200)
137
+
138
+ # 图片处理
139
+ blob.url(fop: 'imageInfo') # 图片信息
140
+ blob.url(fop: 'imageView2/2/w/200') # 缩略图
141
+ blob.url(fop: 'imageMogr2/rotate/90') # 旋转
142
+ ```
143
+
144
+ ## 图片分析器
145
+
146
+ QiniumImageAnalyzer 利用七牛云 imageInfo API 获取图片元数据:
147
+
148
+ ```ruby
149
+ # 自动注册的分析器
150
+ ActiveStorage::Service::QiniumService.analyzers
151
+ # => [ActiveStorage::Analyzer::QiniumImageAnalyzer]
152
+
153
+ # 获取图片元数据
154
+ blob.metadata
155
+ # => {
156
+ # size: 39504,
157
+ # format: "jpg",
158
+ # width: 708,
159
+ # height: 576,
160
+ # colorModel: "ycbcr"
161
+ # }
162
+ ```
163
+
164
+ ## 支持的 Active Storage 版本
165
+
166
+ | Gem 版本 | Active Storage 版本 |
167
+ |---------|-------------------|
168
+ | 0.4.x | >= 6.1 |
169
+
170
+ ## 开发
171
+
172
+ 克隆仓库后运行测试:
173
+
174
+ ```bash
175
+ $ bundle install
176
+ $ bundle exec rspec
177
+ ```
178
+
179
+ 运行特定测试:
180
+
181
+ ```bash
182
+ $ bundle exec rspec spec/active_storage/service/qinium_service_url_spec.rb
183
+ $ bundle exec rspec spec/active_storage/service/qinium_service_spec.rb
184
+ ```
2
185
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/activestorage_qinium`. To experiment with that code, run `bin/console` for an interactive prompt.
186
+ ## 贡献
4
187
 
5
- TODO: Delete this and the text above, and describe your gem
188
+ 1. Fork 项目
189
+ 2. 创建功能分支 (`git checkout -b feature/amazing-feature`)
190
+ 3. 提交更改 (`git commit -m 'Add some amazing feature'`)
191
+ 4. 推送到分支 (`git push origin feature/amazing-feature`)
192
+ 5. 创建 Pull Request
6
193
 
7
- ## Installation
194
+ ## 许可证
195
+
196
+ [MIT 许可证](https://opensource.org/licenses/MIT)
8
197
 
9
- Install the gem and add to the application's Gemfile by executing:
10
-
11
- $ bundle add activestorage_qinium
12
-
13
- If bundler is not being used to manage dependencies, install the gem by executing:
14
-
15
- $ gem install activestorage_qinium
16
-
17
- ## Usage
18
-
19
- TODO: Write usage instructions here
20
-
21
- ## Development
22
-
23
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
24
-
25
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
26
-
27
- ## Contributing
28
-
29
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/activestorage_qinium.
30
-
31
- ## License
32
-
33
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
198
+ ## 相关项目
199
+
200
+ - [qinium](https://github.com/xiaohui-zhangxh/qinium) - 底层七牛云 SDK
201
+ - [Active Storage](https://edgeguides.rubyonrails.org/active_storage_overview.html) - Rails 官方文档
202
+ - [七牛云文档](https://developer.qiniu.com/kodo) - 七牛云开发者中心
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
8
8
  spec.authors = ["xiaohui"]
9
9
  spec.email = ["xiaohui@tanmer.com"]
10
10
 
11
- spec.summary = "A muti-tenant SDK wrap the Qiniu Storage Service as an Active Storage service"
12
- spec.description = "Wraps the Qiniu Storage Service as an Active Storage service, support muti-tenant settings. https://www.qiniu.com"
11
+ spec.summary = "A multi-tenant SDK wrap the Qiniu Storage Service as an Active Storage service"
12
+ spec.description = "Wraps the Qiniu Storage Service as an Active Storage service, support multi-tenant settings. https://www.qiniu.com"
13
13
  spec.homepage = "https://github.com/xiaohui-zhangxh/activestorage_qinium"
14
14
  spec.license = "MIT"
15
15
  spec.required_ruby_version = ">= 2.6.0"
@@ -17,6 +17,7 @@ Gem::Specification.new do |spec|
17
17
  spec.metadata["homepage_uri"] = spec.homepage
18
18
  spec.metadata["source_code_uri"] = spec.homepage
19
19
  spec.metadata["changelog_uri"] = "#{spec.homepage}/CHANGELOG.md"
20
+ spec.metadata["bug_tracker_uri"] = "#{spec.homepage}/issues"
20
21
 
21
22
  spec.files = Dir.chdir(File.expand_path(__dir__)) do
22
23
  `git ls-files -z`.split("\x0").reject do |f|
@@ -27,4 +28,8 @@ Gem::Specification.new do |spec|
27
28
  spec.require_paths = ["lib"]
28
29
 
29
30
  spec.add_dependency "qinium", "~> 0.4.0"
31
+
32
+ spec.add_development_dependency "activestorage", ">= 6.1"
33
+ spec.add_development_dependency "rspec", "~> 3.0"
34
+ spec.add_development_dependency "webmock", "~> 3.0"
30
35
  end
@@ -10,7 +10,7 @@ module ActiveStorage
10
10
  to: :config
11
11
 
12
12
  def self.analyzers
13
- [ActiveStorage::Analyzer::QiniumImageAnalyzer]
13
+ @analyzers ||= [ActiveStorage::Analyzer::QiniumImageAnalyzer]
14
14
  end
15
15
 
16
16
  def initialize(options)
@@ -117,7 +117,8 @@ module ActiveStorage
117
117
  end
118
118
 
119
119
  def copy(source_bucket, source_key, target_bucket, target_key)
120
- instrument :fetch, source_bucket: source_bucket, source_key: source_key, target_bucket: target_bucket, target_key: target_key do
120
+ instrument :fetch, source_bucket: source_bucket, source_key: source_key, target_bucket: target_bucket,
121
+ target_key: target_key do
121
122
  qiniu.object.copy(source_bucket, source_key, target_bucket, target_key)
122
123
  end
123
124
  end
@@ -132,20 +133,84 @@ module ActiveStorage
132
133
 
133
134
  def url(key, **options)
134
135
  instrument :url, key: key do |payload|
135
- fop = if options[:fop].present? # 内容预处理
136
- options[:fop]
137
- elsif options[:disposition].to_s == "attachment" # 下载附件
138
- attname = URI.encode_www_form_component (options[:filename] || key).to_s
139
- "attname=#{attname}"
140
- end
136
+ # 根据七牛云文档:https://developer.qiniu.com/kodo/1659/download-setting
137
+ # 1. 使用 attname 参数可以让浏览器下载而不是打开
138
+ # 2. 使用 response-content-disposition 参数可以自定义 Content-Disposition 响应头
139
+ # 3. 使用 response-content-type 参数可以自定义 Content-Type 响应头
140
+ # 4. 使用 response-cache-control 参数可以自定义 Cache-Control 响应头
141
+ # 5. 使用 response-content-encoding 参数可以自定义 Content-Encoding 响应头
142
+ # 6. 使用 response-content-language 参数可以自定义 Content-Language 响应头
143
+ # 7. 使用 response-expires 参数可以自定义 Expires 响应头
144
+ # 8. 使用 X-Qiniu-Traffic-Limit 参数可以限制下载速度
145
+
146
+ disposition = options[:disposition]
147
+ content_type = options[:content_type]
148
+
149
+ # 构建查询参数
150
+ query_params = []
151
+
152
+ # 内容预处理(图片处理、视频处理等)
153
+ query_params << options[:fop] if options[:fop].present?
154
+
155
+ # 处理 disposition 相关参数
156
+ if disposition.to_s == "attachment" # 下载附件
157
+ # attname:触发「下载」行为;部分节点仍用对象 key 填 Content-Disposition,须同时传 response-content-disposition。
158
+ # 文档:https://developer.qiniu.com/kodo/1659/download-setting
159
+ display_name = (options[:filename].presence || File.basename(key)).to_s
160
+ query_params << "attname=#{URI.encode_www_form_component(display_name)}"
161
+ cd = ActionDispatch::Http::ContentDisposition.format(
162
+ disposition: "attachment",
163
+ filename: ActiveStorage::Filename.new(display_name).sanitized
164
+ )
165
+ query_params << "response-content-disposition=#{ERB::Util.url_encode(cd)}"
166
+ # elsif disposition.to_s == "inline" # 预览(inline)
167
+ # # 明确设置 Content-Disposition 为 inline,确保浏览器预览而不是下载
168
+ # query_params << "response-content-disposition=inline"
169
+ end
170
+
171
+ # 自定义响应头参数
172
+ # 注意:这些参数只有请求成功(即返回码为 200 OK)才会生效
173
+ # 且不支持在匿名访问的下载请求中自定义标准响应头
174
+ if options[:response_content_type].present? || content_type.present?
175
+ value = options[:response_content_type] || content_type
176
+ query_params << "response-content-type=#{URI.encode_www_form_component(value)}"
177
+ end
178
+
179
+ if options[:response_cache_control].present?
180
+ query_params << "response-cache-control=#{URI.encode_www_form_component(options[:response_cache_control])}"
181
+ end
182
+
183
+ if options[:response_content_disposition].present?
184
+ query_params << "response-content-disposition=#{ERB::Util.url_encode(options[:response_content_disposition])}"
185
+ end
186
+
187
+ if options[:response_content_encoding].present?
188
+ query_params << "response-content-encoding=#{URI.encode_www_form_component(options[:response_content_encoding])}"
189
+ end
190
+
191
+ if options[:response_content_language].present?
192
+ query_params << "response-content-language=#{URI.encode_www_form_component(options[:response_content_language])}"
193
+ end
194
+
195
+ if options[:response_expires].present?
196
+ query_params << "response-expires=#{URI.encode_www_form_component(options[:response_expires])}"
197
+ end
198
+
199
+ # 下载限速:X-Qiniu-Traffic-Limit
200
+ # 取值范围为 819200 ~ 838860800,单位为 bit/s
201
+ query_params << "X-Qiniu-Traffic-Limit=#{options[:traffic_limit].to_i}" if options[:traffic_limit].present?
141
202
 
203
+ # 构建 URL
142
204
  url = if config.public
143
205
  url_encoded_key = key.split("/").map { |x| CGI.escape(x) }.join("/")
144
- ["#{protocol}://#{domain}/#{url_encoded_key}", fop].compact.join("?")
206
+ base_url = "#{protocol}://#{domain}/#{url_encoded_key}"
207
+ query_params.any? ? "#{base_url}?#{query_params.join("&")}" : base_url
145
208
  else
146
209
  expires_in = options[:expires_in] ||
147
210
  Rails.application.config.active_storage.service_urls_expire_in ||
148
211
  3600
212
+ # 对于私有资源,需要将查询参数传递给授权 URL 生成
213
+ fop = query_params.join("&") if query_params.any?
149
214
  Qinium::Auth.authorize_download_url(domain, key,
150
215
  access_key, secret_key,
151
216
  schema: protocol, fop: fop, expires_in: expires_in)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveStorageQinium
4
- VERSION = "0.4.0"
4
+ VERSION = "0.4.2"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activestorage_qinium
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - xiaohui
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-01-17 00:00:00.000000000 Z
11
+ date: 2026-04-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: qinium
@@ -24,8 +24,50 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.4.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: activestorage
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '6.1'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '6.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: webmock
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
27
69
  description: Wraps the Qiniu Storage Service as an Active Storage service, support
28
- muti-tenant settings. https://www.qiniu.com
70
+ multi-tenant settings. https://www.qiniu.com
29
71
  email:
30
72
  - xiaohui@tanmer.com
31
73
  executables: []
@@ -54,6 +96,7 @@ metadata:
54
96
  homepage_uri: https://github.com/xiaohui-zhangxh/activestorage_qinium
55
97
  source_code_uri: https://github.com/xiaohui-zhangxh/activestorage_qinium
56
98
  changelog_uri: https://github.com/xiaohui-zhangxh/activestorage_qinium/CHANGELOG.md
99
+ bug_tracker_uri: https://github.com/xiaohui-zhangxh/activestorage_qinium/issues
57
100
  post_install_message:
58
101
  rdoc_options: []
59
102
  require_paths:
@@ -72,5 +115,5 @@ requirements: []
72
115
  rubygems_version: 3.5.16
73
116
  signing_key:
74
117
  specification_version: 4
75
- summary: A muti-tenant SDK wrap the Qiniu Storage Service as an Active Storage service
118
+ summary: A multi-tenant SDK wrap the Qiniu Storage Service as an Active Storage service
76
119
  test_files: []