fakes3 1.2.1 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CONTRIBUTING.md +1 -0
- data/README.md +4 -2
- data/Rakefile +1 -1
- data/lib/fakes3/cli.rb +34 -2
- data/lib/fakes3/server.rb +33 -20
- data/lib/fakes3/version.rb +1 -1
- data/test/aws_sdk_v2_commands_test.rb +9 -1
- data/test/cli_test.rb +1 -1
- data/test/post_test.rb +6 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 4deaaab0070103b1803099e1067fd78dad5a34ac86dede4198c604a9d47bfc20
|
4
|
+
data.tar.gz: fbb4c771b4df864cd7460a9bf4c5fa2fb80a5c7b554dd7c1dda77cd5338e83f6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7382cef361cd7b7aaf048a34695357e08bbd61c9c677a06fa130394ca2dbad2627dceb7c4ef2a7bd4bfe2d4b46723ba3edf47d083dc2dfab17d90778a416c35e
|
7
|
+
data.tar.gz: 2688032f252dcdda84464cbc6c09cb834942996fbc7c575c43f7ff73a7b8398ccb40631584c678b4c0ef207c10f2505a49f7cbd5277809d88efe9b00eb0c1156
|
data/CONTRIBUTING.md
CHANGED
@@ -16,6 +16,7 @@ There are some prerequisites to actually being able to run the unit/integration
|
|
16
16
|
On macOS, edit your /etc/hosts and add the following line:
|
17
17
|
|
18
18
|
127.0.0.1 posttest.localhost
|
19
|
+
127.0.0.1 v2.bucket.localhost
|
19
20
|
|
20
21
|
Then ensure that the following packages are installed (boto, s3cmd):
|
21
22
|
|
data/README.md
CHANGED
@@ -17,9 +17,9 @@ Many commands are supported, including put, get, list, copy, and make bucket.
|
|
17
17
|
|
18
18
|
## Running
|
19
19
|
|
20
|
-
To run the server, you
|
20
|
+
To run the server, you must specify a root, a port, and your license key.
|
21
21
|
|
22
|
-
fakes3 -r /mnt/fakes3_root -p 4567
|
22
|
+
fakes3 -r /mnt/fakes3_root -p 4567 --license YOUR_LICENSE_KEY
|
23
23
|
|
24
24
|
## Licensing
|
25
25
|
|
@@ -29,6 +29,8 @@ https://supso.org/projects/fake-s3
|
|
29
29
|
|
30
30
|
Depending on your company's size, the license may be free. It is also free for individuals.
|
31
31
|
|
32
|
+
You pass the license key to Fake S3 with the command line option --license YOUR_LICENSE_KEY.
|
33
|
+
|
32
34
|
## Connecting to Fake S3
|
33
35
|
|
34
36
|
Take a look at the test cases to see client example usage. For now, Fake S3 is
|
data/Rakefile
CHANGED
@@ -16,7 +16,7 @@ end
|
|
16
16
|
|
17
17
|
desc "Run the test_server"
|
18
18
|
task :test_server do |t|
|
19
|
-
system("bundle exec bin/fakes3 --port 10453 --root test_root")
|
19
|
+
system("bundle exec bin/fakes3 --port 10453 --license test --root test_root --corspostputallowheaders 'Authorization, Content-Length, Cache-Control'")
|
20
20
|
end
|
21
21
|
|
22
22
|
task :default => :test
|
data/lib/fakes3/cli.rb
CHANGED
@@ -15,8 +15,33 @@ module FakeS3
|
|
15
15
|
method_option :limit, :aliases => '-l', :type => :string, :desc => 'Rate limit for serving (ie. 50K, 1.0M)'
|
16
16
|
method_option :sslcert, :type => :string, :desc => 'Path to SSL certificate'
|
17
17
|
method_option :sslkey, :type => :string, :desc => 'Path to SSL certificate key'
|
18
|
+
method_option :corsorigin, :type => :string, :desc => 'Access-Control-Allow-Origin header return value'
|
19
|
+
method_option :corsmethods, :type => :string, :desc => 'Access-Control-Allow-Methods header return value'
|
20
|
+
method_option :corspreflightallowheaders, :type => :string, :desc => 'Access-Control-Allow-Headers header return value for preflight OPTIONS requests'
|
21
|
+
method_option :corspostputallowheaders, :type => :string, :desc => 'Access-Control-Allow-Headers header return value for POST and PUT requests'
|
22
|
+
method_option :corsexposeheaders, :type => :string, :desc => 'Access-Control-Expose-Headers header return value'
|
23
|
+
method_option :license, :type => :string, :desc => 'Your license key, available at https://supso.org/projects/fake-s3'
|
18
24
|
|
19
25
|
def server
|
26
|
+
license_key = options[:license]
|
27
|
+
if license_key.nil?
|
28
|
+
license_message = """
|
29
|
+
======================
|
30
|
+
As of version 1.3, Fake S3 requires a license key passed with --license YOUR_LICENSE_KEY.
|
31
|
+
Please fix this before September 18, 2018.
|
32
|
+
You can get a license at:
|
33
|
+
https://supso.org/projects/fake-s3
|
34
|
+
======================
|
35
|
+
|
36
|
+
"""
|
37
|
+
licensing_required = Time.now > Time.utc(2018, 9, 19)
|
38
|
+
if licensing_required
|
39
|
+
abort license_message
|
40
|
+
else
|
41
|
+
warn license_message
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
20
45
|
store = nil
|
21
46
|
if options[:root]
|
22
47
|
root = File.expand_path(options[:root])
|
@@ -45,6 +70,13 @@ module FakeS3
|
|
45
70
|
end
|
46
71
|
end
|
47
72
|
|
73
|
+
cors_options = {}
|
74
|
+
cors_options['allow_origin'] = options[:corsorigin] if options[:corsorigin]
|
75
|
+
cors_options['allow_methods'] = options[:corsmethods] if options[:corsmethods]
|
76
|
+
cors_options['preflight_allow_headers'] = options[:corspreflightallowheaders] if options[:corspreflightallowheaders]
|
77
|
+
cors_options['post_put_allow_headers'] = options[:corspostputallowheaders] if options[:corspostputallowheaders]
|
78
|
+
cors_options['expose_headers'] = options[:corsexposeheaders] if options[:corsexposeheaders]
|
79
|
+
|
48
80
|
address = options[:address]
|
49
81
|
ssl_cert_path = options[:sslcert]
|
50
82
|
ssl_key_path = options[:sslkey]
|
@@ -53,8 +85,8 @@ module FakeS3
|
|
53
85
|
abort "If you specify an SSL certificate you must also specify an SSL certificate key"
|
54
86
|
end
|
55
87
|
|
56
|
-
puts "Loading
|
57
|
-
server = FakeS3::Server.new(address,options[:port],store,hostname,ssl_cert_path,ssl_key_path, quiet: !!options[:quiet])
|
88
|
+
puts "Loading Fake S3 with #{root} on port #{options[:port]} with hostname #{hostname}" unless options[:quiet]
|
89
|
+
server = FakeS3::Server.new(address,options[:port],store,hostname,ssl_cert_path,ssl_key_path, quiet: !!options[:quiet], cors_options: cors_options)
|
58
90
|
server.serve
|
59
91
|
end
|
60
92
|
|
data/lib/fakes3/server.rb
CHANGED
@@ -49,12 +49,19 @@ module FakeS3
|
|
49
49
|
end
|
50
50
|
|
51
51
|
class Servlet < WEBrick::HTTPServlet::AbstractServlet
|
52
|
-
def initialize(server,store,hostname)
|
52
|
+
def initialize(server,store,hostname,cors_options)
|
53
53
|
super(server)
|
54
54
|
@store = store
|
55
55
|
@hostname = hostname
|
56
56
|
@port = server.config[:Port]
|
57
57
|
@root_hostnames = [hostname,'localhost','s3.amazonaws.com','s3.localhost']
|
58
|
+
|
59
|
+
# Here lies hard-coded defaults for CORS Configuration
|
60
|
+
@cors_allow_origin = (cors_options['allow_origin'] or '*')
|
61
|
+
@cors_allow_methods = (cors_options['allow_methods'] or 'PUT, POST, HEAD, GET, OPTIONS')
|
62
|
+
@cors_preflight_allow_headers = (cors_options['preflight_allow_headers'] or 'Accept, Content-Type, Authorization, Content-Length, ETag, X-CSRF-Token, Content-Disposition')
|
63
|
+
@cors_post_put_allow_headers = (cors_options['post_put_allow_headers'] or 'Authorization, Content-Length')
|
64
|
+
@cors_expose_headers = (cors_options['expose_headers'] or 'ETag')
|
58
65
|
end
|
59
66
|
|
60
67
|
def validate_request(request)
|
@@ -101,7 +108,7 @@ module FakeS3
|
|
101
108
|
response.status = 404
|
102
109
|
response.body = XmlAdapter.error_no_such_key(s_req.object)
|
103
110
|
response['Content-Type'] = "application/xml"
|
104
|
-
response['Access-Control-Allow-Origin'] =
|
111
|
+
response['Access-Control-Allow-Origin'] = @cors_allow_origin
|
105
112
|
return
|
106
113
|
end
|
107
114
|
|
@@ -134,7 +141,7 @@ module FakeS3
|
|
134
141
|
response.header['ETag'] = "\"#{real_obj.md5}\""
|
135
142
|
response['Accept-Ranges'] = "bytes"
|
136
143
|
response['Last-Ranges'] = "bytes"
|
137
|
-
response['Access-Control-Allow-Origin'] =
|
144
|
+
response['Access-Control-Allow-Origin'] = @cors_allow_origin
|
138
145
|
|
139
146
|
real_obj.custom_metadata.each do |header, value|
|
140
147
|
response.header['x-amz-meta-' + header] = value
|
@@ -188,7 +195,7 @@ module FakeS3
|
|
188
195
|
response.status = 200
|
189
196
|
response.body = ""
|
190
197
|
response['Content-Type'] = "text/xml"
|
191
|
-
response['Access-Control-Allow-Origin'] =
|
198
|
+
response['Access-Control-Allow-Origin'] = @cors_allow_origin
|
192
199
|
|
193
200
|
case s_req.type
|
194
201
|
when Request::COPY
|
@@ -240,9 +247,9 @@ module FakeS3
|
|
240
247
|
response.header['ETag'] = "\"#{real_obj.md5}\""
|
241
248
|
end
|
242
249
|
|
243
|
-
response['Access-Control-Allow-Origin'] =
|
244
|
-
response['Access-Control-Allow-Headers'] =
|
245
|
-
response['Access-Control-Expose-Headers'] =
|
250
|
+
response['Access-Control-Allow-Origin'] = @cors_allow_origin
|
251
|
+
response['Access-Control-Allow-Headers'] = @cors_post_put_allow_headers
|
252
|
+
response['Access-Control-Expose-Headers'] = @cors_expose_headers
|
246
253
|
|
247
254
|
response.status = 200
|
248
255
|
end
|
@@ -322,9 +329,9 @@ module FakeS3
|
|
322
329
|
end
|
323
330
|
|
324
331
|
response['Content-Type'] = 'text/xml'
|
325
|
-
response['Access-Control-Allow-Origin'] =
|
326
|
-
response['Access-Control-Allow-Headers'] =
|
327
|
-
response['Access-Control-Expose-Headers'] =
|
332
|
+
response['Access-Control-Allow-Origin'] = @cors_allow_origin
|
333
|
+
response['Access-Control-Allow-Headers'] = @cors_post_put_allow_headers
|
334
|
+
response['Access-Control-Expose-Headers'] = @cors_expose_headers
|
328
335
|
end
|
329
336
|
|
330
337
|
def do_DELETE(request, response)
|
@@ -348,10 +355,10 @@ module FakeS3
|
|
348
355
|
|
349
356
|
def do_OPTIONS(request, response)
|
350
357
|
super
|
351
|
-
response['Access-Control-Allow-Origin'] =
|
352
|
-
response['Access-Control-Allow-Methods'] =
|
353
|
-
response['Access-Control-Allow-Headers'] =
|
354
|
-
response['Access-Control-Expose-Headers'] =
|
358
|
+
response['Access-Control-Allow-Origin'] = @cors_allow_origin
|
359
|
+
response['Access-Control-Allow-Methods'] = @cors_allow_methods
|
360
|
+
response['Access-Control-Allow-Headers'] = @cors_preflight_allow_headers
|
361
|
+
response['Access-Control-Expose-Headers'] = @cors_expose_headers
|
355
362
|
end
|
356
363
|
|
357
364
|
private
|
@@ -371,9 +378,13 @@ module FakeS3
|
|
371
378
|
end
|
372
379
|
|
373
380
|
if elems.size == 0
|
374
|
-
s_req.
|
375
|
-
|
376
|
-
|
381
|
+
if s_req.is_path_style
|
382
|
+
s_req.type = Request::DELETE_OBJECTS
|
383
|
+
s_req.query = query
|
384
|
+
s_req.webrick_request = webrick_req
|
385
|
+
else
|
386
|
+
s_req.type = Request::DELETE_BUCKET
|
387
|
+
end
|
377
388
|
elsif elems.size == 1
|
378
389
|
s_req.type = webrick_req.query_string == 'delete' ? Request::DELETE_OBJECTS : Request::DELETE_BUCKET
|
379
390
|
s_req.query = query
|
@@ -486,8 +497,9 @@ module FakeS3
|
|
486
497
|
s_req.path = webrick_req.path
|
487
498
|
s_req.is_path_style = true
|
488
499
|
|
489
|
-
|
490
|
-
|
500
|
+
root_hostname = @root_hostnames.find { |hostname| host.end_with?(".#{hostname}") }
|
501
|
+
if root_hostname
|
502
|
+
s_req.bucket = host[0...-root_hostname.size - 1]
|
491
503
|
s_req.is_path_style = false
|
492
504
|
end
|
493
505
|
|
@@ -550,6 +562,7 @@ module FakeS3
|
|
550
562
|
@hostname = hostname
|
551
563
|
@ssl_cert_path = ssl_cert_path
|
552
564
|
@ssl_key_path = ssl_key_path
|
565
|
+
@cors_options = extra_options[:cors_options] or {}
|
553
566
|
webrick_config = {
|
554
567
|
:BindAddress => @address,
|
555
568
|
:Port => @port
|
@@ -575,7 +588,7 @@ module FakeS3
|
|
575
588
|
end
|
576
589
|
|
577
590
|
def serve
|
578
|
-
@server.mount "/", Servlet, @store, @hostname
|
591
|
+
@server.mount "/", Servlet, @store, @hostname, @cors_options
|
579
592
|
shutdown = proc { @server.shutdown }
|
580
593
|
trap "INT", &shutdown
|
581
594
|
trap "TERM", &shutdown
|
data/lib/fakes3/version.rb
CHANGED
@@ -17,7 +17,7 @@ class AwsSdkV2CommandsTest < Test::Unit::TestCase
|
|
17
17
|
assert_not_nil bucket
|
18
18
|
|
19
19
|
bucket_names = @resource.buckets.map(&:name)
|
20
|
-
|
20
|
+
assert_not_nil bucket_names.index("v2_create_bucket")
|
21
21
|
end
|
22
22
|
|
23
23
|
def test_destroy_bucket
|
@@ -37,6 +37,14 @@ class AwsSdkV2CommandsTest < Test::Unit::TestCase
|
|
37
37
|
assert_equal 'test', object.get.body.string
|
38
38
|
end
|
39
39
|
|
40
|
+
def test_bucket_with_dots
|
41
|
+
bucket = @resource.create_bucket(bucket: 'v2.bucket')
|
42
|
+
object = bucket.object('key')
|
43
|
+
object.put(body: 'test')
|
44
|
+
|
45
|
+
assert_equal 'test', object.get.body.string
|
46
|
+
end
|
47
|
+
|
40
48
|
def test_delete_object
|
41
49
|
object = @bucket.object('exists')
|
42
50
|
object.put(body: 'test')
|
data/test/cli_test.rb
CHANGED
@@ -10,7 +10,7 @@ class CLITest < Test::Unit::TestCase
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def test_quiet_mode
|
13
|
-
script = FakeS3::CLI.new([], :root => '.', :port => 4567, :quiet => true)
|
13
|
+
script = FakeS3::CLI.new([], :root => '.', :port => 4567, :license => 'test', :quiet => true)
|
14
14
|
assert_output('') do
|
15
15
|
script.invoke(:server)
|
16
16
|
end
|
data/test/post_test.rb
CHANGED
@@ -29,6 +29,8 @@ class PostTest < Test::Unit::TestCase
|
|
29
29
|
) { |response|
|
30
30
|
assert_equal(response.code, 303)
|
31
31
|
assert_equal(response.headers[:location], 'http://somewhere.else.com/?foo=bar&bucket=posttest&key=uploads%2F12345%2Fpost_test.rb')
|
32
|
+
# Tests that CORS Headers can be set from command line
|
33
|
+
assert_equal(response.headers[:access_control_allow_headers], 'Authorization, Content-Length, Cache-Control')
|
32
34
|
}
|
33
35
|
end
|
34
36
|
|
@@ -40,6 +42,8 @@ class PostTest < Test::Unit::TestCase
|
|
40
42
|
'file'=>File.new(__FILE__,"rb")
|
41
43
|
) { |response|
|
42
44
|
assert_equal(response.code, 200)
|
45
|
+
# Tests that CORS Headers can be set from command line
|
46
|
+
assert_equal(response.headers[:access_control_allow_headers], 'Authorization, Content-Length, Cache-Control')
|
43
47
|
}
|
44
48
|
end
|
45
49
|
|
@@ -52,6 +56,8 @@ class PostTest < Test::Unit::TestCase
|
|
52
56
|
) { |response|
|
53
57
|
assert_equal(response.code, 201)
|
54
58
|
assert_match(%r{^\<\?xml.*uploads/12345/post_test\.rb}m, response.body)
|
59
|
+
# Tests that CORS Headers can be set from command line
|
60
|
+
assert_equal(response.headers[:access_control_allow_headers], 'Authorization, Content-Length, Cache-Control')
|
55
61
|
}
|
56
62
|
end
|
57
63
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fakes3
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Curtis Spencer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-08-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -249,7 +249,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
249
249
|
version: '0'
|
250
250
|
requirements: []
|
251
251
|
rubyforge_project:
|
252
|
-
rubygems_version: 2.
|
252
|
+
rubygems_version: 2.7.7
|
253
253
|
signing_key:
|
254
254
|
specification_version: 4
|
255
255
|
summary: Fake S3 is a server that simulates Amazon S3 commands so you can test your
|