lib/upyun/rest.rb in upyun-1.0.1 vs lib/upyun/rest.rb in upyun-1.0.2

- old
+ new

@@ -1,23 +1,26 @@ # encoding: utf-8 require 'restclient' -require 'uri' +require 'open-uri' module Upyun class Rest include Utils - def initialize(bucket, operator, password, endpoint=Upyun::ED_AUTO) + attr_reader :options + + def initialize(bucket, operator, password, options={timeout: 60}, endpoint=Upyun::ED_AUTO) @bucket = bucket @operator = operator @password = md5(password) + @options = options @endpoint = endpoint end def put(path, file, headers={}) raise ArgumentError, "'file' is not an instance of String" unless file.is_a?(String) - headers = headers.merge({"mkdir" => true}) unless headers.key?("mkdir") + headers = headers.merge({'mkdir' => true}) unless headers.key?('mkdir') options = if File.file?(file) {body: File.read(file), length: File.size(file), headers: headers} else {body: file, length: file.length, headers: headers} end @@ -45,26 +48,27 @@ def mkdir(path) request(:post, path, {headers: {folder: true, mkdir: true}}) end - def getlist(path="/") + def getlist(path='/') res = request(:get, path) return res if res.is_a?(Hash) - res.split("\n").map do |f| - attrs = f.split("\t") + + res.split('\n').map do |f| + attrs = f.split('\t') { name: attrs[0], - type: attrs[1] == "N" ? :file : :folder, + type: attrs[1] == 'N' ? :file : :folder, length: attrs[2].to_i, last_modified: attrs[3].to_i } end end - def usage(path="/") - res = request(:get, path, {params: "usage"}) + def usage + res = request(:get, '/', {query: 'usage'}) return res if res.is_a?(Hash) # RestClient has a bug, body.to_i returns the code instead of body, # see more on https://github.com/rest-client/rest-client/pull/103 res.dup.to_i @@ -78,34 +82,34 @@ memo.merge!({k[8..-1].to_sym => /^\d+$/.match(v) ? v.to_i : v}) end end def fullpath(path) - "/#{@bucket}#{URI.encode(URI.decode(path[0] == '/' ? path : '/' + path))}" + decoded = URI::encode(URI::decode(path.force_encoding('utf-8'))) + "/#{@bucket}#{decoded.start_with?('/') ? decoded : '/' + decoded}" end - def encode(fullpath, params) - URI.join("http://#{@endpoint}", fullpath, params.nil? ? '' : '?' + params).to_s - end - def request(method, path, options={}) fullpath = fullpath(path) - url = encode(fullpath, options[:params]) + query = options[:query] + fullpath_query = "#{fullpath}#{query.nil? ? '' : '?' + query}" headers = options[:headers] || {} date = gmdate length = options[:length] || 0 headers.merge!({ + 'User-Agent' => "Upyun-Ruby-SDK-#{VERSION}", 'Date' => date, 'Authorization' => sign(method, date, fullpath, length) }) if [:post, :patch, :put].include? method - RestClient.send(method, url, options[:body].nil? ? "" : options[:body], headers) do |res| + body = options[:body].nil? ? '' : options[:body] + rest_client[fullpath_query].send(method, body, headers) do |res| res.code == 200 ? true : {error: {code: res.code, message: res.body}} end else - RestClient.send(method, url, headers) do |res| + rest_client[fullpath_query].send(method, headers) do |res| if res.code == 200 case method when :get res.body when :head @@ -116,9 +120,13 @@ else {error: {code: res.code, message: res.body}} end end end + end + + def rest_client + @rest_clint ||= RestClient::Resource.new("http://#{@endpoint}", options) end def gmdate Time.now.utc.strftime('%a, %d %b %Y %H:%M:%S GMT') end