s3_proxy 0.1.0 → 0.2.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 +4 -4
- data/lib/s3_proxy/app.rb +75 -21
- data/lib/s3_proxy/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b87ae0701382cfcc91e7b233bd68ecef70546677
|
4
|
+
data.tar.gz: 5c6344cbac68b8b9b06b5a032aa9d0db5e4a1821
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 636b2f85af7915558cae9107de37cc2498e961909af4821ca2621bbaa531ad3b2711a01a33b7f00f6053f63faa0a352043807e7956279d6ad80174d3dcd9a79c
|
7
|
+
data.tar.gz: 3f42b9f14ac02405ca8489f76211f01f4e8a1c665f75dbe29463dbb122875f630f43aa0f182d5b4de4836caa4933d0f6dad11260dbd5768178517af80572cb45
|
data/lib/s3_proxy/app.rb
CHANGED
@@ -8,28 +8,60 @@ module S3Proxy
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def call(env)
|
11
|
-
return Errors.method_not_allowed unless env['REQUEST_METHOD']
|
11
|
+
return Errors.method_not_allowed unless %w(GET HEAD).include?(env['REQUEST_METHOD'])
|
12
12
|
return Errors.not_found if env['PATH_INFO'].empty?
|
13
13
|
|
14
|
-
|
15
|
-
|
14
|
+
# When used as a forward proxy
|
15
|
+
if env['HTTP_HOST'] =~ /(.+)\.s3\.amazonaws\.com/
|
16
|
+
bucket = $1
|
17
|
+
_, key = env['PATH_INFO'].split('/', 2)
|
18
|
+
else
|
19
|
+
_, bucket, key = env['PATH_INFO'].split('/', 3)
|
20
|
+
end
|
21
|
+
|
22
|
+
return Errors.not_found unless bucket && key
|
23
|
+
|
24
|
+
req = {bucket: bucket, key: key}
|
25
|
+
|
26
|
+
req[:if_match] = env['HTTP_IF_MATCH'] if env['HTTP_IF_MATCH']
|
27
|
+
req[:if_none_match] = env['HTTP_IF_NONE_MATCH'] if env['HTTP_IF_NONE_MATCH']
|
28
|
+
req[:if_modified_since] = env['HTTP_IF_MODIFIED_SINCE'] if env['HTTP_IF_MODIFIED_SINCE']
|
29
|
+
req[:if_unmodified_since] = env['HTTP_IF_UNMODIFIED_SINCE'] if env['HTTP_UNMODIFIED_SINCE']
|
30
|
+
|
31
|
+
head = s3.head_object(req)
|
16
32
|
|
17
|
-
head = s3.head_object(path)
|
18
33
|
return Errors.not_found unless head
|
19
34
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
35
|
+
case env['REQUEST_METHOD']
|
36
|
+
when 'HEAD'
|
37
|
+
gentle env, req, head
|
38
|
+
when 'GET'
|
39
|
+
if env['rack.hijack?']
|
40
|
+
hijack env, req, head
|
41
|
+
else
|
42
|
+
gentle env, req, head
|
43
|
+
end
|
24
44
|
end
|
25
45
|
|
26
|
-
rescue Aws::S3::Errors::NoSuchKey
|
46
|
+
rescue Aws::S3::Errors::NoSuchKey, Aws::S3::Errors::NotFound
|
27
47
|
return Errors.not_found
|
48
|
+
|
49
|
+
rescue Aws::S3::Errors::NotModified
|
50
|
+
return Errors.not_modified
|
51
|
+
|
52
|
+
rescue Aws::S3::Errors::PreconditionFailed
|
53
|
+
return Errors.precondition_failed
|
54
|
+
|
55
|
+
rescue NameError => e
|
56
|
+
# https://github.com/aws/aws-sdk-core-ruby/pull/65
|
57
|
+
raise e unless e.message == "wrong constant name 412Error"
|
58
|
+
|
59
|
+
return Errors.precondition_failed
|
28
60
|
end
|
29
61
|
|
30
62
|
private
|
31
63
|
|
32
|
-
def hijack(env,
|
64
|
+
def hijack(env, request, head)
|
33
65
|
env['rack.hijack'].call
|
34
66
|
|
35
67
|
io = env['rack.hijack_io']
|
@@ -39,31 +71,45 @@ module S3Proxy
|
|
39
71
|
io.write "Connection: close\r\n"
|
40
72
|
io.write "Content-Type: #{head.content_type}\r\n"
|
41
73
|
io.write "Content-Length: #{head.content_length}\r\n"
|
74
|
+
io.write "ETag: #{head.etag}\r\n"
|
75
|
+
io.write "Last-Modified: #{head.last_modified}\r\n"
|
42
76
|
io.write "\r\n"
|
43
77
|
io.flush
|
44
78
|
|
45
|
-
s3.get_object(
|
79
|
+
s3.get_object(request, target: io)
|
46
80
|
ensure
|
47
81
|
io.close
|
48
82
|
end
|
49
83
|
return [200, {}, ['']]
|
50
84
|
end
|
51
85
|
|
52
|
-
def gentle(env,
|
53
|
-
|
54
|
-
|
55
|
-
|
86
|
+
def gentle(env, request, head)
|
87
|
+
case env['REQUEST_METHOD']
|
88
|
+
when 'GET'
|
89
|
+
fiber = Fiber.new do
|
90
|
+
s3.get_object(request) do |chunk|
|
91
|
+
Fiber.yield(chunk)
|
92
|
+
end
|
93
|
+
Fiber.yield(nil)
|
56
94
|
end
|
57
|
-
Fiber.yield(nil)
|
58
|
-
end
|
59
95
|
|
60
|
-
|
61
|
-
|
62
|
-
|
96
|
+
body = Enumerator.new do |y|
|
97
|
+
while n = fiber.resume
|
98
|
+
y << n
|
99
|
+
end
|
63
100
|
end
|
101
|
+
when 'HEAD'
|
102
|
+
body = ['']
|
64
103
|
end
|
65
104
|
|
66
|
-
|
105
|
+
headers = {
|
106
|
+
'Content-Type' => head.content_type,
|
107
|
+
'Content-Length' => head.content_length.to_s,
|
108
|
+
'Last-Modified' => head.last_modified,
|
109
|
+
'ETag' => head.etag,
|
110
|
+
}
|
111
|
+
|
112
|
+
[200, headers, body]
|
67
113
|
end
|
68
114
|
|
69
115
|
def s3
|
@@ -84,6 +130,14 @@ module S3Proxy
|
|
84
130
|
[403, {'Content-Type' => 'text/plain'}, ["forbidden"]]
|
85
131
|
end
|
86
132
|
|
133
|
+
def precondition_failed
|
134
|
+
[412, {'Content-Type' => 'text/plain'}, ["precondition failed"]]
|
135
|
+
end
|
136
|
+
|
137
|
+
def not_modified
|
138
|
+
[304, {'Content-Type' => 'text/plain'}, ["not modified"]]
|
139
|
+
end
|
140
|
+
|
87
141
|
def unknown(code)
|
88
142
|
[code, {'Content-Type' => 'text/plain'}, ["Error: #{code}"]]
|
89
143
|
end
|
data/lib/s3_proxy/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: s3_proxy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shota Fukumori (sora_h)
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-06-
|
11
|
+
date: 2014-06-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -122,3 +122,4 @@ signing_key:
|
|
122
122
|
specification_version: 4
|
123
123
|
summary: S3 reverse proxy rack app that accepts multiple buckets
|
124
124
|
test_files: []
|
125
|
+
has_rdoc:
|