fog-aliyun 0.3.13 → 0.3.19
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 +4 -4
- data/CHANGELOG.md +109 -0
- data/Gemfile +0 -1
- data/fog-aliyun.gemspec +2 -0
- data/lib/fog/aliyun/models/storage/directories.rb +30 -53
- data/lib/fog/aliyun/models/storage/directory.rb +96 -17
- data/lib/fog/aliyun/models/storage/file.rb +127 -125
- data/lib/fog/aliyun/models/storage/files.rb +62 -156
- data/lib/fog/aliyun/requests/storage/abort_multipart_upload.rb +22 -0
- data/lib/fog/aliyun/requests/storage/complete_multipart_upload.rb +21 -0
- data/lib/fog/aliyun/requests/storage/copy_object.rb +14 -19
- data/lib/fog/aliyun/requests/storage/delete_bucket.rb +3 -10
- data/lib/fog/aliyun/requests/storage/delete_multiple_objects.rb +20 -0
- data/lib/fog/aliyun/requests/storage/delete_object.rb +10 -11
- data/lib/fog/aliyun/requests/storage/get_bucket.rb +26 -125
- data/lib/fog/aliyun/requests/storage/get_bucket_location.rb +33 -0
- data/lib/fog/aliyun/requests/storage/get_object.rb +29 -11
- data/lib/fog/aliyun/requests/storage/get_object_acl.rb +30 -0
- data/lib/fog/aliyun/requests/storage/get_object_http_url.rb +8 -11
- data/lib/fog/aliyun/requests/storage/get_object_https_url.rb +8 -11
- data/lib/fog/aliyun/requests/storage/get_service.rb +13 -0
- data/lib/fog/aliyun/requests/storage/head_object.rb +25 -14
- data/lib/fog/aliyun/requests/storage/initiate_multipart_upload.rb +19 -0
- data/lib/fog/aliyun/requests/storage/list_buckets.rb +6 -24
- data/lib/fog/aliyun/requests/storage/list_objects.rb +10 -67
- data/lib/fog/aliyun/requests/storage/put_bucket.rb +2 -8
- data/lib/fog/aliyun/requests/storage/put_object.rb +16 -142
- data/lib/fog/aliyun/requests/storage/upload_part.rb +24 -0
- data/lib/fog/aliyun/storage.rb +41 -27
- data/lib/fog/aliyun/version.rb +1 -1
- metadata +39 -6
- data/lib/fog/aliyun/requests/storage/delete_container.rb +0 -31
- data/lib/fog/aliyun/requests/storage/get_container.rb +0 -56
- data/lib/fog/aliyun/requests/storage/get_containers.rb +0 -65
- data/lib/fog/aliyun/requests/storage/put_container.rb +0 -30
| @@ -0,0 +1,33 @@ | |
| 1 | 
            +
            require 'nokogiri'
         | 
| 2 | 
            +
            module Fog
         | 
| 3 | 
            +
              module Aliyun
         | 
| 4 | 
            +
                class Storage
         | 
| 5 | 
            +
                  class Real
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                    # Get location constraint for an OSS bucket
         | 
| 8 | 
            +
                    #
         | 
| 9 | 
            +
                    # @param bucket_name [String] name of bucket to get location constraint for
         | 
| 10 | 
            +
                    #
         | 
| 11 | 
            +
                    # @see https://help.aliyun.com/document_detail/31967.html
         | 
| 12 | 
            +
                    #
         | 
| 13 | 
            +
                    # note: The OSS Ruby sdk does not support get_bucket_location and there needs to parse response
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                    def get_bucket_location(bucket_name)
         | 
| 16 | 
            +
                      data = @oss_http.get({:bucket => bucket_name, :sub_res => { 'location' => nil} }, {})
         | 
| 17 | 
            +
                      doc = parse_xml(data.body)
         | 
| 18 | 
            +
                      doc.at_css("LocationConstraint").text
         | 
| 19 | 
            +
                    end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                    private
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                    def parse_xml(content)
         | 
| 24 | 
            +
                      doc = Nokogiri::XML(content) do |config|
         | 
| 25 | 
            +
                        config.options |= Nokogiri::XML::ParseOptions::NOBLANKS
         | 
| 26 | 
            +
                      end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                      doc
         | 
| 29 | 
            +
                    end
         | 
| 30 | 
            +
                  end
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
            end
         | 
| @@ -7,21 +7,39 @@ module Fog | |
| 7 7 | 
             
                    # Get details for object
         | 
| 8 8 | 
             
                    #
         | 
| 9 9 | 
             
                    # ==== Parameters
         | 
| 10 | 
            -
                    # *  | 
| 10 | 
            +
                    # * object_name<~String> - Name of object to look for
         | 
| 11 11 | 
             
                    #
         | 
| 12 | 
            -
                    def get_object( | 
| 12 | 
            +
                    def get_object(bucket_name, object_name, options = {}, &block)
         | 
| 13 13 | 
             
                      options = options.reject { |_key, value| value.nil? }
         | 
| 14 | 
            -
                      bucket_name | 
| 15 | 
            -
             | 
| 14 | 
            +
                      unless bucket_name
         | 
| 15 | 
            +
                        raise ArgumentError.new('bucket_name is required')
         | 
| 16 | 
            +
                      end
         | 
| 17 | 
            +
                      unless object_name
         | 
| 18 | 
            +
                        raise ArgumentError.new('object_name is required')
         | 
| 19 | 
            +
                      end
         | 
| 16 20 | 
             
                      # Using OSS ruby SDK to fix performance issue
         | 
| 17 | 
            -
                       | 
| 18 | 
            -
                       | 
| 19 | 
            -
             | 
| 20 | 
            -
             | 
| 21 | 
            +
                      http_options = { :headers => {} }
         | 
| 22 | 
            +
                      http_options[:query] = options.delete('query') || {}
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                      http_options[:headers].merge!(options)
         | 
| 25 | 
            +
                      if options['If-Modified-Since']
         | 
| 26 | 
            +
                        http_options[:headers]['If-Modified-Since'] = Fog::Time.at(options['If-Modified-Since'].to_i).to_date_header
         | 
| 21 27 | 
             
                      end
         | 
| 22 | 
            -
                       | 
| 23 | 
            -
             | 
| 24 | 
            -
                       | 
| 28 | 
            +
                      if options['If-Unmodified-Since']
         | 
| 29 | 
            +
                        http_options[:headers]['If-Unmodified-Since'] = Fog::Time.at(options['If-Unmodified-Since'].to_i).to_date_header
         | 
| 30 | 
            +
                      end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                      if block_given?
         | 
| 33 | 
            +
                        http_options[:response_block] = Proc.new
         | 
| 34 | 
            +
                      end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                      resources = {
         | 
| 37 | 
            +
                          :bucket => bucket_name,
         | 
| 38 | 
            +
                          :object => object_name
         | 
| 39 | 
            +
                      }
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                      @oss_http.get(resources, http_options, &block)
         | 
| 42 | 
            +
             | 
| 25 43 | 
             
                    end
         | 
| 26 44 | 
             
                  end
         | 
| 27 45 | 
             
                end
         | 
| @@ -0,0 +1,30 @@ | |
| 1 | 
            +
            module Fog
         | 
| 2 | 
            +
              module Aliyun
         | 
| 3 | 
            +
                class Storage
         | 
| 4 | 
            +
                  class Real
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                    # Get access control list for an S3 object
         | 
| 7 | 
            +
                    #
         | 
| 8 | 
            +
                    # @param bucket_name [String] name of bucket containing object
         | 
| 9 | 
            +
                    # @param object_name [String] name of object to get access control list for
         | 
| 10 | 
            +
                    # @param options [Hash]
         | 
| 11 | 
            +
                    # @option options versionId [String] specify a particular version to retrieve
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                    def get_object_acl(bucket_name, object_name, options = {})
         | 
| 14 | 
            +
                      unless bucket_name
         | 
| 15 | 
            +
                        raise ArgumentError.new('bucket_name is required')
         | 
| 16 | 
            +
                      end
         | 
| 17 | 
            +
                      unless object_name
         | 
| 18 | 
            +
                        raise ArgumentError.new('object_name is required')
         | 
| 19 | 
            +
                      end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                      # At present, sdk does not support versionId
         | 
| 22 | 
            +
                      # if version_id = options.delete('versionId')
         | 
| 23 | 
            +
                      #   query['versionId'] = version_id
         | 
| 24 | 
            +
                      # end
         | 
| 25 | 
            +
                      @oss_protocol.get_object_acl(bucket_name, object_name)
         | 
| 26 | 
            +
                    end
         | 
| 27 | 
            +
                  end
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
            end
         | 
| @@ -7,29 +7,26 @@ module Fog | |
| 7 7 | 
             
                    # Get an expiring object http url
         | 
| 8 8 | 
             
                    #
         | 
| 9 9 | 
             
                    # ==== Parameters
         | 
| 10 | 
            -
                    # *  | 
| 11 | 
            -
                    # *  | 
| 10 | 
            +
                    # * bucket_name<~String> - Name of bucket
         | 
| 11 | 
            +
                    # * object_name<~String> - Name of object to get expiring url for
         | 
| 12 12 | 
             
                    # * expires<~Integer> - An expiry time for this url
         | 
| 13 13 | 
             
                    #
         | 
| 14 14 | 
             
                    # ==== Returns
         | 
| 15 15 | 
             
                    # * response<~Excon::Response>:
         | 
| 16 16 | 
             
                    #   * body<~String> - url for object
         | 
| 17 | 
            -
                    def get_object_http_url_public( | 
| 18 | 
            -
                       | 
| 19 | 
            -
                       | 
| 20 | 
            -
                      bucket ||= @aliyun_oss_bucket
         | 
| 21 | 
            -
                      acl = get_bucket_acl(bucket)
         | 
| 22 | 
            -
                      location = get_bucket_location(bucket)
         | 
| 17 | 
            +
                    def get_object_http_url_public(bucket_name, object_name, expires)
         | 
| 18 | 
            +
                      bucket = @oss_client.get_bucket(bucket_name)
         | 
| 19 | 
            +
                      acl = bucket.acl()
         | 
| 23 20 |  | 
| 24 21 | 
             
                      if acl == 'private'
         | 
| 25 22 | 
             
                        expires_time = (Time.now.to_i + (expires.nil? ? 0 : expires.to_i)).to_s
         | 
| 26 | 
            -
                        resource =  | 
| 23 | 
            +
                        resource = bucket_name + '/' + object_name
         | 
| 27 24 | 
             
                        signature = sign('GET', expires_time, nil, resource)
         | 
| 28 | 
            -
                        'http://' +  | 
| 25 | 
            +
                        'http://' + bucket_name + '.' + @host + '/' + object_name +
         | 
| 29 26 | 
             
                          '?OSSAccessKeyId=' + @aliyun_accesskey_id + '&Expires=' + expires_time +
         | 
| 30 27 | 
             
                          '&Signature=' + URI.encode(signature, '/[^!*\'()\;?:@#&%=+$,{}[]<>`" ')
         | 
| 31 28 | 
             
                      elsif acl == 'public-read' || acl == 'public-read-write'
         | 
| 32 | 
            -
                        'http://' +  | 
| 29 | 
            +
                        'http://' + bucket_name + '.' + @host + '/' + object_name
         | 
| 33 30 | 
             
                      else
         | 
| 34 31 | 
             
                        'acl is wrong with value:' + acl
         | 
| 35 32 | 
             
                      end
         | 
| @@ -7,29 +7,26 @@ module Fog | |
| 7 7 | 
             
                    # Get an expiring object https url from Cloud Files
         | 
| 8 8 | 
             
                    #
         | 
| 9 9 | 
             
                    # ==== Parameters
         | 
| 10 | 
            -
                    # *  | 
| 11 | 
            -
                    # *  | 
| 10 | 
            +
                    # * bucket_name<~String> - Name of bucket
         | 
| 11 | 
            +
                    # * object_name<~String> - Name of object to get expiring url for
         | 
| 12 12 | 
             
                    # * expires<~Integer> - An expiry time for this url
         | 
| 13 13 | 
             
                    #
         | 
| 14 14 | 
             
                    # ==== Returns
         | 
| 15 15 | 
             
                    # * response<~Excon::Response>:
         | 
| 16 16 | 
             
                    #   * body<~String> - url for object
         | 
| 17 | 
            -
                    def get_object_https_url_public( | 
| 18 | 
            -
                       | 
| 19 | 
            -
                       | 
| 20 | 
            -
                      bucket ||= @aliyun_oss_bucket
         | 
| 21 | 
            -
                      acl = get_bucket_acl(bucket)
         | 
| 22 | 
            -
                      location = get_bucket_location(bucket)
         | 
| 17 | 
            +
                    def get_object_https_url_public(bucket_name, object_name, expires)
         | 
| 18 | 
            +
                      bucket = @oss_client.get_bucket(bucket_name)
         | 
| 19 | 
            +
                      acl = bucket.acl()
         | 
| 23 20 |  | 
| 24 21 | 
             
                      if acl == 'private'
         | 
| 25 22 | 
             
                        expires_time = (Time.now.to_i + (expires.nil? ? 0 : expires.to_i)).to_s
         | 
| 26 | 
            -
                        resource =  | 
| 23 | 
            +
                        resource = bucket_name + '/' + object_name
         | 
| 27 24 | 
             
                        signature = sign('GET', expires_time, nil, resource)
         | 
| 28 | 
            -
                        'https://' +  | 
| 25 | 
            +
                        'https://' + bucket_name + '.' + @host + '/' + object_name +
         | 
| 29 26 | 
             
                          '?OSSAccessKeyId=' + @aliyun_accesskey_id + '&Expires=' + expires_time +
         | 
| 30 27 | 
             
                          '&Signature=' + URI.encode(signature, '/[^!*\'()\;?:@#&%=+$,{}[]<>`" ')
         | 
| 31 28 | 
             
                      elsif acl == 'public-read' || acl == 'public-read-write'
         | 
| 32 | 
            -
                        'https://' +  | 
| 29 | 
            +
                        'https://' + bucket_name + '.' + @host + '/' + object_name
         | 
| 33 30 | 
             
                      else
         | 
| 34 31 | 
             
                        'acl is wrong with value:' + acl
         | 
| 35 32 | 
             
                      end
         | 
| @@ -7,21 +7,32 @@ module Fog | |
| 7 7 | 
             
                    # Get headers for object
         | 
| 8 8 | 
             
                    #
         | 
| 9 9 | 
             
                    # ==== Parameters
         | 
| 10 | 
            -
                    # *  | 
| 10 | 
            +
                    # * object_name<~String> - Name of object to look for
         | 
| 11 11 | 
             
                    #
         | 
| 12 | 
            -
                    def head_object( | 
| 13 | 
            -
                       | 
| 14 | 
            -
             | 
| 15 | 
            -
                       | 
| 16 | 
            -
                       | 
| 17 | 
            -
                         | 
| 18 | 
            -
             | 
| 19 | 
            -
             | 
| 20 | 
            -
             | 
| 21 | 
            -
             | 
| 22 | 
            -
             | 
| 23 | 
            -
                       | 
| 24 | 
            -
                       | 
| 12 | 
            +
                    def head_object(bucket_name, object_name, options={})
         | 
| 13 | 
            +
                      unless bucket_name
         | 
| 14 | 
            +
                        raise ArgumentError.new('bucket_name is required')
         | 
| 15 | 
            +
                      end
         | 
| 16 | 
            +
                      unless object_name
         | 
| 17 | 
            +
                        raise ArgumentError.new('object_name is required')
         | 
| 18 | 
            +
                      end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                      # Currently, the ruby sdk does not support versionId
         | 
| 21 | 
            +
                      # if version_id = options.delete('versionId')
         | 
| 22 | 
            +
                      #   query = {'versionId' => version_id}
         | 
| 23 | 
            +
                      # end
         | 
| 24 | 
            +
                      headers = {}
         | 
| 25 | 
            +
                      headers['If-Modified-Since'] = Fog::Time.at(options['If-Modified-Since'].to_i).to_date_header if options['If-Modified-Since']
         | 
| 26 | 
            +
                      headers['If-Unmodified-Since'] = Fog::Time.at(options['If-Unmodified-Since'].to_i).to_date_header if options['If-Modified-Since']
         | 
| 27 | 
            +
                      headers.merge!(options)
         | 
| 28 | 
            +
                      resources = {
         | 
| 29 | 
            +
                          :bucket => bucket_name,
         | 
| 30 | 
            +
                          :object => object_name
         | 
| 31 | 
            +
                      }
         | 
| 32 | 
            +
                      http_options = {
         | 
| 33 | 
            +
                          :headers => headers
         | 
| 34 | 
            +
                      }
         | 
| 35 | 
            +
                      @oss_http.head(resources, http_options)
         | 
| 25 36 | 
             
                    end
         | 
| 26 37 | 
             
                  end
         | 
| 27 38 | 
             
                end
         | 
| @@ -0,0 +1,19 @@ | |
| 1 | 
            +
            module Fog
         | 
| 2 | 
            +
              module Aliyun
         | 
| 3 | 
            +
                class Storage
         | 
| 4 | 
            +
                  class Real
         | 
| 5 | 
            +
                    # Initiate a multipart upload
         | 
| 6 | 
            +
                    #
         | 
| 7 | 
            +
                    # @param bucket_name [String] Name of bucket to create
         | 
| 8 | 
            +
                    # @param object_name [String] Name of object to create
         | 
| 9 | 
            +
                    # @param options [Hash]
         | 
| 10 | 
            +
                    #
         | 
| 11 | 
            +
                    # @see https://help.aliyun.com/document_detail/31992.html
         | 
| 12 | 
            +
                    #
         | 
| 13 | 
            +
                    def initiate_multipart_upload(bucket_name, object_name, options = {})
         | 
| 14 | 
            +
                      @oss_protocol.initiate_multipart_upload(bucket_name, object_name, options)
         | 
| 15 | 
            +
                    end
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
            end
         | 
| @@ -5,31 +5,13 @@ module Fog | |
| 5 5 | 
             
                class Storage
         | 
| 6 6 | 
             
                  class Real
         | 
| 7 7 | 
             
                    def list_buckets(options = {})
         | 
| 8 | 
            -
                       | 
| 9 | 
            -
                       | 
| 10 | 
            -
                      maxKeys =  | 
| 8 | 
            +
                      maxKeys = options[:max_keys] || 1000
         | 
| 9 | 
            +
                      maxKeys = maxKeys.to_i
         | 
| 10 | 
            +
                      maxKeys = [maxKeys, 1000].min
         | 
| 11 11 |  | 
| 12 | 
            -
                       | 
| 13 | 
            -
                       | 
| 14 | 
            -
             | 
| 15 | 
            -
                        path += '&marker=' + marker if marker
         | 
| 16 | 
            -
                        path += '&max-keys=' + maxKeys if maxKeys
         | 
| 17 | 
            -
             | 
| 18 | 
            -
                      elsif marker
         | 
| 19 | 
            -
                        path += '?marker=' + marker
         | 
| 20 | 
            -
                        path += '&max-keys=' + maxKeys if maxKeys
         | 
| 21 | 
            -
             | 
| 22 | 
            -
                      elsif maxKeys
         | 
| 23 | 
            -
                        path += '?max-keys=' + maxKeys
         | 
| 24 | 
            -
                      end
         | 
| 25 | 
            -
             | 
| 26 | 
            -
                      ret = request(
         | 
| 27 | 
            -
                        expects: [200, 203],
         | 
| 28 | 
            -
                        method: 'GET',
         | 
| 29 | 
            -
                        path: path
         | 
| 30 | 
            -
                      )
         | 
| 31 | 
            -
                      xml = ret.data[:body]
         | 
| 32 | 
            -
                      XmlSimple.xml_in(xml)['Buckets'][0]
         | 
| 12 | 
            +
                      options[:limit] = maxKeys
         | 
| 13 | 
            +
                      options.delete(:max_keys)
         | 
| 14 | 
            +
                      @oss_protocol.list_buckets(options)
         | 
| 33 15 | 
             
                    end
         | 
| 34 16 | 
             
                  end
         | 
| 35 17 | 
             
                end
         | 
| @@ -4,79 +4,22 @@ module Fog | |
| 4 4 | 
             
              module Aliyun
         | 
| 5 5 | 
             
                class Storage
         | 
| 6 6 | 
             
                  class Real
         | 
| 7 | 
            -
                    def list_objects(options = {})
         | 
| 8 | 
            -
                       | 
| 9 | 
            -
                       | 
| 10 | 
            -
                      prefix = options['prefix']
         | 
| 11 | 
            -
                      marker = options['marker']
         | 
| 12 | 
            -
                      # Set the ListObjects max limitation to 1000
         | 
| 13 | 
            -
                      maxKeys = options['max-keys'] || 1000
         | 
| 7 | 
            +
                    def list_objects(bucket_name, options = {})
         | 
| 8 | 
            +
                      maxKeys = options[:max_keys] || 1000
         | 
| 9 | 
            +
                      maxKeys = maxKeys.to_i
         | 
| 14 10 | 
             
                      maxKeys = [maxKeys, 1000].min
         | 
| 15 | 
            -
                      delimiter = options['delimiter']
         | 
| 16 11 |  | 
| 17 | 
            -
                       | 
| 18 | 
            -
                       | 
| 19 | 
            -
             | 
| 20 | 
            -
                        path += '&marker=' + marker if marker
         | 
| 21 | 
            -
                        path += '&max-keys=' + maxKeys.to_s if maxKeys
         | 
| 22 | 
            -
                        path += '&delimiter=' + delimiter if delimiter
         | 
| 23 | 
            -
             | 
| 24 | 
            -
                      elsif marker
         | 
| 25 | 
            -
                        path += '/?marker=' + marker
         | 
| 26 | 
            -
                        path += '&max-keys=' + maxKeys.to_s if maxKeys
         | 
| 27 | 
            -
                        path += '&delimiter=' + delimiter if delimiter
         | 
| 28 | 
            -
             | 
| 29 | 
            -
                      elsif maxKeys
         | 
| 30 | 
            -
                        path += '/?max-keys=' + maxKeys.to_s
         | 
| 31 | 
            -
                        path += '&delimiter=' + delimiter if delimiter
         | 
| 32 | 
            -
                      elsif delimiter
         | 
| 33 | 
            -
                        path += '/?delimiter=' + delimiter
         | 
| 34 | 
            -
                      end
         | 
| 35 | 
            -
             | 
| 36 | 
            -
                      resource = bucket + '/'
         | 
| 37 | 
            -
                      ret = request(
         | 
| 38 | 
            -
                        expects: [200, 203, 400],
         | 
| 39 | 
            -
                        method: 'GET',
         | 
| 40 | 
            -
                        path: path,
         | 
| 41 | 
            -
                        resource: resource,
         | 
| 42 | 
            -
                        bucket: bucket
         | 
| 43 | 
            -
                      )
         | 
| 44 | 
            -
                      xml = ret.data[:body]
         | 
| 45 | 
            -
                      XmlSimple.xml_in(xml)
         | 
| 12 | 
            +
                      options[:limit] = maxKeys
         | 
| 13 | 
            +
                      options.delete(:max_keys)
         | 
| 14 | 
            +
                      @oss_protocol.list_objects(bucket_name, options)
         | 
| 46 15 | 
             
                    end
         | 
| 47 16 |  | 
| 48 | 
            -
                    def list_multipart_uploads( | 
| 49 | 
            -
                       | 
| 50 | 
            -
             | 
| 51 | 
            -
                      path = '?uploads'
         | 
| 52 | 
            -
                      resource = bucket + '/' + path
         | 
| 53 | 
            -
             | 
| 54 | 
            -
                      ret = request(
         | 
| 55 | 
            -
                        expects: 200,
         | 
| 56 | 
            -
                        method: 'GET',
         | 
| 57 | 
            -
                        path: path,
         | 
| 58 | 
            -
                        bucket: bucket,
         | 
| 59 | 
            -
                        resource: resource,
         | 
| 60 | 
            -
                        location: location
         | 
| 61 | 
            -
                      )
         | 
| 62 | 
            -
                      XmlSimple.xml_in(ret.data[:body])['Upload']
         | 
| 17 | 
            +
                    def list_multipart_uploads(bucket_name, _options = {})
         | 
| 18 | 
            +
                      @oss_protocol.list_multipart_uploads(bucket_name, _options)
         | 
| 63 19 | 
             
                    end
         | 
| 64 20 |  | 
| 65 | 
            -
                    def list_parts( | 
| 66 | 
            -
                       | 
| 67 | 
            -
             | 
| 68 | 
            -
                      path = object + '?uploadId=' + uploadid
         | 
| 69 | 
            -
                      resource = bucket + '/' + path
         | 
| 70 | 
            -
             | 
| 71 | 
            -
                      ret = request(
         | 
| 72 | 
            -
                        expects: 200,
         | 
| 73 | 
            -
                        method: 'GET',
         | 
| 74 | 
            -
                        path: path,
         | 
| 75 | 
            -
                        bucket: bucket,
         | 
| 76 | 
            -
                        resource: resource,
         | 
| 77 | 
            -
                        location: location
         | 
| 78 | 
            -
                      )
         | 
| 79 | 
            -
                      XmlSimple.xml_in(ret.data[:body])['Part']
         | 
| 21 | 
            +
                    def list_parts(bucket_name, object_name, upload_id, _options = {})
         | 
| 22 | 
            +
                      @oss_protocol.list_parts(bucket_name, object_name, upload_id, _options)
         | 
| 80 23 | 
             
                    end
         | 
| 81 24 | 
             
                  end
         | 
| 82 25 | 
             
                end
         | 
| @@ -4,14 +4,8 @@ module Fog | |
| 4 4 | 
             
              module Aliyun
         | 
| 5 5 | 
             
                class Storage
         | 
| 6 6 | 
             
                  class Real
         | 
| 7 | 
            -
                    def put_bucket( | 
| 8 | 
            -
                       | 
| 9 | 
            -
                      request(
         | 
| 10 | 
            -
                        expects: [200, 203],
         | 
| 11 | 
            -
                        method: 'PUT',
         | 
| 12 | 
            -
                        resource: resource,
         | 
| 13 | 
            -
                        bucket: bucketName
         | 
| 14 | 
            -
                      )
         | 
| 7 | 
            +
                    def put_bucket(bucket_name, options = {})
         | 
| 8 | 
            +
                      @oss_protocol.create_bucket(bucket_name, options)
         | 
| 15 9 | 
             
                    end
         | 
| 16 10 | 
             
                  end
         | 
| 17 11 | 
             
                end
         | 
| @@ -7,153 +7,27 @@ module Fog | |
| 7 7 | 
             
                    # Put details for object
         | 
| 8 8 | 
             
                    #
         | 
| 9 9 | 
             
                    # ==== Parameters
         | 
| 10 | 
            -
                    # *  | 
| 10 | 
            +
                    # * bucket_name<~String> - Name of bucket to look for
         | 
| 11 | 
            +
                    # * object_name<~String> - Object of object to look for
         | 
| 12 | 
            +
                    # * data<~File>
         | 
| 13 | 
            +
                    # * options<~Hash>
         | 
| 11 14 | 
             
                    #
         | 
| 12 | 
            -
                    def put_object( | 
| 13 | 
            -
                       | 
| 14 | 
            -
             | 
| 15 | 
            -
             | 
| 16 | 
            -
             | 
| 17 | 
            -
                      # put multiparts if object's size is over 100m
         | 
| 18 | 
            -
                      return put_multipart_object(bucket, object, file) if file.size > 104_857_600
         | 
| 19 | 
            -
             | 
| 20 | 
            -
                      body = file.read
         | 
| 21 | 
            -
             | 
| 22 | 
            -
                      resource = bucket + '/' + object
         | 
| 23 | 
            -
                      request(
         | 
| 24 | 
            -
                        expects: [200, 203],
         | 
| 25 | 
            -
                        method: 'PUT',
         | 
| 26 | 
            -
                        path: object,
         | 
| 27 | 
            -
                        bucket: bucket,
         | 
| 28 | 
            -
                        resource: resource,
         | 
| 29 | 
            -
                        body: body,
         | 
| 30 | 
            -
                        location: get_bucket_location(bucket)
         | 
| 31 | 
            -
                      )
         | 
| 32 | 
            -
                    end
         | 
| 33 | 
            -
             | 
| 34 | 
            -
                    def put_object_with_body(object, body, options = {})
         | 
| 35 | 
            -
                      bucket = options[:bucket]
         | 
| 36 | 
            -
                      bucket ||= @aliyun_oss_bucket
         | 
| 37 | 
            -
             | 
| 38 | 
            -
                      resource = bucket + '/' + object
         | 
| 39 | 
            -
                      request(
         | 
| 40 | 
            -
                        expects: [200, 203],
         | 
| 41 | 
            -
                        method: 'PUT',
         | 
| 42 | 
            -
                        path: object,
         | 
| 43 | 
            -
                        bucket: bucket,
         | 
| 44 | 
            -
                        resource: resource,
         | 
| 45 | 
            -
                        body: body,
         | 
| 46 | 
            -
                        location: get_bucket_location(bucket)
         | 
| 47 | 
            -
                      )
         | 
| 48 | 
            -
                    end
         | 
| 49 | 
            -
             | 
| 50 | 
            -
                    def put_folder(bucket, folder)
         | 
| 51 | 
            -
                      path = folder + '/'
         | 
| 52 | 
            -
                      resource = bucket + '/' + folder + '/'
         | 
| 53 | 
            -
                      request(
         | 
| 54 | 
            -
                        expects: [200, 203],
         | 
| 55 | 
            -
                        method: 'PUT',
         | 
| 56 | 
            -
                        path: path,
         | 
| 57 | 
            -
                        bucket: bucket,
         | 
| 58 | 
            -
                        resource: resource,
         | 
| 59 | 
            -
                        location: get_bucket_location(bucket)
         | 
| 60 | 
            -
                      )
         | 
| 61 | 
            -
                    end
         | 
| 62 | 
            -
             | 
| 63 | 
            -
                    def put_multipart_object(bucket, object, file)
         | 
| 64 | 
            -
                      location = get_bucket_location(bucket)
         | 
| 65 | 
            -
             | 
| 66 | 
            -
                      # find the right uploadid
         | 
| 67 | 
            -
                      uploads = list_multipart_uploads(bucket, location)
         | 
| 68 | 
            -
                      upload = (uploads&.find { |tmpupload| tmpupload['Key'][0] == object })
         | 
| 69 | 
            -
             | 
| 70 | 
            -
                      uploadedSize = 0
         | 
| 71 | 
            -
                      start_partNumber = 1
         | 
| 72 | 
            -
                      if !upload.nil?
         | 
| 73 | 
            -
                        uploadId = upload['UploadId'][0]
         | 
| 74 | 
            -
                        parts = list_parts(bucket, object, location, uploadId)
         | 
| 75 | 
            -
                        if !parts.nil? && !parts.empty?
         | 
| 76 | 
            -
                          if parts[-1]['Size'][0].to_i != 5_242_880
         | 
| 77 | 
            -
                            # the part is the last one, if its size is over 5m, then finish this upload
         | 
| 78 | 
            -
                            complete_multipart_upload(bucket, object, location, uploadId)
         | 
| 79 | 
            -
                            return
         | 
| 15 | 
            +
                    def put_object(bucket_name, object_name, data, options = {})
         | 
| 16 | 
            +
                      if data.is_a? ::File
         | 
| 17 | 
            +
                        @oss_protocol.put_object(bucket_name, object_name, options)do |sw|
         | 
| 18 | 
            +
                          while line = data.read(16*1024)
         | 
| 19 | 
            +
                            sw.write(line)
         | 
| 80 20 | 
             
                          end
         | 
| 81 | 
            -
                          uploadedSize = (parts[0]['Size'][0].to_i * (parts.size - 1)) + parts[-1]['Size'][0].to_i
         | 
| 82 | 
            -
                          start_partNumber = parts[-1]['PartNumber'][0].to_i + 1
         | 
| 83 21 | 
             
                        end
         | 
| 84 22 | 
             
                      else
         | 
| 85 | 
            -
                         | 
| 86 | 
            -
                         | 
| 87 | 
            -
             | 
| 88 | 
            -
             | 
| 89 | 
            -
             | 
| 90 | 
            -
                         | 
| 91 | 
            -
                         | 
| 92 | 
            -
                      end
         | 
| 93 | 
            -
             | 
| 94 | 
            -
                      end_partNumber = (file.size + 5_242_880 - 1) / 5_242_880
         | 
| 95 | 
            -
                      file.seek(uploadedSize)
         | 
| 96 | 
            -
             | 
| 97 | 
            -
                      for i in start_partNumber..end_partNumber
         | 
| 98 | 
            -
                        body = file.read(5_242_880)
         | 
| 99 | 
            -
                        upload_part(bucket, object, location, i.to_s, uploadId, body)
         | 
| 100 | 
            -
                      end
         | 
| 101 | 
            -
             | 
| 102 | 
            -
                      complete_multipart_upload(bucket, object, location, uploadId)
         | 
| 103 | 
            -
                    end
         | 
| 104 | 
            -
             | 
| 105 | 
            -
                    def initiate_multipart_upload(bucket, object, location)
         | 
| 106 | 
            -
                      location ||= get_bucket_location(bucket)
         | 
| 107 | 
            -
                      path = object + '?uploads'
         | 
| 108 | 
            -
                      resource = bucket + '/' + path
         | 
| 109 | 
            -
                      ret = request(
         | 
| 110 | 
            -
                        expects: 200,
         | 
| 111 | 
            -
                        method: 'POST',
         | 
| 112 | 
            -
                        path: path,
         | 
| 113 | 
            -
                        bucket: bucket,
         | 
| 114 | 
            -
                        resource: resource,
         | 
| 115 | 
            -
                        location: location
         | 
| 116 | 
            -
                      )
         | 
| 117 | 
            -
                      XmlSimple.xml_in(ret.data[:body])['UploadId'][0]
         | 
| 118 | 
            -
                    end
         | 
| 119 | 
            -
             | 
| 120 | 
            -
                    def upload_part(bucket, object, location, partNumber, uploadId, body)
         | 
| 121 | 
            -
                      location ||= get_bucket_location(bucket)
         | 
| 122 | 
            -
                      path = object + '?partNumber=' + partNumber + '&uploadId=' + uploadId
         | 
| 123 | 
            -
                      resource = bucket + '/' + path
         | 
| 124 | 
            -
                      request(
         | 
| 125 | 
            -
                        expects: [200, 203],
         | 
| 126 | 
            -
                        method: 'PUT',
         | 
| 127 | 
            -
                        path: path,
         | 
| 128 | 
            -
                        bucket: bucket,
         | 
| 129 | 
            -
                        resource: resource,
         | 
| 130 | 
            -
                        body: body,
         | 
| 131 | 
            -
                        location: location
         | 
| 132 | 
            -
                      )
         | 
| 133 | 
            -
                    end
         | 
| 134 | 
            -
             | 
| 135 | 
            -
                    def complete_multipart_upload(bucket, object, location, uploadId)
         | 
| 136 | 
            -
                      location ||= get_bucket_location(bucket)
         | 
| 137 | 
            -
                      parts = list_parts(bucket, object, location, uploadId, options = {})
         | 
| 138 | 
            -
                      request_part = []
         | 
| 139 | 
            -
                      return if parts.empty?
         | 
| 140 | 
            -
                      for i in 0..(parts.size - 1)
         | 
| 141 | 
            -
                        part = parts[i]
         | 
| 142 | 
            -
                        request_part[i] = { 'PartNumber' => part['PartNumber'], 'ETag' => part['ETag'] }
         | 
| 23 | 
            +
                        content=StringIO.new(data.dup)
         | 
| 24 | 
            +
                        @oss_protocol.put_object(bucket_name, object_name, options)do |sw|
         | 
| 25 | 
            +
                          while line=content.read(16*1024)
         | 
| 26 | 
            +
                            sw.write(line)
         | 
| 27 | 
            +
                          end
         | 
| 28 | 
            +
                        end
         | 
| 29 | 
            +
                        content.close
         | 
| 143 30 | 
             
                      end
         | 
| 144 | 
            -
                      body = XmlSimple.xml_out({ 'Part' => request_part }, 'RootName' => 'CompleteMultipartUpload')
         | 
| 145 | 
            -
             | 
| 146 | 
            -
                      path = object + '?uploadId=' + uploadId
         | 
| 147 | 
            -
                      resource = bucket + '/' + path
         | 
| 148 | 
            -
                      request(
         | 
| 149 | 
            -
                        expects: 200,
         | 
| 150 | 
            -
                        method: 'POST',
         | 
| 151 | 
            -
                        path: path,
         | 
| 152 | 
            -
                        bucket: bucket,
         | 
| 153 | 
            -
                        resource: resource,
         | 
| 154 | 
            -
                        location: location,
         | 
| 155 | 
            -
                        body: body
         | 
| 156 | 
            -
                      )
         | 
| 157 31 | 
             
                    end
         | 
| 158 32 | 
             
                  end
         | 
| 159 33 | 
             
                end
         |