Module: Aliyun::OSS::Util

Extended by:
Common::Logging
Defined in:
lib/aliyun/oss/util.rb

Overview

Util functions to help generate formatted Date, signatures, etc.

Constant Summary collapse

HEADER_PREFIX =

Prefix for OSS specific HTTP headers

"x-oss-"

Constants included from Common::Logging

Common::Logging::MAX_NUM_LOG, Common::Logging::ROTATE_SIZE

Class Method Summary collapse

Methods included from Common::Logging

logger, set_log_file, set_log_level

Class Method Details

.crc(data, init_crc = 0) ⇒ Object

Get a crc value of the data



80
81
82
# File 'lib/aliyun/oss/util.rb', line 80

def crc(data, init_crc = 0)
  CrcX::crc64(init_crc, data, data.size)
end

.crc_check(crc_a, crc_b, operation) ⇒ Object



89
90
91
92
93
94
# File 'lib/aliyun/oss/util.rb', line 89

def crc_check(crc_a, crc_b, operation)
  if crc_a.nil? || crc_b.nil? || crc_a.to_i != crc_b.to_i
    logger.error("The crc of #{operation} between client and oss is not inconsistent. crc_a=#{crc_a} crc_b=#{crc_b}")
    fail CrcInconsistentError.new("The crc of #{operation} between client and oss is not inconsistent.")
  end
end

.crc_combine(crc1, crc2, len2) ⇒ Object

Calculate a value of the crc1 combine with crc2.



85
86
87
# File 'lib/aliyun/oss/util.rb', line 85

def crc_combine(crc1, crc2, len2)
  CrcX::crc64_combine(crc1, crc2, len2)
end

.ensure_bucket_name_valid(name) ⇒ Object



96
97
98
99
100
# File 'lib/aliyun/oss/util.rb', line 96

def ensure_bucket_name_valid(name)
  unless (name =~ %r|^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$|)
    fail ClientError, "The bucket name is invalid."
  end
end

.get_content_md5(content) ⇒ Object

Calculate content md5



60
61
62
# File 'lib/aliyun/oss/util.rb', line 60

def get_content_md5(content)
  Base64.strict_encode64(OpenSSL::Digest::MD5.digest(content))
end

.get_signature(key, verb, headers, resources) ⇒ Object

Calculate request signatures



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/aliyun/oss/util.rb', line 25

def get_signature(key, verb, headers, resources)
  logger.debug("Sign, headers: #{headers}, resources: #{resources}")

  content_md5 = headers['content-md5'] || ""
  content_type = headers['content-type'] || ""
  date = headers['date']

  cano_headers = headers.select { |k, v| k.start_with?(HEADER_PREFIX) }
                 .map { |k, v| [k.downcase.strip, v.strip] }
                 .sort.map { |k, v| [k, v].join(":") + "\n" }.join

  cano_res = resources[:path] || "/"
  sub_res = (resources[:sub_res] || {})
            .sort.map { |k, v| v ? [k, v].join("=") : k }.join("&")
  cano_res += "?#{sub_res}" unless sub_res.empty?

  string_to_sign =
    "#{verb}\n#{content_md5}\n#{content_type}\n#{date}\n" +
    "#{cano_headers}#{cano_res}"

  Util.sign(key, string_to_sign)
end

.sign(key, string_to_sign) ⇒ String

Sign a string using HMAC and BASE64

Parameters:

  • key (String)

    the secret key

  • string_to_sign (String)

    the string to sign

Returns:



52
53
54
55
56
57
# File 'lib/aliyun/oss/util.rb', line 52

def sign(key, string_to_sign)
  logger.debug("String to sign: #{string_to_sign}")

  Base64.strict_encode64(
    OpenSSL::HMAC.digest('sha1', key, string_to_sign))
end

.symbolize(v) ⇒ Object

Symbolize keys in Hash, recursively



65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/aliyun/oss/util.rb', line 65

def symbolize(v)
  if v.is_a?(Hash)
    result = {}
    v.each_key { |k| result[k.to_sym] = symbolize(v[k]) }
    result
  elsif v.is_a?(Array)
    result = []
    v.each { |x| result << symbolize(x) }
    result
  else
    v
  end
end