class ActiveStorage::Service::QiniuService
Wraps the Qiniu Storage Service
as an Active Storage service. See ActiveStorage::Service
for the generic API documentation that applies to all services.
you can set-up qiniu storage service through the generated <tt>config/storage.yml</tt> file. For example: qiniu: service: Qiniu access_key: <%= ENV['QINIU_ACCESS_KEY'] %> secret_key: <%= ENV['QINIU_SECRET_KEY'] %> bucket: <%= ENV['QINIU_BUCKET'] %> domain: <%= ENV['QINIU_DOMAIN'] %> protocol: <%= ENV.fetch("QINIU_PROTOCOL") { "http" } %> more options. https://github.com/qiniu/ruby-sdk/blob/master/lib/qiniu/auth.rb#L49
Then, in your application's configuration, you can specify the service to use like this:
config.active_storage.service = :qiniu
Constants
- BLOCK_SIZE
Attributes
bucket[R]
bucket_private[R]
domain[R]
protocol[R]
upload_options[R]
Public Class Methods
new(access_key:, secret_key:, bucket:, domain:, **options)
click to toggle source
# File lib/active_storage/service/qiniu_service.rb, line 31 def initialize(access_key:, secret_key:, bucket:, domain:, **options) @bucket = bucket @domain = domain @protocol = (options.delete(:protocol) || 'https').to_sym bucket_private = options.delete(:bucket_private) @bucket_private = bucket_private.nil? ? false : !!bucket_private Qiniu.establish_connection! access_key: access_key, secret_key: secret_key, protocol: @protocol, **options @upload_options = options end
Public Instance Methods
delete(key)
click to toggle source
# File lib/active_storage/service/qiniu_service.rb, line 71 def delete(key) instrument :delete, key: key do Qiniu.delete(bucket, key) end end
delete_prefixed(prefix)
click to toggle source
# File lib/active_storage/service/qiniu_service.rb, line 77 def delete_prefixed(prefix) instrument :delete_prefixed, prefix: prefix do items_for(prefix).each { |item| delete item['key'] } end end
download(key) { |data| ... }
click to toggle source
# File lib/active_storage/service/qiniu_service.rb, line 91 def download(key) if block_given? instrument :streaming_download, key: key do open(url(key, disposition: :attachment)) do |file| while data = file.read(64.kilobytes) yield data end end end else instrument :download, key: key do open(url(key, disposition: :attachment)).read end end end
download_chunk(key, range)
click to toggle source
# File lib/active_storage/service/qiniu_service.rb, line 107 def download_chunk(key, range) instrument :download_chunk, key: key, range: range do uri = URI(url(key, disposition: :attachment)) Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https") do |client| client.get(uri, 'Range' => "bytes=#{range.begin}-#{range.exclude_end? ? range.end - 1 : range.end}").body end end end
exist?(key)
click to toggle source
# File lib/active_storage/service/qiniu_service.rb, line 83 def exist?(key) instrument :exist, key: key do |payload| answer = items_for(key).any? payload[:exist] = answer answer end end
headers_for_direct_upload(key, content_type:, checksum:, **)
click to toggle source
# File lib/active_storage/service/qiniu_service.rb, line 146 def headers_for_direct_upload(key, content_type:, checksum:, **) { "Content-Type" => content_type, "Content-MD5" => checksum, "x-token" => generate_uptoken(key) } end
upload(key, io, checksum: nil, content_type: nil, **)
click to toggle source
# File lib/active_storage/service/qiniu_service.rb, line 45 def upload(key, io, checksum: nil, content_type: nil, **) instrument :upload, key: key, checksum: checksum do io = File.open(io) unless io.respond_to?(:read) ctx_list = [] file_size = 0 while (blk = io.read(BLOCK_SIZE)) ctx = upload_blk(key, blk) file_size += blk.size ctx_list.push(ctx) end api_call( key, '/' + [ 'mkfile', file_size, 'key', encode(key), *(content_type ? ['mimeType', encode(content_type)] : []) ].join('/'), ctx_list.join(',') ) end end
url(key, **options)
click to toggle source
# File lib/active_storage/service/qiniu_service.rb, line 116 def url(key, **options) instrument :url, key: key do |payload| fop = if options[:fop].present? # 内容预处理 options[:fop] elsif options[:disposition].to_s == 'attachment' # 下载附件 attname = URI.escape "#{options[:filename] || key}" "attname=#{attname}" end url = if bucket_private expires_in = options[:expires_in] || url_expires_in Qiniu::Auth.authorize_download_url_2(domain, key, schema: protocol, fop: fop, expires_in: expires_in) else url_encoded_key = CGI::escape(key) "#{protocol}://#{domain}/#{url_encoded_key}?#{fop}" end payload[:url] = url url end end
url_for_direct_upload(key, expires_in:, content_type:, content_length:, checksum:)
click to toggle source
# File lib/active_storage/service/qiniu_service.rb, line 138 def url_for_direct_upload(key, expires_in:, content_type:, content_length:, checksum:) instrument :url, key: key do |payload| url = Qiniu::Config.up_host(bucket) payload[:url] = url url end end
Private Instance Methods
api_call(key, path, body)
click to toggle source
# File lib/active_storage/service/qiniu_service.rb, line 181 def api_call(key, path, body) url = Qiniu::Config.up_host(bucket) + path response = RestClient.post( url, body, 'Authorization' => "UpToken #{generate_uptoken(key)}" ) result = JSON.parse(response.body) result end
encode(value)
click to toggle source
# File lib/active_storage/service/qiniu_service.rb, line 195 def encode(value) Base64.encode64(value).strip.gsub(/\+/, '-').gsub(%r{/}, '_') end
generate_uptoken(key=nil, expires_in=nil)
click to toggle source
# File lib/active_storage/service/qiniu_service.rb, line 163 def generate_uptoken(key=nil, expires_in=nil) expires_in ||= 3600 put_policy = Qiniu::Auth::PutPolicy.new(bucket, key, expires_in) upload_options.slice(*Qiniu::Auth::PutPolicy::PARAMS.keys).each do |k, v| put_policy.send("#{k}=", v) end Qiniu::Auth.generate_uptoken(put_policy) end
items_for(prefix='')
click to toggle source
# File lib/active_storage/service/qiniu_service.rb, line 152 def items_for(prefix='') list_policy = Qiniu::Storage::ListPolicy.new( bucket, # 存储空间 1000, # 列举的条目数 prefix, # 指定前缀 '' # 指定目录分隔符 ) code, result, response_headers, s, d = Qiniu::Storage.list(list_policy) result['items'] end
upload_blk(key, blk)
click to toggle source
# File lib/active_storage/service/qiniu_service.rb, line 173 def upload_blk(key, blk) result = with_retries(max_retries: 3) do api_call(key, "/mkblk/#{blk.size}", blk) end result.fetch('ctx') end