rack-s3 0.0.4 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 7599f69a1cbca17370de913e1655483592c0eb48bbb27ca387f86d76ba9a546a
4
+ data.tar.gz: 686f099029d234af9204bfcd4a92e17d83af0e14f25bb7349912d4352de9fa29
5
+ SHA512:
6
+ metadata.gz: 2069727dfd1766c838962639730e8c06ffaeb9bc9dc71a89f61412d5d0851fc1d7629d477c754ed409721915829643ef8f7e383563bff9966955428d37d4e69a
7
+ data.tar.gz: 55da444e8c76366a8fad36b1605126997502b69720acd28823aee637c457df1fefad1a4bee57c185bf64984c0894b9ecbe5d7148afdd2504a208b66e558aa341
Binary file
Binary file
data/README.md CHANGED
@@ -1,24 +1,24 @@
1
- # Rack::S3
1
+ # Rack S3
2
2
 
3
- Serve files from an S3 bucket as if they were local assets similar to
4
- Rack::Static. Stand up behind Rack::Thumb for fame and notoriety.
3
+ Expose an [S3][s3] bucket prefix as a [Rack][rack] application with streaming.
5
4
 
5
+ ![s3]: https://aws.amazon.com/s3
6
+ ![rack]: https://github.com/rack/rack
6
7
 
7
8
  ## Usage
8
9
 
9
- require 'myapp'
10
- require 'rack/thumb'
11
- require 'rack/s3'
10
+ Specify an S3 URI to mount a bucket and optional prefix:
12
11
 
13
- use Rack::Thumb
14
- use Rack::S3
12
+ ```ruby
13
+ # config.ru
15
14
 
16
- run MyApp.new
15
+ run Rack::S3.new("s3://my-bucket/assets")
16
+ ```
17
17
 
18
+ or, with options:
18
19
 
19
- ## Copyright
20
+ ```ruby
21
+ # config.ru
20
22
 
21
- Copyright (c) 2011 Larry Marburger. See [LICENSE] for details.
22
-
23
-
24
- [LICENSE]: http://github.com/lmarburger/rack-s3/blob/master/LICENSE
23
+ run Rack::S3.new(bucket: "my-app", prefix: "assets", client: Aws::S3::Client.new(...))
24
+ ```
@@ -1,66 +1,117 @@
1
- require 'rack'
2
- require 'aws/s3'
3
- require 'cgi'
1
+ # frozen_string_literal: true
4
2
 
5
- module Rack
6
- class S3
3
+ require "aws-sdk-s3"
4
+ require "rack"
7
5
 
8
- def initialize(options={})
9
- @bucket = options[:bucket]
10
-
11
- establish_aws_connection(options[:access_key_id],
12
- options[:secret_access_key])
6
+ # Serve static s3 content, like Rack::Files
7
+ class Rack::S3
8
+ def initialize(url: nil, bucket: nil, prefix: nil, client: Aws::S3::Client.new)
9
+ if url
10
+ uri = URI.parse(url)
11
+ raise "Not an S3 url" unless uri.scheme == "s3"
12
+ bucket = uri.host
13
+ prefix = uri.path.delete_prefix("/")
13
14
  end
14
15
 
15
- def establish_aws_connection(access_key_id, secret_access_key)
16
- return unless access_key_id && secret_access_key
16
+ prefix = nil if prefix == "" || prefix == "/"
17
17
 
18
- AWS::S3::Base.establish_connection!(
19
- :access_key_id => access_key_id,
20
- :secret_access_key => secret_access_key)
21
- end
18
+ @bucket = bucket
19
+ @prefix = prefix
20
+ @client = client
21
+ end
22
+
23
+ def call(env)
24
+ request = Rack::Request.new(env)
25
+
26
+ # Only allow GET
27
+ return error(405, { "Allow" => "GET" }) unless request.get?
22
28
 
23
- def call(env)
24
- dup._call env
29
+ # Don't allow odd encodings in paths
30
+ path_info = Rack::Utils.unescape_path request.path_info
31
+ return error(400) unless Rack::Utils.valid_path?(path_info)
32
+
33
+ # Redirect when logical uri path ends with a slash, but not really
34
+ # i.e. mount Rack::S3.new(...), at: "blah" # => /blah => /blah/
35
+ if (path_info.nil? || path_info.empty? || path_info.end_with?("/")) && !request.fullpath.end_with?("/")
36
+ return redirect(request.fullpath + "/")
25
37
  end
26
38
 
27
- def _call(env)
28
- @env = env
29
- [ 200, headers, object.value ]
30
- rescue AWS::S3::NoSuchKey
31
- not_found
39
+ # Rails routes with mount "/blah" => Rack::S3.new(...), and a request to
40
+ # "/blah" produces a script_path of "/blah" and path_info of "/". If we
41
+ # serve an index.html at that uri then relative references will not work.
42
+ # So consult the request_path, if we can, to double check.
43
+ if env["REQUEST_PATH"] && request.fullpath.end_with?("/") && !env["REQUEST_PATH"].end_with?("/")
44
+ return redirect(request.fullpath)
32
45
  end
33
46
 
34
- def headers
35
- about = object.about
47
+ # Reject any traversals, etc
48
+ clean_path = Rack::Utils.clean_path_info(path_info)
49
+ return error(400) unless clean_path == path_info
36
50
 
37
- { 'Content-Type' => about['content-type'],
38
- 'Content-Length' => about['content-length'],
39
- 'Etag' => about['etag'],
40
- 'Last-Modified' => about['last-modified']
41
- }
42
- end
51
+ key = path_info.delete_prefix("/")
43
52
 
44
- def path_info
45
- CGI.unescape @env['PATH_INFO']
53
+ key = "#{@prefix}/#{key}" if @prefix
54
+
55
+ # Basic index file support
56
+ if key.empty? || key.end_with?("/")
57
+ key << "index.html"
46
58
  end
47
59
 
48
- def path
49
- path_info[0...1] == '/' ? path_info[1..-1] : path_info
60
+ # It would be nice to only head the object if we need to (if modified
61
+ # since, etc), but aws-sdk-s3 doesn't expose a nice way to get an object,
62
+ # use its response headers, and then stream the body -- you can only
63
+ # receive a response with a buffered body, or stream the body before
64
+ # getting the headers.
65
+ head = @client.head_object(bucket: @bucket, key: key)
66
+
67
+ etag = head.etag
68
+ if none_match = request.get_header("HTTP_IF_NONE_MATCH")
69
+ return not_modified if none_match == etag
50
70
  end
51
71
 
52
- def object
53
- @object ||= AWS::S3::S3Object.find(path, @bucket)
72
+ last_modified = head.last_modified.httpdate
73
+ if modified_since = request.get_header("HTTP_IF_MODIFIED_SINCE")
74
+ return not_modified if modified_since == last_modified
54
75
  end
55
76
 
56
- def not_found
57
- body = "File not found: #{ path_info }\n"
77
+ headers = {
78
+ "Content-Length" => head.content_length.to_s,
79
+ "Content-Type" => head.content_type,
80
+ "ETag" => etag,
81
+ "Last-Modified" => last_modified,
82
+ }
58
83
 
59
- [ 404,
60
- { 'Content-Type' => "text/plain",
61
- 'Content-Length' => body.size.to_s },
62
- [ body ]]
84
+ body = Enumerator.new do |enum|
85
+ @client.get_object(bucket: @bucket, key: key) do |chunk|
86
+ enum.yield chunk
87
+ end
63
88
  end
64
89
 
90
+ [200, headers, body]
91
+ rescue Aws::S3::Errors::Forbidden
92
+ error(403)
93
+ rescue Aws::S3::Errors::NotFound
94
+ error(404)
95
+ end
96
+
97
+ private
98
+
99
+ def redirect(location)
100
+ [302, { "Location" => location }, []]
101
+ end
102
+
103
+ def not_modified
104
+ [304, {}, []]
105
+ end
106
+
107
+ def error(status, headers = {})
108
+ body = Rack::Utils::HTTP_STATUS_CODES.fetch(status)
109
+
110
+ headers = {
111
+ "Content-Type" => "text/plain",
112
+ "Content-Length" => body.size.to_s,
113
+ }.merge!(headers)
114
+
115
+ [status, headers, [body]]
65
116
  end
66
117
  end
metadata CHANGED
@@ -1,156 +1,165 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: rack-s3
3
- version: !ruby/object:Gem::Version
4
- hash: 23
5
- prerelease:
6
- segments:
7
- - 0
8
- - 0
9
- - 4
10
- version: 0.0.4
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
11
5
  platform: ruby
12
- authors:
6
+ authors:
13
7
  - Larry Marburger
14
- autorequire:
8
+ - Samuel Cochran
9
+ autorequire:
15
10
  bindir: bin
16
- cert_chain: []
17
-
18
- date: 2011-01-28 00:00:00 -05:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
22
- name: aws-s3
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
25
- none: false
26
- requirements:
11
+ cert_chain:
12
+ - |
13
+ -----BEGIN CERTIFICATE-----
14
+ MIIDKDCCAhCgAwIBAgIBBzANBgkqhkiG9w0BAQsFADA6MQ0wCwYDVQQDDARzajI2
15
+ MRQwEgYKCZImiZPyLGQBGRYEc2oyNjETMBEGCgmSJomT8ixkARkWA2NvbTAeFw0x
16
+ OTEwMjQwNjM0MjJaFw0yMDEwMjMwNjM0MjJaMDoxDTALBgNVBAMMBHNqMjYxFDAS
17
+ BgoJkiaJk/IsZAEZFgRzajI2MRMwEQYKCZImiZPyLGQBGRYDY29tMIIBIjANBgkq
18
+ hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsr60Eo/ttCk8GMTMFiPr3GoYMIMFvLak
19
+ xSmTk9YGCB6UiEePB4THSSA5w6IPyeaCF/nWkDp3/BAam0eZMWG1IzYQB23TqIM0
20
+ 1xzcNRvFsn0aQoQ00k+sj+G83j3T5OOV5OZIlu8xAChMkQmiPd1NXc6uFv+Iacz7
21
+ kj+CMsI9YUFdNoU09QY0b+u+Rb6wDYdpyvN60YC30h0h1MeYbvYZJx/iZK4XY5zu
22
+ 4O/FL2ChjL2CPCpLZW55ShYyrzphWJwLOJe+FJ/ZBl6YXwrzQM9HKnt4titSNvyU
23
+ KzE3L63A3PZvExzLrN9u09kuWLLJfXB2sGOlw3n9t72rJiuBr3/OQQIDAQABozkw
24
+ NzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQU99dfRjEKFyczTeIz
25
+ m3ZsDWrNC80wDQYJKoZIhvcNAQELBQADggEBAI06Bv7coqIflKtxRIwIJABl3hRR
26
+ fZ2U0C1T16VXGwGdxRyDJHYt/2aMDfS/bpDzqR0ela2dwTh/29/oZQeAtzbQq6dE
27
+ 7Pax2oYi+dahcreJFndcA6P/dl03XLNVIFVDtfEHvcUjtKKWQALAWirmW7KGAW1R
28
+ Xn1uy1RJ0TzazCY059p0UQwLU1KXz/5NnTrGka/GvKjLTjk67T6Y05lmr7TxMY2w
29
+ cTRkS42ilkarelc4DnSSO5jw7qFq7Cmf6F9hMx3xdoSWpLf+FvXJRbYrqwZIsmME
30
+ V8zEtJFhdNOFOdtcTE67qh/aYQe2y/LDnG9ywXHWdSeF4UUjg1WRt8s3OP8=
31
+ -----END CERTIFICATE-----
32
+ date: 2020-09-08 00:00:00.000000000 Z
33
+ dependencies:
34
+ - !ruby/object:Gem::Dependency
35
+ name: rack
36
+ requirement: !ruby/object:Gem::Requirement
37
+ requirements:
27
38
  - - ">="
28
- - !ruby/object:Gem::Version
29
- hash: 3
30
- segments:
31
- - 0
32
- version: "0"
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
33
41
  type: :runtime
34
- version_requirements: *id001
35
- - !ruby/object:Gem::Dependency
36
- name: rack
37
42
  prerelease: false
38
- requirement: &id002 !ruby/object:Gem::Requirement
39
- none: false
40
- requirements:
43
+ version_requirements: !ruby/object:Gem::Requirement
44
+ requirements:
41
45
  - - ">="
42
- - !ruby/object:Gem::Version
43
- hash: 3
44
- segments:
45
- - 0
46
- version: "0"
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ - !ruby/object:Gem::Dependency
49
+ name: aws-sdk-s3
50
+ requirement: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
47
55
  type: :runtime
48
- version_requirements: *id002
49
- - !ruby/object:Gem::Dependency
50
- name: shoulda
51
56
  prerelease: false
52
- requirement: &id003 !ruby/object:Gem::Requirement
53
- none: false
54
- requirements:
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rake
64
+ requirement: !ruby/object:Gem::Requirement
65
+ requirements:
55
66
  - - ">="
56
- - !ruby/object:Gem::Version
57
- hash: 3
58
- segments:
59
- - 0
60
- version: "0"
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
61
69
  type: :development
62
- version_requirements: *id003
63
- - !ruby/object:Gem::Dependency
64
- name: webmock
65
70
  prerelease: false
66
- requirement: &id004 !ruby/object:Gem::Requirement
67
- none: false
68
- requirements:
71
+ version_requirements: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ - !ruby/object:Gem::Dependency
77
+ name: rspec
78
+ requirement: !ruby/object:Gem::Requirement
79
+ requirements:
69
80
  - - ">="
70
- - !ruby/object:Gem::Version
71
- hash: 3
72
- segments:
73
- - 0
74
- version: "0"
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
75
83
  type: :development
76
- version_requirements: *id004
77
- - !ruby/object:Gem::Dependency
84
+ prerelease: false
85
+ version_requirements: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ - !ruby/object:Gem::Dependency
91
+ name: rack-test
92
+ requirement: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ type: :development
98
+ prerelease: false
99
+ version_requirements: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ - !ruby/object:Gem::Dependency
78
105
  name: vcr
106
+ requirement: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ type: :development
79
112
  prerelease: false
80
- requirement: &id005 !ruby/object:Gem::Requirement
81
- none: false
82
- requirements:
113
+ version_requirements: !ruby/object:Gem::Requirement
114
+ requirements:
83
115
  - - ">="
84
- - !ruby/object:Gem::Version
85
- hash: 3
86
- segments:
87
- - 0
88
- version: "0"
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ - !ruby/object:Gem::Dependency
119
+ name: webmock
120
+ requirement: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
89
125
  type: :development
90
- version_requirements: *id005
91
- description: Serve files from an S3 bucket as if they were local assets similar to Rack::Static.
92
- email:
126
+ prerelease: false
127
+ version_requirements: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ description:
133
+ email:
93
134
  - larry@marburger.cc
135
+ - sj26@sj26.com
94
136
  executables: []
95
-
96
137
  extensions: []
97
-
98
138
  extra_rdoc_files: []
99
-
100
- files:
101
- - .gitignore
102
- - Gemfile
103
- - Gemfile.lock
139
+ files:
104
140
  - LICENSE
105
141
  - README.md
106
- - Rakefile
107
142
  - lib/rack/s3.rb
108
- - lib/rack/s3/version.rb
109
- - rack-s3.gemspec
110
- - test/rack_s3_test.rb
111
- - test/test_helper.rb
112
- - test/vcr_cassettes/clear.yml
113
- - test/vcr_cassettes/key_with_spaces.yml
114
- - test/vcr_cassettes/nested_clear.yml
115
- - test/vcr_cassettes/not_found.yml
116
- has_rdoc: true
117
- homepage: http://developmentastic.com
143
+ homepage: https://github.com/sj26/rack-s3
118
144
  licenses: []
119
-
120
- post_install_message:
145
+ metadata: {}
146
+ post_install_message:
121
147
  rdoc_options: []
122
-
123
- require_paths:
148
+ require_paths:
124
149
  - lib
125
- required_ruby_version: !ruby/object:Gem::Requirement
126
- none: false
127
- requirements:
150
+ required_ruby_version: !ruby/object:Gem::Requirement
151
+ requirements:
128
152
  - - ">="
129
- - !ruby/object:Gem::Version
130
- hash: 3
131
- segments:
132
- - 0
133
- version: "0"
134
- required_rubygems_version: !ruby/object:Gem::Requirement
135
- none: false
136
- requirements:
153
+ - !ruby/object:Gem::Version
154
+ version: '0'
155
+ required_rubygems_version: !ruby/object:Gem::Requirement
156
+ requirements:
137
157
  - - ">="
138
- - !ruby/object:Gem::Version
139
- hash: 3
140
- segments:
141
- - 0
142
- version: "0"
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
143
160
  requirements: []
144
-
145
- rubyforge_project:
146
- rubygems_version: 1.4.1
147
- signing_key:
148
- specification_version: 3
149
- summary: A Rack::Static like middleware for serving assets from S3
150
- test_files:
151
- - test/rack_s3_test.rb
152
- - test/test_helper.rb
153
- - test/vcr_cassettes/clear.yml
154
- - test/vcr_cassettes/key_with_spaces.yml
155
- - test/vcr_cassettes/nested_clear.yml
156
- - test/vcr_cassettes/not_found.yml
161
+ rubygems_version: 3.1.4
162
+ signing_key:
163
+ specification_version: 4
164
+ summary: Serve static files from S3 via Rack
165
+ test_files: []
@@ -0,0 +1 @@
1
+ G��ĥ��iH�hH�� �}�{d�f^��M��П����_�YDd\� Q��+�7\�?��;��������-�}�����ڈ�*M���������܌^d%��4�p`�:�D Y�?�6ر�@��M�X-��:㊝��:�dwJTe-@���x5G3L<Л����S�J�8�j�D��~QM_��cG�O�I6�յ1r���5T���[�P"|_�^\�?g�|-���b�`98�� 4�{
data/.gitignore DELETED
@@ -1,3 +0,0 @@
1
- pkg/*
2
- *.gem
3
- .bundle
data/Gemfile DELETED
@@ -1,4 +0,0 @@
1
- source "http://rubygems.org"
2
-
3
- # Specify your gem's dependencies in rack-s3.gemspec
4
- gemspec
@@ -1,34 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- rack-s3 (0.0.4)
5
- aws-s3
6
- rack
7
-
8
- GEM
9
- remote: http://rubygems.org/
10
- specs:
11
- addressable (2.2.3)
12
- aws-s3 (0.6.2)
13
- builder
14
- mime-types
15
- xml-simple
16
- builder (3.0.0)
17
- crack (0.1.8)
18
- mime-types (1.16)
19
- rack (1.2.1)
20
- shoulda (2.11.3)
21
- vcr (1.5.1)
22
- webmock (1.6.2)
23
- addressable (>= 2.2.2)
24
- crack (>= 0.1.7)
25
- xml-simple (1.0.14)
26
-
27
- PLATFORMS
28
- ruby
29
-
30
- DEPENDENCIES
31
- rack-s3!
32
- shoulda
33
- vcr
34
- webmock
data/Rakefile DELETED
@@ -1,13 +0,0 @@
1
- require 'bundler'
2
- require 'rake/testtask'
3
-
4
- Bundler::GemHelper.install_tasks
5
-
6
- Rake::TestTask.new('test') do |t|
7
- t.libs << 'test'
8
- t.pattern = 'test/*_test.rb'
9
- t.verbose = true
10
- end
11
-
12
- desc 'Default: run tests'
13
- task :default => 'test'
@@ -1,5 +0,0 @@
1
- module Rack
2
- class S3
3
- VERSION = "0.0.4"
4
- end
5
- end
@@ -1,26 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
3
- require "rack/s3/version"
4
-
5
- Gem::Specification.new do |s|
6
- s.name = "rack-s3"
7
- s.version = Rack::S3::VERSION
8
- s.platform = Gem::Platform::RUBY
9
- s.authors = ["Larry Marburger"]
10
- s.email = ["larry@marburger.cc"]
11
- s.homepage = "http://developmentastic.com"
12
- s.summary = %q{A Rack::Static like middleware for serving assets from S3}
13
- s.description = %q{Serve files from an S3 bucket as if they were local assets similar to Rack::Static.}
14
-
15
- s.add_dependency 'aws-s3'
16
- s.add_dependency 'rack'
17
-
18
- s.add_development_dependency 'shoulda'
19
- s.add_development_dependency 'webmock'
20
- s.add_development_dependency 'vcr'
21
-
22
- s.files = `git ls-files`.split("\n")
23
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
24
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
25
- s.require_paths = ["lib"]
26
- end
@@ -1,115 +0,0 @@
1
- require 'test_helper'
2
-
3
- class RackS3Test < Test::Unit::TestCase
4
-
5
- def mock_request(path)
6
- Rack::MockRequest.new(app).get path, :lint => true
7
- end
8
-
9
- def app
10
- Rack::S3.new :bucket => 'rack-s3',
11
- :access_key_id => 'abc123',
12
- :secret_access_key => 'abc123'
13
- end
14
-
15
- def teardown
16
- AWS::S3::Base.disconnect!
17
- end
18
-
19
-
20
- context 'A request for a nonexistent key' do
21
- subject do
22
- VCR.use_cassette 'not_found' do
23
- mock_request '/not_found.png'
24
- end
25
- end
26
-
27
- should 'render a not found response' do
28
- assert_equal 404, subject.status
29
- assert_equal "File not found: /not_found.png\n", subject.body
30
-
31
- assert_equal 'text/plain', subject.headers['Content-Type']
32
- assert_equal '31', subject.headers['Content-Length']
33
- end
34
- end
35
-
36
- context 'A request for a key' do
37
- subject do
38
- VCR.use_cassette 'clear' do
39
- mock_request '/clear.png'
40
- end
41
- end
42
-
43
- should 'render the file' do
44
- assert_equal 200, subject.status
45
- assert_not_nil subject.body
46
-
47
- %w(Content-Type Last-Modified Last-Modified Etag).each do |header|
48
- assert_not_nil subject.headers[header]
49
- end
50
- end
51
- end
52
-
53
- context 'A request for a nested key' do
54
- subject do
55
- VCR.use_cassette 'nested_clear' do
56
- mock_request '/very/important/files/clear.png'
57
- end
58
- end
59
-
60
- should 'render the file' do
61
- assert_equal 200, subject.status
62
- assert_not_nil subject.body
63
-
64
- %w(Content-Type Last-Modified Last-Modified Etag).each do |header|
65
- assert_not_nil subject.headers[header]
66
- end
67
- end
68
- end
69
-
70
- context 'A request for a key containing spaces' do
71
- subject do
72
- VCR.use_cassette 'key_with_spaces' do
73
- mock_request '/key%20with%20spaces.png'
74
- end
75
- end
76
-
77
- should 'render the file' do
78
- assert_equal 200, subject.status
79
- end
80
- end
81
-
82
- context 'A request to a mapped app' do
83
- subject do
84
- VCR.use_cassette 'clear' do
85
- unmapped_app = app
86
- mapped_app = Rack::Builder.new do
87
- map '/mapped/app' do
88
- run unmapped_app
89
- end
90
- end
91
-
92
- Rack::MockRequest.new(mapped_app).get '/mapped/app/clear.png'
93
- end
94
- end
95
-
96
- should 'render the file' do
97
- assert_equal 200, subject.status
98
- end
99
- end
100
-
101
- context 'Without AWS credentials' do
102
- subject do
103
- app = Rack::S3.new :bucket => 'rack-s3'
104
-
105
- Rack::MockRequest.new(app).get '/clear.png'
106
- end
107
-
108
- should 'not attempt to establish a connection to AWS' do
109
- assert_raise AWS::S3::NoConnectionEstablished do
110
- subject
111
- end
112
- end
113
- end
114
-
115
- end
@@ -1,18 +0,0 @@
1
- require 'rubygems'
2
- require 'test/unit'
3
-
4
- require 'bundler/setup'
5
- Bundler.require :development
6
-
7
- require 'rack/mock'
8
- require 'rack/s3'
9
-
10
- class Test::Unit::TestCase
11
-
12
- VCR.config do |c|
13
- c.cassette_library_dir = 'test/vcr_cassettes'
14
- c.stub_with :webmock
15
- c.default_cassette_options = { :record => :none }
16
- end
17
-
18
- end
@@ -1,94 +0,0 @@
1
- ---
2
- - !ruby/struct:VCR::HTTPInteraction
3
- request: !ruby/struct:VCR::Request
4
- method: :get
5
- uri: http://s3.amazonaws.com:80/rack-s3?marker=clear.pnf&max-keys=1
6
- body:
7
- headers:
8
- response: !ruby/struct:VCR::Response
9
- status: !ruby/struct:VCR::ResponseStatus
10
- code: 200
11
- message: OK
12
- headers:
13
- x-amz-id-2:
14
- - iIjcmkNXzlg1zNQXmrO+gglqBmJR6znWyQf3nBwiRgfxIaLhCJDzIySgjoCQPhm2
15
- content-type:
16
- - application/xml
17
- server:
18
- - AmazonS3
19
- date:
20
- - Tue, 25 Jan 2011 21:06:13 GMT
21
- x-amz-request-id:
22
- - AAAAAAAAAAAAAAAA
23
- transfer-encoding:
24
- - chunked
25
- body: |-
26
- <?xml version="1.0" encoding="UTF-8"?>
27
- <ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Name>rack-s3</Name><Prefix></Prefix><Marker>clear.pnf</Marker><MaxKeys>1</MaxKeys><IsTruncated>true</IsTruncated><Contents><Key>clear.png</Key><LastModified>2011-01-22T01:40:19.000Z</LastModified><ETag>&quot;71a50dbba44c78128b221b7df7bb51f1&quot;</ETag><Size>95</Size><Owner><ID>abc123</ID><DisplayName>rack-s3</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents></ListBucketResult>
28
- http_version: "1.1"
29
- - !ruby/struct:VCR::HTTPInteraction
30
- request: !ruby/struct:VCR::Request
31
- method: :head
32
- uri: http://s3.amazonaws.com:80/rack-s3/clear.png
33
- body:
34
- headers:
35
- response: !ruby/struct:VCR::Response
36
- status: !ruby/struct:VCR::ResponseStatus
37
- code: 200
38
- message: OK
39
- headers:
40
- etag:
41
- - "\"71a50dbba44c78128b221b7df7bb51f1\""
42
- last-modified:
43
- - Sat, 22 Jan 2011 01:40:19 GMT
44
- x-amz-id-2:
45
- - 5DNVaHC4B0cbQqBc10aCulfozqKEpJPLo6SNcBcFRkZLD4+cZRNY9TBXe5KLEJDK
46
- content-type:
47
- - image/png
48
- server:
49
- - AmazonS3
50
- date:
51
- - Tue, 25 Jan 2011 21:06:13 GMT
52
- content-length:
53
- - "95"
54
- x-amz-request-id:
55
- - BBBBBBBBBBBBBBBB
56
- accept-ranges:
57
- - bytes
58
- body:
59
- http_version: "1.1"
60
- - !ruby/struct:VCR::HTTPInteraction
61
- request: !ruby/struct:VCR::Request
62
- method: :get
63
- uri: http://s3.amazonaws.com:80/rack-s3/clear.png
64
- body:
65
- headers:
66
- response: !ruby/struct:VCR::Response
67
- status: !ruby/struct:VCR::ResponseStatus
68
- code: 200
69
- message: OK
70
- headers:
71
- etag:
72
- - "\"71a50dbba44c78128b221b7df7bb51f1\""
73
- last-modified:
74
- - Sat, 22 Jan 2011 01:40:19 GMT
75
- x-amz-id-2:
76
- - VHSXty5O3M9vnhiRRL3OzbCfrNIB2BA35K4DtJ9AIO5UXeYHHTmDTzCjYVUTi3XF
77
- content-type:
78
- - image/png
79
- server:
80
- - AmazonS3
81
- date:
82
- - Tue, 25 Jan 2011 21:06:13 GMT
83
- content-length:
84
- - "95"
85
- x-amz-request-id:
86
- - CCCCCCCCCCCCCCCC
87
- accept-ranges:
88
- - bytes
89
- body: !binary |
90
- iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAACn
91
- ej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVO
92
- RK5CYII=
93
-
94
- http_version: "1.1"
@@ -1,94 +0,0 @@
1
- ---
2
- - !ruby/struct:VCR::HTTPInteraction
3
- request: !ruby/struct:VCR::Request
4
- method: :get
5
- uri: http://s3.amazonaws.com:80/rack-s3?marker=key%20with%20spaces.pnf&max-keys=1
6
- body:
7
- headers:
8
- response: !ruby/struct:VCR::Response
9
- status: !ruby/struct:VCR::ResponseStatus
10
- code: 200
11
- message: OK
12
- headers:
13
- x-amz-id-2:
14
- - pOjjAQ3Dsd3tKoFG9Hg0tK81Incbd243yIOLFMGsI5NBIvshC/drTCXkvhjEM9Iq
15
- content-type:
16
- - application/xml
17
- server:
18
- - AmazonS3
19
- date:
20
- - Fri, 28 Jan 2011 15:54:02 GMT
21
- x-amz-request-id:
22
- - C8D0513081C9FC43
23
- transfer-encoding:
24
- - chunked
25
- body: |-
26
- <?xml version="1.0" encoding="UTF-8"?>
27
- <ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Name>rack-s3</Name><Prefix></Prefix><Marker>key with spaces.pnf</Marker><MaxKeys>1</MaxKeys><IsTruncated>true</IsTruncated><Contents><Key>key with spaces.png</Key><LastModified>2011-01-28T15:44:27.000Z</LastModified><ETag>&quot;71a50dbba44c78128b221b7df7bb51f1&quot;</ETag><Size>95</Size><Owner><ID>abc123</ID><DisplayName>rack-s3</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents></ListBucketResult>
28
- http_version: "1.1"
29
- - !ruby/struct:VCR::HTTPInteraction
30
- request: !ruby/struct:VCR::Request
31
- method: :head
32
- uri: http://s3.amazonaws.com:80/rack-s3/key%20with%20spaces.png
33
- body:
34
- headers:
35
- response: !ruby/struct:VCR::Response
36
- status: !ruby/struct:VCR::ResponseStatus
37
- code: 200
38
- message: OK
39
- headers:
40
- etag:
41
- - "\"71a50dbba44c78128b221b7df7bb51f1\""
42
- last-modified:
43
- - Fri, 28 Jan 2011 15:44:27 GMT
44
- x-amz-id-2:
45
- - o6jvTK19hfPEaaUW22trSeS3+PB6FezxvxkQCWSpGmIO3lu/wtkPY1yyX3Ao7QGT
46
- content-type:
47
- - image/png
48
- server:
49
- - AmazonS3
50
- date:
51
- - Fri, 28 Jan 2011 15:54:03 GMT
52
- content-length:
53
- - "95"
54
- x-amz-request-id:
55
- - 9DB4B86707E5AD05
56
- accept-ranges:
57
- - bytes
58
- body:
59
- http_version: "1.1"
60
- - !ruby/struct:VCR::HTTPInteraction
61
- request: !ruby/struct:VCR::Request
62
- method: :get
63
- uri: http://s3.amazonaws.com:80/rack-s3/key%20with%20spaces.png
64
- body:
65
- headers:
66
- response: !ruby/struct:VCR::Response
67
- status: !ruby/struct:VCR::ResponseStatus
68
- code: 200
69
- message: OK
70
- headers:
71
- etag:
72
- - "\"71a50dbba44c78128b221b7df7bb51f1\""
73
- last-modified:
74
- - Fri, 28 Jan 2011 15:44:27 GMT
75
- x-amz-id-2:
76
- - e21vM8iCkWJlB3vRiaG2V9uXWC5fJEmqPCChC0XvwwfOagz8NGjeUMEM7IW24r+c
77
- content-type:
78
- - image/png
79
- server:
80
- - AmazonS3
81
- date:
82
- - Fri, 28 Jan 2011 15:54:03 GMT
83
- content-length:
84
- - "95"
85
- x-amz-request-id:
86
- - E5EF8520D4E7D879
87
- accept-ranges:
88
- - bytes
89
- body: !binary |
90
- iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAACn
91
- ej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVO
92
- RK5CYII=
93
-
94
- http_version: "1.1"
@@ -1,94 +0,0 @@
1
- ---
2
- - !ruby/struct:VCR::HTTPInteraction
3
- request: !ruby/struct:VCR::Request
4
- method: :get
5
- uri: http://s3.amazonaws.com:80/rack-s3?marker=very/important/files/clear.pnf&max-keys=1
6
- body:
7
- headers:
8
- response: !ruby/struct:VCR::Response
9
- status: !ruby/struct:VCR::ResponseStatus
10
- code: 200
11
- message: OK
12
- headers:
13
- x-amz-id-2:
14
- - ffuJcBHfzAJ8xBN78wtnMwkXLLIxj9jOhV9AN0ShCLRpsiZVgKbWGts58jNTWj2A
15
- content-type:
16
- - application/xml
17
- server:
18
- - AmazonS3
19
- date:
20
- - Tue, 25 Jan 2011 21:34:08 GMT
21
- x-amz-request-id:
22
- - FEFB96BBB722B0FA
23
- transfer-encoding:
24
- - chunked
25
- body: |-
26
- <?xml version="1.0" encoding="UTF-8"?>
27
- <ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Name>rack-s3</Name><Prefix></Prefix><Marker>very/important/files/clear.pnf</Marker><MaxKeys>1</MaxKeys><IsTruncated>false</IsTruncated><Contents><Key>very/important/files/clear.png</Key><LastModified>2011-01-25T21:26:16.000Z</LastModified><ETag>&quot;71a50dbba44c78128b221b7df7bb51f1&quot;</ETag><Size>95</Size><Owner><ID>abc123</ID><DisplayName>rack-s3</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents></ListBucketResult>
28
- http_version: "1.1"
29
- - !ruby/struct:VCR::HTTPInteraction
30
- request: !ruby/struct:VCR::Request
31
- method: :head
32
- uri: http://s3.amazonaws.com:80/rack-s3/very/important/files/clear.png
33
- body:
34
- headers:
35
- response: !ruby/struct:VCR::Response
36
- status: !ruby/struct:VCR::ResponseStatus
37
- code: 200
38
- message: OK
39
- headers:
40
- etag:
41
- - "\"71a50dbba44c78128b221b7df7bb51f1\""
42
- last-modified:
43
- - Tue, 25 Jan 2011 21:26:16 GMT
44
- x-amz-id-2:
45
- - lbRqqCOq4dt4LICQKxbE+zWaayYw3+4A+8RjijAYIe9uW+NgeEDRdsDo9bTJcIoC
46
- content-type:
47
- - image/png
48
- server:
49
- - AmazonS3
50
- date:
51
- - Tue, 25 Jan 2011 21:34:08 GMT
52
- content-length:
53
- - "95"
54
- x-amz-request-id:
55
- - 5E4F5037D17C276D
56
- accept-ranges:
57
- - bytes
58
- body:
59
- http_version: "1.1"
60
- - !ruby/struct:VCR::HTTPInteraction
61
- request: !ruby/struct:VCR::Request
62
- method: :get
63
- uri: http://s3.amazonaws.com:80/rack-s3/very/important/files/clear.png
64
- body:
65
- headers:
66
- response: !ruby/struct:VCR::Response
67
- status: !ruby/struct:VCR::ResponseStatus
68
- code: 200
69
- message: OK
70
- headers:
71
- etag:
72
- - "\"71a50dbba44c78128b221b7df7bb51f1\""
73
- last-modified:
74
- - Tue, 25 Jan 2011 21:26:16 GMT
75
- x-amz-id-2:
76
- - QYMU8xe/VbyO0TOaBIjxdekTAiPd47sWRFg+GfKwD7QweTyEouln1W/7hDj3F1cr
77
- content-type:
78
- - image/png
79
- server:
80
- - AmazonS3
81
- date:
82
- - Tue, 25 Jan 2011 21:34:09 GMT
83
- content-length:
84
- - "95"
85
- x-amz-request-id:
86
- - 0BCD2B062BA0FAD6
87
- accept-ranges:
88
- - bytes
89
- body: !binary |
90
- iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAACn
91
- ej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVO
92
- RK5CYII=
93
-
94
- http_version: "1.1"
@@ -1,28 +0,0 @@
1
- ---
2
- - !ruby/struct:VCR::HTTPInteraction
3
- request: !ruby/struct:VCR::Request
4
- method: :get
5
- uri: http://s3.amazonaws.com:80/rack-s3?marker=not_found.pnf&max-keys=1
6
- body:
7
- headers:
8
- response: !ruby/struct:VCR::Response
9
- status: !ruby/struct:VCR::ResponseStatus
10
- code: 200
11
- message: OK
12
- headers:
13
- x-amz-id-2:
14
- - abc123
15
- content-type:
16
- - application/xml
17
- server:
18
- - AmazonS3
19
- date:
20
- - Tue, 25 Jan 2011 20:56:58 GMT
21
- x-amz-request-id:
22
- - abc123
23
- transfer-encoding:
24
- - chunked
25
- body: |-
26
- <?xml version="1.0" encoding="UTF-8"?>
27
- <ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Name>rack-s3</Name><Prefix></Prefix><Marker>not_found.pnf</Marker><MaxKeys>1</MaxKeys><IsTruncated>false</IsTruncated><Contents><Key>test.png</Key><LastModified>2011-01-22T02:59:53.000Z</LastModified><ETag>&quot;71a50dbba44c78128b221b7df7bb51f1&quot;</ETag><Size>47173</Size><Owner><ID>abc123</ID><DisplayName>rack-s3</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents></ListBucketResult>
28
- http_version: "1.1"