This file is indexed.

/usr/lib/ruby/1.8/moneta/s3.rb is in libmoneta-ruby1.8 0.6.0-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
begin
  require "right_aws"
rescue LoadError
  puts "You need the RightScale AWS gem to use the S3 moneta store"
  exit  
end

module Moneta
  # An S3 implementation of Moneta
  #
  # Example usage:
  #
  #   require 'rubygems'
  #   require 'moneta'
  #   require 'moneta/s3'
  #
  #   store = Moneta::S3.new(
  #     :access_key_id => 'ACCESS_KEY_ID', 
  #     :secret_access_key => 'SECRET_ACCESS_KEY', 
  #     :bucket => 'a_bucket'
  #   )
  #   store['somefile'] 
  class S3
    # Initialize the Moneta::S3 store.
    #
    # Required values passed in the options hash:
    # * <tt>:access_key_id</tt>: The access id key
    # * <tt>:secret_access_key</tt>: The secret key
    # * <tt>:bucket</tt>: The name of bucket. Will be created if it doesn't
    # exist.
    # * <tt>:multi_thread</tt>: Set to true if using threading
    def initialize(options = {})
      validate_options(options)
      s3 = RightAws::S3.new(
        options[:access_key_id], 
        options[:secret_access_key], 
        {
          :logger => logger, 
          :multi_thread => options.delete(:multi_thread) || false
        }
      )
      @bucket = s3.bucket(options.delete(:bucket), true)
    end
    
    def key?(key)
      !s3_key(key).nil?
    end
    
    alias has_key? key?
    
    def [](key)
      get(key)
    end
    
    def []=(key, value)
      store(key, value)
    end
        
    def delete(key)
      k = s3_key(key)
      if k
        value = k.get
        k.delete
        value
      end
    end
    
    # Store the key/value pair.
    # 
    # Options:
    # *<tt>:meta_headers</tt>: Meta headers passed to S3
    # *<tt>:perms</tt>: Permissions passed to S3
    # *<tt>:headers</tt>: Headers sent as part of the PUT request
    # *<tt>:expires_in</tt>: Number of seconds until expiration
    def store(key, value, options = {})
      debug "store(key=#{key}, value=#{value}, options=#{options.inspect})"
      meta_headers = meta_headers_from_options(options)
      perms = options[:perms]
      headers = options[:headers] || {}
      
      case value
      when IO
        @bucket.put(key, value.read, meta_headers, perms, headers)
      else
        @bucket.put(key, value, meta_headers, perms, headers)
      end
    end
    
    def update_key(key, options = {})
      debug "update_key(key=#{key}, options=#{options.inspect})"
      k = s3_key(key, false)
      k.save_meta(meta_headers_from_options(options)) unless k.nil?
    end
    
    def clear
      @bucket.clear
    end
    
    protected
    def logger
      @logger ||= begin
        logger = Logger.new(STDOUT)
        logger.level = Logger::FATAL
        logger
      end
    end
    
    private
    def validate_options(options)
      unless options[:access_key_id]
        raise RuntimeError, ":access_key_id is required in options"
      end
      unless options[:secret_access_key]
        raise RuntimeError, ":secret_access_key is required in options"
      end
      unless options[:bucket]
        raise RuntimeError, ":bucket is required in options"
      end
    end
    
    def get(key)
      k = s3_key(key)
      k.nil? ? nil : k.get
    end
    
    def s3_key(key, nil_if_expired=true)
      begin
        s3_key = @bucket.key(key, true)
        if s3_key.exists?
          logger.debug "[Moneta::S3] key exists: #{key}"
          if s3_key.meta_headers.has_key?('expires-at')
            expires_at = Time.parse(s3_key.meta_headers['expires-at'])
            if Time.now > expires_at && nil_if_expired
              # TODO delete the object?
              debug "key expired: #{key} (@#{s3_key.meta_headers['expires-at']})"
              return nil
            end
          end
          return s3_key
        else
          debug "key does not exist: #{key}"
        end
      rescue RightAws::AwsError => e
        debug "key does not exist: #{key}"
      end
      nil
    end
    
    def meta_headers_from_options(options={})
      meta_headers = options[:meta_headers] || {}
      if options[:expires_in]
        meta_headers['expires-at'] = (Time.now + options[:expires_in]).rfc2822
      end
      debug "setting expires-at: #{meta_headers['expires-at']}"
      meta_headers
    end
    
    def debug(message)
      logger.debug "[Moneta::S3] #{message}"
    end
  end
end