fakes3 1.2.1 → 1.3.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.
- 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
|