class MistFiles

Constants

AuthenticationError
DEFAULT_HTTP_HEADERS
RACKSPACE_UK_URL
RACKSPACE_US_URL
RS_SERVICE_TYPES
VERB_MAP

Public Class Methods

new(opts={}) click to toggle source
# File lib/mistfiles.rb, line 9
def initialize(opts={})
  @username = opts[:username] || opts["username"]
  @api_key = opts[:api_key] || opts["api_key"]
  @region = (opts[:region] || opts["region"]).downcase.to_sym
  @british = (opts[:british] || opts["british"]) || false
  @internal = (opts[:internal] || opts["internal"]) || false
end

Public Instance Methods

auth_if_necessary!() click to toggle source
# File lib/mistfiles/authentication.rb, line 56
def auth_if_necessary!
  authenticate! unless authenticated?
end
authenticate!() click to toggle source
# File lib/mistfiles/authentication.rb, line 18
def authenticate!
  json_body = {
    :auth => {
      "RAX-KSKEY:apiKeyCredentials" => {
        :username => @username,
        :apiKey => @api_key
      }
    }
  }
  
  res = send_request(
    :host => @british ? RACKSPACE_UK_URL : RACKSPACE_US_URL,
    :path => "/v2.0/tokens",
    :method => :post,
    :body_type => :json,
    :params => json_body
  )
              
              raise AuthenticationError, "HTTP error #{res.code}" if res.code < 200 || res.code > 299
  
  body = JSON.parse(res.body)
  raise AuthenticationError, "#{self.class}: Invalid response data, something must be wrong." unless body.member?("access")
  access = body["access"]

  @token = access["token"]["id"]
  @expires = DateTime.parse(access["token"]["expires"])
  @user = access["user"]
  @user[:id] = @user.delete "id"
  @user[:username] = @user.delete "name"
  @user[:default_region] = @user.delete("RAX-AUTH:defaultRegion").downcase.to_sym
  
  catalog = access["serviceCatalog"].select { |service| RS_SERVICE_TYPES.include?(service["type"]) }.each_with_object({}) { |entry,ctlg| ctlg[entry["type"]] = entry["endpoints"] }
  
  @cdn_catalog = Hash[catalog["rax:object-cdn"].map{ |endpt| [endpt["region"].downcase.to_sym, endpt["publicURL"]] }]
  @files_catalog = Hash[catalog["object-store"].map{ |endpt| [endpt["region"].downcase.to_sym, endpt[@internal ? "internalURL" : "publicURL"]] }]
  nil
end
authenticated?() click to toggle source
# File lib/mistfiles/authentication.rb, line 14
def authenticated?
  @token && @token.length > 0 && @expires && @expires.to_time.to_i > Time.now.to_i
end
cdn_settings(params={}) click to toggle source
# File lib/mistfiles/containers.rb, line 98
def cdn_settings(params={})
              auth_if_necessary!
  container = params[:container] || params["container"]
  send_request(
    :host => @cdn_catalog[@region],
    :path => "/#{container}",
    :method => :head
  )
end
cdn_settings=(params={}) click to toggle source

parameters :ttl => The ttl in seconds :enabled => A true or false value indicating the CDN status of the container :log_retention => Whether RackSpace should store CDN access logs in the container. IMPORTANT: if the log_retention parameter is passed, this request will not be able to

# File lib/mistfiles/containers.rb, line 76
def cdn_settings=(params={})
              auth_if_necessary!
  container = params[:container] || params["container"]
  ttl = (params[:ttl] || params["ttl"]).to_i.to_s
  enabled = (params[:enabled] || params["enabled"]) ? "True" : "False"
  log_retention = params[:log_retention] || params["log_retention"]
  
  headers = {}
  headers["X-Ttl"] = ttl unless ttl.nil? || ttl.empty?
  headers["X-Cdn-Enabled"] = container unless container.nil? || container.empty?
  headers["X-Log-Retention"] = log_retention if params.member?(:log_retention) || params.member?("log_retention")
  
  method = headers.member?("X-Log-Retention") ? :post : :put
  
  send_request(
    :host => @cdn_catalog[@region],
    :path => "/#{container}",
    :method => method,
    :headers => headers
  )
end
create_container(params={}) click to toggle source
# File lib/mistfiles/containers.rb, line 6
def create_container(params={})
              auth_if_necessary!
  container = params[:container] || params["container"]
  headers = params[:headers] || params["headers"]
  send_request(
    :host => @files_catalog[@region],
    :path => "/#{container}",
    :method => :put,
    :params => params || {},
    :headers => headers
  )
end
create_object(params={}) click to toggle source
# File lib/mistfiles/objects.rb, line 6
def create_object(params={})
              auth_if_necessary!
  # Required parameters
  data = params[:data] || params["data"]
  container = params[:container] || params["container"]
  object = params[:object] || params["object"]
  
  # optional parameters
  content_type = params[:content_type] || params["content_type"] # can be detected by Rackspace
  delete_at = (params[:delete_at] || params["delete_at"]).to_i
  delete_after = (params[:delete_after] || params["delete_after"]).to_i
  name = (params[:name] || params["name"])
  
  # TODO: Implement X-Copy-From
  
  headers = {
    "ETag" => Digest::MD5.digest(data)
  }
  
  # Either X-Detect-Content-Type or Content-Type is required
  headers["X-Detect-Content-Type"] = "True" if content_type.nil?
  headers["Content-Type"] = content_type unless content_type.nil?
  headers["X-Object-Meta-name"] = name unless name.nil?
  
  send_request(
    :host => @files_catalog[@region],
    :path => "/#{container}/#{object}",
    :method => :put,
    :body_type => :raw,
    :params => data,
    :headers => headers
  )
end
Also aliased as: update_object
delete_object(params={}) click to toggle source
# File lib/mistfiles/objects.rb, line 44
def delete_object(params={})
              auth_if_necessary!
  container = params[:container] || params["container"]
  object = params[:object] || params["object"]
  send_request(
    :host => @files_catalog[@region],
    :path => "/#{container}/#{object}",
    :method => :delete
  )
end
destroy_container(params={}) click to toggle source
# File lib/mistfiles/containers.rb, line 32
def destroy_container(params={})
              auth_if_necessary!
  container = params[:container] || params["container"]
  send_request(
    :host => @files_catalog[@region],
    :path => "/#{container}",
    :method => :delete,
    :params => params || {}
  )
end
get_object(params={}) click to toggle source
# File lib/mistfiles/objects.rb, line 55
def get_object(params={})
              auth_if_necessary!
  ontainer = params[:container] || params["container"]
  object = params[:object] || params["object"]
  headers = params[:headers] || params["headers"]
  send_request(
    :host => @files_catalog[@region],
    :path => "/#{container}/#{object}",
    :method => :get,
    :params => params || {},
    :headers => headers,
    :parse_json => false
  )
end
http(opts={}) click to toggle source
# File lib/mistfiles/send_request.rb, line 41
def http(opts={})
  @http_objs ||= {}
  
  uri = opts[:uri] || opts["uri"]
  http = @http_objs[uri.host]
  return http unless http.nil?
  
  http = Net::HTTP.new uri.host, uri.port
  if uri.port == 443
    http.use_ssl = true
    http.verify_mode = OpenSSL::SSL::VERIFY_PEER
  end
  @http_objs[uri.host] = http
  http
end
list_containers(params={}) click to toggle source

list_containers(params={}) :limit => the number of containers to return :marker => returns results after the container name specified here :end_marker => retuns results before the container name

# File lib/mistfiles/containers.rb, line 47
def list_containers(params={})
  auth_if_necessary!
  send_request(
    :host => @files_catalog[@region],
    :method => :get,
    :params => params || {}
  )
end
list_objects(params={}) click to toggle source

lists objects ALSO gets container metadata

# File lib/mistfiles/containers.rb, line 58
def list_objects(params={})
  auth_if_necessary!
  
  container = (params[:container] || params["container"])
  
  send_request(
    :host => @files_catalog[@region],
    :path => "/#{container}",
    :method => :get,
    :params => params || {}
  )
end
send_request(opts={}) click to toggle source
# File lib/mistfiles/send_request.rb, line 57
def send_request(opts={})
  parse_json  = (opts[:parse_json] || opts["parse_json"]) == true
  host        = opts[:host] || opts["host"]
  path        = opts[:path] || opts["path"] || ""
  method      = (opts[:method] || opts["method"]).to_sym
  params      = opts[:params] || opts["params"] || {}
  body        = opts[:body] || opts["body"]
  body_type   = (opts[:body_type] || opts["body_type"] || :ignored).to_sym
  headers     = DEFAULT_HTTP_HEADERS.merge(opts[:headers] || opts["headers"] || {})
  headers.merge!({ "X-Auth-Token" => @token }) unless @token.nil? || @token.empty?
  
  uri = URI.parse host
  path = uri.path + path
  
  request = 
  case method
  when :get
    path << "?" + URI.encode_www_form(params) unless params.empty?
    VERB_MAP[method].new path
  else
    request = VERB_MAP[method].new path
    case body_type
    when :json
      request.body = 
      case params
      when String
        params
      else
        params.to_json
      end
    when :form_data
      request.set_form_data params
    when :raw
      request.body = body
    end
    request
  end
  
  headers.each { |k,v| request.add_field k,v }

  MistFilesResponse.new(
                      :response => http(:uri => uri).request(request),
                      :parse_json => parse_json
              )
end
update_container(params={}) click to toggle source
# File lib/mistfiles/containers.rb, line 19
def update_container(params={})
              auth_if_necessary!
  container = params[:container] || params["container"]
  headers = params[:headers] || params["headers"]
  send_request(
    :host => @files_catalog[@region],
    :path => "/#{container}",
    :method => :post,
    :params => params || {},
    :headers => headers
  )
end
update_object(params={})

Create and Update are the same Rackspace doesn’t have a patch endpoint here

Alias for: create_object