rack-s3 0.0.4 → 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.
@@ -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"