shuck 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- shuck (0.0.2)
4
+ shuck (0.0.3)
5
5
  builder
6
6
  thor
7
7
 
@@ -18,6 +18,9 @@ GEM
18
18
  linecache19 (0.5.11)
19
19
  ruby_core_source (>= 0.1.4)
20
20
  mime-types (1.16)
21
+ right_aws (2.0.0)
22
+ right_http_connection (>= 1.2.1)
23
+ right_http_connection (1.2.4)
21
24
  ruby-debug-base19 (0.11.24)
22
25
  columnize (>= 0.3.1)
23
26
  linecache19 (>= 0.5.11)
@@ -38,6 +41,7 @@ DEPENDENCIES
38
41
  aws-s3
39
42
  builder
40
43
  bundler (>= 1.0.0)
44
+ right_aws
41
45
  ruby-debug19
42
46
  shuck!
43
47
  thor
data/README.md ADDED
@@ -0,0 +1,8 @@
1
+ == Introduction ==
2
+ Shuck is a lightweight interface for S3 that can have any backend. It is
3
+ mainly useful for testing of S3 in a sandbox environment without actually
4
+ making calls to Amazon. For now there is a basic file store backend.
5
+
6
+ == Running Tests ==
7
+ In order to run the tests add the following line to your /etc/hosts:
8
+ 127.0.0.1 s3.localhost
data/Rakefile CHANGED
@@ -8,3 +8,6 @@ Rake::TestTask.new(:test) do |t|
8
8
  t.ruby_opts << '-I.'
9
9
  end
10
10
 
11
+ task :test_server do |t|
12
+ system("bundle exec bin/shuck --port 10453 --root test_root")
13
+ end
data/lib/shuck/cli.rb CHANGED
@@ -5,9 +5,10 @@ module Shuck
5
5
  class CLI < Thor
6
6
  default_task("server")
7
7
 
8
- desc "server", "Run a server"
9
- method_option :root, :type => :string, :aliases => '-r'
8
+ desc "server", "Run a server on a particular hostname"
9
+ method_option :root, :type => :string, :aliases => '-r', :required => true
10
10
  method_option :port, :type => :numeric, :aliases => '-p', :required => true
11
+ method_option :hostname, :type => :string, :aliases => '-h', :desc => "The root name of the host. Defaults to localhost."
11
12
  def server
12
13
  store = nil
13
14
  if options[:root]
@@ -18,8 +19,14 @@ module Shuck
18
19
  puts "You must specify a root to use a file store (the current default)"
19
20
  exit(-1)
20
21
  end
21
- puts "Loading Shuck with #{root} on port #{options[:port]}"
22
- server = Shuck::Server.new(options[:port],store)
22
+
23
+ hostname = 's3.amazonaws.com'
24
+ if options[:hostname]
25
+ hostname = options[:hostname]
26
+ end
27
+
28
+ puts "Loading Shuck with #{root} on port #{options[:port]} with hostname #{hostname}"
29
+ server = Shuck::Server.new(options[:port],store,hostname)
23
30
  server.serve
24
31
  end
25
32
  end
data/lib/shuck/server.rb CHANGED
@@ -4,24 +4,37 @@ require 'shuck/xml_adapter'
4
4
 
5
5
  module Shuck
6
6
  class Servlet < WEBrick::HTTPServlet::AbstractServlet
7
- def initialize(server,store)
7
+ def initialize(server,store,hostname)
8
8
  super(server)
9
9
  @store = store
10
+ @hostname = hostname
10
11
  end
11
12
 
12
13
  def do_GET(request, response)
13
14
  path = request.path
14
15
  path_len = path.size
16
+ host = request["HOST"]
17
+ path_style_request = true
18
+ bucket = nil
19
+ if host != @hostname
20
+ bucket = host.split(".")[0]
21
+ path_style_request = false
22
+ end
15
23
 
16
- if path == "/"
24
+ if path == "/" and path_style_request
17
25
  response.status = 200
18
26
  response['Content-Type'] = 'text/xml'
19
27
  buckets = @store.buckets
20
28
  response.body = XmlAdapter.buckets(buckets)
21
29
  else
22
- elems = path[1,path_len].split("/")
23
- bucket = elems[0]
24
- if elems.size == 1
30
+ if path_style_request
31
+ elems = path[1,path_len].split("/")
32
+ bucket = elems[0]
33
+ else
34
+ elems = path.split("/")
35
+ end
36
+
37
+ if elems.size == 1
25
38
  bucket_obj = @store.get_bucket(bucket)
26
39
  if bucket_obj
27
40
  response.status = 200
@@ -51,16 +64,38 @@ module Shuck
51
64
  def do_PUT(request,response)
52
65
  path = request.path
53
66
  path_len = path.size
67
+ path_style_request = true
68
+ host = request["Host"]
69
+ bucket = nil
70
+ path_style_request = true
71
+ if host != @hostname
72
+ bucket = host.split(".")[0]
73
+ path_style_request = false
74
+ end
75
+
54
76
  if path == "/"
55
- puts "Unsure what to do"
56
- else
57
- elems = path[1,path_len].split("/")
58
- bucket = elems[0]
59
- if elems.size == 1
77
+ if bucket
60
78
  @store.create_bucket(bucket)
61
- else
62
- object = elems[1,elems.size].join('/')
63
- @store.store_object(bucket,object,request)
79
+ else
80
+ puts "Unsure what to do"
81
+ end
82
+ else
83
+ if path_style_request
84
+ elems = path[1,path_len].split("/")
85
+ bucket = elems[0]
86
+ else
87
+ elems = path.split("/")
88
+ end
89
+
90
+ if path_style_request
91
+ if elems.size == 1
92
+ @store.create_bucket(bucket)
93
+ else
94
+ object = elems[1,elems.size].join('/')
95
+ @store.store_object(bucket,object,request)
96
+ end
97
+ else
98
+ @store.store_object(bucket,path,request)
64
99
  end
65
100
  end
66
101
  response.status = 200
@@ -80,14 +115,15 @@ module Shuck
80
115
  end
81
116
 
82
117
  class Server
83
- def initialize(port,store)
118
+ def initialize(port,store,hostname = "localhost")
84
119
  @port = port
85
120
  @store = store
121
+ @hostname = hostname
86
122
  end
87
123
 
88
124
  def serve
89
125
  @server = WEBrick::HTTPServer.new(:Port => @port)
90
- @server.mount "/", Servlet, @store
126
+ @server.mount "/", Servlet, @store,@hostname
91
127
  trap "INT" do @server.shutdown end
92
128
  @server.start
93
129
  end
data/lib/shuck/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Shuck
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
data/shuck.gemspec CHANGED
@@ -17,6 +17,7 @@ Gem::Specification.new do |s|
17
17
  s.add_development_dependency "bundler", ">= 1.0.0"
18
18
  s.add_development_dependency "ruby-debug19"
19
19
  s.add_development_dependency "aws-s3"
20
+ s.add_development_dependency "right_aws"
20
21
  s.add_dependency "thor"
21
22
  s.add_dependency "builder"
22
23
 
@@ -0,0 +1,54 @@
1
+ require 'test/test_helper'
2
+ require 'fileutils'
3
+ require 'shuck/server'
4
+ require 'right_aws'
5
+
6
+ class RightAWSCommandsTest < Test::Unit::TestCase
7
+
8
+ def setup
9
+ @s3 = RightAws::S3Interface.new('1E3GDYEOGFJPIT7XXXXXX','hgTHt68JY07JKUY08ftHYtERkjgtfERn57XXXXXX', {:multi_thread => false, :logger => Logger.new('/tmp/x.log'), :server => 'localhost', :port => 10453, :protocol => 'http' })
10
+ end
11
+
12
+ def teardown
13
+ end
14
+
15
+ def test_create_bucket
16
+ bucket = @s3.create_bucket("s3media")
17
+ assert_not_nil bucket
18
+ end
19
+
20
+ def test_store
21
+ @s3.put("s3media","helloworld","Hello World Man!")
22
+ obj = @s3.get("s3media","helloworld")
23
+ assert_equal "Hello World Man!",obj[:object]
24
+
25
+ obj = @s3.get("s3media","helloworld", )
26
+ end
27
+
28
+ def test_large_store
29
+ @s3.put("s3media","helloworld","Hello World Man!")
30
+ buffer = ""
31
+ 500000.times do
32
+ buffer << "#{(rand * 100).to_i}"
33
+ end
34
+ #
35
+ buf_len = buffer.length
36
+ @s3.put("s3media","big",buffer)
37
+
38
+ output = ""
39
+ @s3.get("s3media","big") do |chunk|
40
+ output << chunk
41
+ end
42
+ assert_equal buf_len,output.size
43
+ end
44
+
45
+ def test_multi_directory
46
+ @s3.put("s3media","dir/right/123.txt","recursive")
47
+ output = ""
48
+ obj = @s3.get("s3media","dir/right/123.txt") do |chunk|
49
+ output << chunk
50
+ end
51
+ assert_equal "recursive", output
52
+ end
53
+
54
+ end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 3
9
- version: 0.0.3
8
+ - 4
9
+ version: 0.0.4
10
10
  platform: ruby
11
11
  authors:
12
12
  - Curtis Spencer
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-11-23 00:00:00 -08:00
17
+ date: 2010-12-11 00:00:00 -08:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -59,7 +59,7 @@ dependencies:
59
59
  type: :development
60
60
  version_requirements: *id003
61
61
  - !ruby/object:Gem::Dependency
62
- name: thor
62
+ name: right_aws
63
63
  prerelease: false
64
64
  requirement: &id004 !ruby/object:Gem::Requirement
65
65
  none: false
@@ -69,10 +69,10 @@ dependencies:
69
69
  segments:
70
70
  - 0
71
71
  version: "0"
72
- type: :runtime
72
+ type: :development
73
73
  version_requirements: *id004
74
74
  - !ruby/object:Gem::Dependency
75
- name: builder
75
+ name: thor
76
76
  prerelease: false
77
77
  requirement: &id005 !ruby/object:Gem::Requirement
78
78
  none: false
@@ -84,6 +84,19 @@ dependencies:
84
84
  version: "0"
85
85
  type: :runtime
86
86
  version_requirements: *id005
87
+ - !ruby/object:Gem::Dependency
88
+ name: builder
89
+ prerelease: false
90
+ requirement: &id006 !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ segments:
96
+ - 0
97
+ version: "0"
98
+ type: :runtime
99
+ version_requirements: *id006
87
100
  description: Use Shuck to test basic S3 functionality without actually connecting to S3
88
101
  email:
89
102
  - curtis@sevenforge.com
@@ -97,6 +110,7 @@ files:
97
110
  - .gitignore
98
111
  - Gemfile
99
112
  - Gemfile.lock
113
+ - README.md
100
114
  - Rakefile
101
115
  - bin/shuck
102
116
  - lib/shuck.rb
@@ -108,6 +122,7 @@ files:
108
122
  - lib/shuck/version.rb
109
123
  - lib/shuck/xml_adapter.rb
110
124
  - shuck.gemspec
125
+ - test/right_aws_commands_test.rb
111
126
  - test/s3_commands_test.rb
112
127
  - test/test_helper.rb
113
128
  has_rdoc: true
@@ -143,5 +158,6 @@ signing_key:
143
158
  specification_version: 3
144
159
  summary: Shuck is a phony S3 engine with minimal dependencies
145
160
  test_files:
161
+ - test/right_aws_commands_test.rb
146
162
  - test/s3_commands_test.rb
147
163
  - test/test_helper.rb