Class: QingStor::SDK::Preprocessor

Inherits:
Object
  • Object
show all
Defined in:
lib/qingstor/sdk/request/preprocessor.rb

Class Method Summary collapse

Class Method Details

.compact(object) ⇒ Object



163
164
165
166
167
168
169
# File 'lib/qingstor/sdk/request/preprocessor.rb', line 163

def self.compact(object)
  object.each do |k, v|
    object[k] = compact v if v.is_a? Hash
    object.delete k if v.nil? || v == ''
  end
  object
end

.decorate_input(input) ⇒ Object



157
158
159
160
161
# File 'lib/qingstor/sdk/request/preprocessor.rb', line 157

def self.decorate_input(input)
  input.deep_symbolize_keys!
  input[:id] = (Random.new.rand * 1_000_000).to_int
  compact input
end

.escape(origin) ⇒ Object



171
172
173
174
175
176
177
# File 'lib/qingstor/sdk/request/preprocessor.rb', line 171

def self.escape(origin)
  origin = CGI.escape origin
  origin.gsub! '%2F', '/'
  origin.gsub! '%3D', '='
  origin.gsub! '+', '%20'
  origin
end

.parse_endpoint(endpoint) ⇒ Object

try to parse endpoint: if endpoint invalid, means ip host without scheme, like: 192.168.0.1:3000 if endpoint parsed, and no scheme find, means host without scheme, like: qingstor.dev both above will add default schema at the start, and parse again



183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/qingstor/sdk/request/preprocessor.rb', line 183

def self.parse_endpoint(endpoint)
  if endpoint.blank?
    raise 'endpoint should not be empty when parse'
  end

  begin
    uri = URI.parse endpoint
    unless uri.scheme.nil?
      return uri
    end
  rescue URI::InvalidURIError
    # Ignored and continue, add scheme prefix then
  end

  endpoint = "http://#{endpoint}" # add default scheme for endpoint
  URI.parse endpoint
end

.preprocess(input) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/qingstor/sdk/request/preprocessor.rb', line 29

def self.preprocess(input)
  input                    = decorate_input input
  input[:request_endpoint] = request_endpoint input
  input[:request_uri]      = request_uri input
  input[:request_body]     = request_body input
  input[:request_headers]  = request_headers input
  input[:request_params]   = request_params input

  display = {}
  input.each { |k, v| display[k] = v unless k.to_s == 'request_body' }
  Logger.info "Preprocess QingStor request: [#{input[:id]}] #{display}"
  input
end

.request_body(input) ⇒ Object



81
82
83
84
85
86
87
88
89
90
91
# File 'lib/qingstor/sdk/request/preprocessor.rb', line 81

def self.request_body(input)
  body = input[:request_body]
  body = body.is_a?(File) ? body.read : body
  return body if body

  if input[:request_elements] && !input[:request_elements].empty?
    json_body = JSON.generate input[:request_elements]
    Logger.info "QingStor request json: [#{input[:id]}] #{json_body}"
    json_body
  end
end

.request_endpoint(input) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/qingstor/sdk/request/preprocessor.rb', line 43

def self.request_endpoint(input)
  config = input[:config]
  zone = input[:properties] ? input[:properties][:zone] : nil
  # handle endpoint directly if it exists
  if config[:endpoint].present?
    uri = parse_endpoint(config[:endpoint].to_s)
    if zone
      uri.host = "#{zone}.#{uri.host}"
    end
    return uri.to_s
  end

  if zone
    "#{config[:protocol]}://#{zone}.#{config[:host]}:#{config[:port]}"
  else
    "#{config[:protocol]}://#{config[:host]}:#{config[:port]}"
  end
end

.request_headers(input) ⇒ Object



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/qingstor/sdk/request/preprocessor.rb', line 93

def self.request_headers(input)
  unless input[:request_headers][:Date]
    input[:request_headers][:Date] = Time.now.utc.strftime '%a, %d %b %Y %H:%M:%S GMT'
  end
  if !input[:request_headers][:'Content-Length'] && input[:request_body]
    input[:request_headers][:'Content-Length'] = input[:request_body].length
  end
  if input[:request_method] == 'POST' ||
     input[:request_method] == 'PUT' ||
     input[:request_method] == 'DELETE'
    unless input[:request_headers][:'Content-Type']
      if input[:request_elements] && !input[:request_elements].empty?
        input[:request_headers][:'Content-Type'] = 'application/json'
      else
        input[:request_headers][:'Content-Type'] = MimeMagic.by_path input[:request_uri]
      end
    end
  end
  unless input[:request_headers][:'Content-Type']
    input[:request_headers][:'Content-Type'] = 'application/octet-stream'
  end
  unless input[:request_headers][:'User-Agent']
    ua = "qingstor-sdk-ruby/#{QingStor::SDK::VERSION} (Ruby v#{RUBY_VERSION}; #{RUBY_PLATFORM})"
    if input[:config][:additional_user_agent] && !input[:config][:additional_user_agent].empty?
      ua = "#{ua} #{input[:config][:additional_user_agent]}"
    end
    input[:request_headers][:'User-Agent'] = ua
  end

  if input[:api_name] == 'Delete Multiple Objects'
    input[:request_headers][:'Content-MD5'] = Base64.encode64(Digest::MD5.digest(input[:request_body])).strip
  end

  # X-QS-MetaData used to handle meta data
  unless input[:request_headers][:'X-QS-MetaData'].nil?
    if input[:request_headers][:'X-QS-MetaData'].is_a?(Hash) && !input[:request_headers][:'X-QS-MetaData'].empty?
      prefix = 'x-qs-meta-'
      input[:request_headers][:'X-QS-MetaData'].each do |k, v|
        k = k.to_s
        # add prefix for meta data in header
        k = prefix + k
        input[:request_headers][:"#{k}"] = v
      end
    end
    # remove X-QS-MetaData from request header
    input[:request_headers].delete :'X-QS-MetaData'
  end

  input[:request_headers].map do |k, v|
    input[:request_headers][k] = escape v.to_s unless v.to_s.ascii_only?
  end

  input[:request_headers]
end

.request_params(input) ⇒ Object



148
149
150
151
152
153
154
155
# File 'lib/qingstor/sdk/request/preprocessor.rb', line 148

def self.request_params(input)
  unless input[:request_params].nil?
    input[:request_params].map do |k, v|
      input[:request_params][k] = escape v.to_s
    end
  end
  input[:request_params]
end

.request_uri(input) ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/qingstor/sdk/request/preprocessor.rb', line 62

def self.request_uri(input)
  config = input[:config]
  # if enable vhost, and uri property contains bucket-name
  if config[:enable_virtual_host_style] && input[:properties].present? && input[:properties][:"bucket-name"]
    uri = parse_endpoint input[:request_endpoint]
    # modify host, add bucket before
    uri.host = "#{input[:properties][:"bucket-name"]}.#{uri.host}"
    input[:request_endpoint] = uri.to_s
    # handle request_uri, remove prefix (bucket-name)
    input[:request_uri].delete_prefix! URI_BUCKET_PREFIX if input[:request_uri].start_with? URI_BUCKET_PREFIX
  end
  unless input[:properties].nil?
    input[:properties].each do |k, v|
      input[:request_uri].gsub! "<#{k}>", (escape v.to_s)
    end
  end
  input[:request_uri]
end