cloud_cache 1.0.0

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.
data/History.txt ADDED
@@ -0,0 +1,6 @@
1
+ === 1.0.0 / 2009-04-23
2
+
3
+ * 1 major enhancement
4
+
5
+ * Birthday!
6
+
data/Manifest.txt ADDED
@@ -0,0 +1,9 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ bin/cloud_cache
6
+ lib/cloud_cache.rb
7
+ lib/hmac.rb
8
+ lib/hmac-sha1.rb
9
+ test/test_cloud_cache.rb
data/README.txt ADDED
@@ -0,0 +1,48 @@
1
+ = cloud_cache
2
+
3
+ http://code.google.com/p/cloudcache-ruby/
4
+
5
+ == DESCRIPTION:
6
+
7
+ Instant memcached, no servers required! See www.quetzall.com for more information.
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ * FIX (list of features or problems)
12
+
13
+ == SYNOPSIS:
14
+
15
+ FIX (code sample of usage)
16
+
17
+ == REQUIREMENTS:
18
+
19
+ * FIX (list of requirements)
20
+
21
+ == INSTALL:
22
+
23
+ sudo gem install activesupport
24
+
25
+ == LICENSE:
26
+
27
+ (The MIT License)
28
+
29
+ Copyright (c) 2009 FIX
30
+
31
+ Permission is hereby granted, free of charge, to any person obtaining
32
+ a copy of this software and associated documentation files (the
33
+ 'Software'), to deal in the Software without restriction, including
34
+ without limitation the rights to use, copy, modify, merge, publish,
35
+ distribute, sublicense, and/or sell copies of the Software, and to
36
+ permit persons to whom the Software is furnished to do so, subject to
37
+ the following conditions:
38
+
39
+ The above copyright notice and this permission notice shall be
40
+ included in all copies or substantial portions of the Software.
41
+
42
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
43
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
44
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
45
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
46
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
47
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
48
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ require './lib/cloud_cache.rb'
6
+
7
+ Hoe.new('cloud_cache', ActiveSupport::Cache::CloudCache::VERSION) do |p|
8
+ p.rubyforge_name = 'spacegems' # if different than lowercase project name
9
+ p.developer('Travis Reeder', 'travis@crankapps.com')
10
+ end
11
+
12
+ # vim: syntax=Ruby
data/bin/cloud_cache ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ abort "you need to write me"
@@ -0,0 +1,183 @@
1
+ require 'rubygems'
2
+ require 'active_support'
3
+ require 'net/http'
4
+ require 'base64'
5
+
6
+ $:.unshift(File.dirname(__FILE__))
7
+ require 'hmac-sha1'
8
+
9
+
10
+ module ActiveSupport
11
+ module Cache
12
+
13
+ class CloudCache < Store
14
+
15
+ VERSION = '1.0.0'
16
+
17
+ attr_accessor :secret_key
18
+
19
+ def initialize(bucket_name, access_key, secret_key)
20
+ puts 'Creating new CloudCache'
21
+ @access_key = access_key
22
+ @secret_key = secret_key
23
+
24
+ end
25
+
26
+ def run_http(http_method, command_name, command_path, body=nil, parameters=nil, extra_headers=nil)
27
+ ts = generate_timestamp(Time.now.gmtime)
28
+ puts 'timestamp = ' + ts
29
+ sig = generate_signature("CloudCache", command_name, ts, @secret_key)
30
+ puts "My signature = " + sig
31
+ url = "http://cloudcache.ws/" + command_path
32
+ puts url
33
+
34
+ user_agent = "CloudCache Ruby Client"
35
+ headers = {'User-Agent' => user_agent, 'signature' => sig, 'timestamp' => ts, 'akey' => @access_key}
36
+
37
+ if !extra_headers.nil?
38
+ extra_headers.each_pair do |k, v|
39
+ headers[k] = v
40
+ end
41
+ end
42
+
43
+
44
+ uri = URI.parse(url)
45
+ if (http_method == :put)
46
+ req = Net::HTTP::Put.new(uri.path)
47
+ req.body = body unless body.nil?
48
+ elsif (http_method == :post)
49
+ req = Net::HTTP::Post.new(uri.path)
50
+ if !parameters.nil?
51
+ req.set_form_data(parameters)
52
+ end
53
+ elsif (http_method == :delete)
54
+ req = Net::HTTP::Delete.new(uri.path)
55
+ if !parameters.nil?
56
+ req.set_form_data(parameters)
57
+ end
58
+ else
59
+ req = Net::HTTP::Get.new(uri.path)
60
+ end
61
+ headers.each_pair do |k, v|
62
+ req[k] = v
63
+ end
64
+ req.each_header do |k, v|
65
+ puts 'header ' + k + '=' + v
66
+ end
67
+ res = Net::HTTP.start(uri.host, uri.port) do |http|
68
+ http.request(req)
69
+ end
70
+ case res
71
+ when Net::HTTPSuccess
72
+ puts 'response body=' + res.body
73
+ res.body
74
+ else
75
+ res.error!
76
+ end
77
+
78
+ end
79
+
80
+ def auth()
81
+ command_name = "auth"
82
+ command_path = "auth"
83
+ run_http(:get, command_name, command_path)
84
+ end
85
+
86
+ def put(key, val, seconds_to_store=0)
87
+ # seconds_to_store = seconds_to_store > 0 ? seconds_to_store : 9999999
88
+ puts 'seconds=' + seconds_to_store.to_s
89
+ data = Marshal.dump(val)
90
+ val_to_put = data #(Time.now+seconds_to_store).to_i.to_s + "::" + data
91
+ extra_headers = seconds_to_store > 0 ? {"ttl"=>seconds_to_store} : nil
92
+ run_http(:put, "PUT", key, val_to_put, nil, extra_headers)
93
+ end
94
+
95
+
96
+ def get(key)
97
+
98
+ begin
99
+ cache_entry = run_http(:get, "GET", key)
100
+ rescue Net::HTTPServerException
101
+ puts $!.message
102
+ return nil if $!.message.include? "404"
103
+ end
104
+ puts 'cache_entry=' + cache_entry
105
+ =begin
106
+ index = cache_entry.index('::')
107
+ puts 'index=' + index.to_s
108
+ expires = cache_entry[0..index].to_i
109
+ puts 'expires in get=' + expires.to_s
110
+ expires2 = (expires - Time.now.to_i)
111
+ data = cache_entry[(index+2)...cache_entry.length]
112
+ =end
113
+
114
+ data = cache_entry
115
+ return Marshal.load(data)
116
+
117
+ =begin
118
+ if expires2 > 0
119
+ return Marshal.load(data)
120
+ else
121
+ puts 'expired=' + key + ' about ' + expires2.to_s + ' ago... now=' + Time.now.to_s
122
+ end
123
+ =end
124
+
125
+ end
126
+
127
+ def list_keys
128
+ body = run_http(:get, "listkeys", "listkeys")
129
+ keys = ActiveSupport::JSON.decode body # body[1..-2].split(',').collect! {|n| n.to_i}
130
+ keys
131
+ end
132
+
133
+ def read(name, options = nil)
134
+ # puts 'read from localcache'
135
+ super
136
+ ret = get(name)
137
+ # puts 'ret.frozen=' + ret.frozen?.to_s
138
+ return ret
139
+ end
140
+
141
+ def write(name, value, options = nil)
142
+ super
143
+ put(name, value, options.nil? ? nil : options[:expires_in])
144
+ # puts 'write.frozen=' + value.frozen?.to_s
145
+ end
146
+
147
+ def delete(name, options = nil)
148
+ super
149
+ run_http(:delete, "DELETE", name)
150
+ end
151
+
152
+ def delete_matched(matcher, options = nil)
153
+ super
154
+ raise "delete_matched not supported by BigCache"
155
+ end
156
+
157
+ def increment(key)
158
+ ret = run_http(:post, "POST", key + "/incr", nil, {"val"=>1})
159
+ ret.to_i
160
+ end
161
+
162
+ def decrement(key)
163
+ ret = run_http(:post, "POST", key + "/decr", nil, {"val"=>1})
164
+ ret.to_i
165
+ end
166
+
167
+ def shutdown
168
+
169
+ end
170
+
171
+
172
+ def generate_timestamp(gmtime)
173
+ return gmtime.strftime("%Y-%m-%dT%H:%M:%SZ")
174
+ end
175
+
176
+ def generate_signature(service, operation, timestamp, secret_access_key)
177
+ my_sha_hmac = HMAC::SHA1.digest(secret_access_key, service + operation + timestamp)
178
+ my_b64_hmac_digest = Base64.encode64(my_sha_hmac).strip
179
+ return my_b64_hmac_digest
180
+ end
181
+ end
182
+ end
183
+ end
data/lib/hmac-sha1.rb ADDED
@@ -0,0 +1,11 @@
1
+ require 'hmac'
2
+ require 'digest/sha1'
3
+
4
+ module HMAC
5
+ class SHA1 < Base
6
+ def initialize(key = nil)
7
+ super(Digest::SHA1, 64, 20, key)
8
+ end
9
+ public_class_method :new, :digest, :hexdigest
10
+ end
11
+ end
data/lib/hmac.rb ADDED
@@ -0,0 +1,112 @@
1
+ # Copyright (C) 2001 Daiki Ueno <ueno@unixuser.org>
2
+ # This library is distributed under the terms of the Ruby license.
3
+
4
+ # This module provides common interface to HMAC engines.
5
+ # HMAC standard is documented in RFC 2104:
6
+ #
7
+ # H. Krawczyk et al., "HMAC: Keyed-Hashing for Message Authentication",
8
+ # RFC 2104, February 1997
9
+ #
10
+ # These APIs are inspired by JCE 1.2's javax.crypto.Mac interface.
11
+ #
12
+ # <URL:http://java.sun.com/security/JCE1.2/spec/apidoc/javax/crypto/Mac.html>
13
+
14
+ module HMAC
15
+ class Base
16
+ def initialize(algorithm, block_size, output_length, key)
17
+ @algorithm = algorithm
18
+ @block_size = block_size
19
+ @output_length = output_length
20
+ @status = STATUS_UNDEFINED
21
+ @key_xor_ipad = ''
22
+ @key_xor_opad = ''
23
+ set_key(key) unless key.nil?
24
+ end
25
+
26
+ private
27
+ def check_status
28
+ unless @status == STATUS_INITIALIZED
29
+ raise RuntimeError,
30
+ "The underlying hash algorithm has not yet been initialized."
31
+ end
32
+ end
33
+
34
+ public
35
+ def set_key(key)
36
+ # If key is longer than the block size, apply hash function
37
+ # to key and use the result as a real key.
38
+ key = @algorithm.digest(key) if key.size > @block_size
39
+ key_xor_ipad = "\x36" * @block_size
40
+ key_xor_opad = "\x5C" * @block_size
41
+ for i in 0 .. key.size - 1
42
+ key_xor_ipad[i] ^= key[i]
43
+ key_xor_opad[i] ^= key[i]
44
+ end
45
+ @key_xor_ipad = key_xor_ipad
46
+ @key_xor_opad = key_xor_opad
47
+ @md = @algorithm.new
48
+ @status = STATUS_INITIALIZED
49
+ end
50
+
51
+ def reset_key
52
+ @key_xor_ipad.gsub!(/./, '?')
53
+ @key_xor_opad.gsub!(/./, '?')
54
+ @key_xor_ipad[0..-1] = ''
55
+ @key_xor_opad[0..-1] = ''
56
+ @status = STATUS_UNDEFINED
57
+ end
58
+
59
+ def update(text)
60
+ check_status
61
+ # perform inner H
62
+ md = @algorithm.new
63
+ md.update(@key_xor_ipad)
64
+ md.update(text)
65
+ str = md.digest
66
+ # perform outer H
67
+ md = @algorithm.new
68
+ md.update(@key_xor_opad)
69
+ md.update(str)
70
+ @md = md
71
+ end
72
+ alias << update
73
+
74
+ def digest
75
+ check_status
76
+ @md.digest
77
+ end
78
+
79
+ def hexdigest
80
+ check_status
81
+ @md.hexdigest
82
+ end
83
+ alias to_s hexdigest
84
+
85
+ # These two class methods below are safer than using above
86
+ # instance methods combinatorially because an instance will have
87
+ # held a key even if it's no longer in use.
88
+ def Base.digest(key, text)
89
+ begin
90
+ hmac = self.new(key)
91
+ hmac.update(text)
92
+ hmac.digest
93
+ ensure
94
+ hmac.reset_key
95
+ end
96
+ end
97
+
98
+ def Base.hexdigest(key, text)
99
+ begin
100
+ hmac = self.new(key)
101
+ hmac.update(text)
102
+ hmac.hexdigest
103
+ ensure
104
+ hmac.reset_key
105
+ end
106
+ end
107
+
108
+ private_class_method :new, :digest, :hexdigest
109
+ end
110
+
111
+ STATUS_UNDEFINED, STATUS_INITIALIZED = 0, 1
112
+ end
@@ -0,0 +1,8 @@
1
+ require "test/unit"
2
+ require "cloud_cache"
3
+
4
+ class TestCloudCache < Test::Unit::TestCase
5
+ def test_sanity
6
+ flunk "write tests or I will kneecap you"
7
+ end
8
+ end
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cloud_cache
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Travis Reeder
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-04-23 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: hoe
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.12.2
24
+ version:
25
+ description: Instant memcached, no servers required! See www.quetzall.com for more information.
26
+ email:
27
+ - travis@crankapps.com
28
+ executables:
29
+ - cloud_cache
30
+ extensions: []
31
+
32
+ extra_rdoc_files:
33
+ - History.txt
34
+ - Manifest.txt
35
+ - README.txt
36
+ files:
37
+ - History.txt
38
+ - Manifest.txt
39
+ - README.txt
40
+ - Rakefile
41
+ - bin/cloud_cache
42
+ - lib/cloud_cache.rb
43
+ - lib/hmac.rb
44
+ - lib/hmac-sha1.rb
45
+ - test/test_cloud_cache.rb
46
+ has_rdoc: true
47
+ homepage: http://code.google.com/p/cloudcache-ruby/
48
+ licenses: []
49
+
50
+ post_install_message:
51
+ rdoc_options:
52
+ - --main
53
+ - README.txt
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: "0"
61
+ version:
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: "0"
67
+ version:
68
+ requirements: []
69
+
70
+ rubyforge_project: spacegems
71
+ rubygems_version: 1.3.2
72
+ signing_key:
73
+ specification_version: 3
74
+ summary: Instant memcached, no servers required! See www.quetzall.com for more information.
75
+ test_files:
76
+ - test/test_cloud_cache.rb