fog 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/fog.gemspec +2 -2
- data/lib/fog/aws/requests/s3/get_bucket.rb +6 -0
- data/lib/fog/aws/requests/s3/get_object.rb +15 -2
- data/lib/fog/aws/requests/s3/put_object.rb +10 -10
- data/lib/fog/aws/requests/simpledb/batch_put_attributes.rb +7 -6
- data/lib/fog/aws/requests/simpledb/create_domain.rb +1 -1
- data/lib/fog/aws/requests/simpledb/delete_attributes.rb +68 -30
- data/lib/fog/aws/requests/simpledb/domain_metadata.rb +75 -25
- data/lib/fog/aws/requests/simpledb/get_attributes.rb +70 -30
- data/lib/fog/aws/requests/simpledb/put_attributes.rb +42 -24
- data/lib/fog/aws/s3.rb +13 -8
- data/lib/fog/connection.rb +27 -5
- data/spec/aws/requests/s3/get_object_spec.rb +9 -0
- metadata +2 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.6
|
data/fog.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{fog}
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.6"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Wesley Beary"]
|
12
|
-
s.date = %q{2009-09-
|
12
|
+
s.date = %q{2009-09-09}
|
13
13
|
s.description = %q{brings clouds to you}
|
14
14
|
s.email = %q{me@geemus.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -34,6 +34,9 @@ unless Fog.mocking?
|
|
34
34
|
# * 'Size'<~Integer> - Size of object
|
35
35
|
# * 'StorageClass'<~String> - Storage class of object
|
36
36
|
def get_bucket(bucket_name, options = {})
|
37
|
+
unless bucket_name
|
38
|
+
raise ArgumentError.new('bucket_name is required')
|
39
|
+
end
|
37
40
|
query = ''
|
38
41
|
for key, value in options
|
39
42
|
query << "#{key}=#{value};"
|
@@ -61,6 +64,9 @@ else
|
|
61
64
|
|
62
65
|
# FIXME: implement delimiter
|
63
66
|
def get_bucket(bucket_name, options = {})
|
67
|
+
unless bucket_name
|
68
|
+
raise ArgumentError.new('bucket_name is required')
|
69
|
+
end
|
64
70
|
response = Fog::Response.new
|
65
71
|
if bucket = Fog::AWS::S3.data[:buckets][bucket_name]
|
66
72
|
response.status = 200
|
@@ -23,7 +23,13 @@ unless Fog.mocking?
|
|
23
23
|
# * 'Content-Type'<~String> - MIME type of object
|
24
24
|
# * 'ETag'<~String> - Etag of object
|
25
25
|
# * 'Last-Modified'<~String> - Last modified timestamp for object
|
26
|
-
def get_object(bucket_name, object_name, options = {})
|
26
|
+
def get_object(bucket_name, object_name, options = {}, &block)
|
27
|
+
unless bucket_name
|
28
|
+
raise ArgumentError.new('bucket_name is required')
|
29
|
+
end
|
30
|
+
unless object_name
|
31
|
+
raise ArgumentError.new('object_name is required')
|
32
|
+
end
|
27
33
|
headers = {}
|
28
34
|
headers['If-Modified-Since'] = options['If-Modified-Since'].utc.strftime("%a, %d %b %Y %H:%M:%S +0000") if options['If-Modified-Since']
|
29
35
|
headers['If-Unmodified-Since'] = options['If-Unmodified-Since'].utc.strftime("%a, %d %b %Y %H:%M:%S +0000") if options['If-Modified-Since']
|
@@ -33,7 +39,8 @@ unless Fog.mocking?
|
|
33
39
|
:headers => headers,
|
34
40
|
:host => "#{bucket_name}.#{@host}",
|
35
41
|
:method => 'GET',
|
36
|
-
:path => object_name
|
42
|
+
:path => object_name,
|
43
|
+
:block => block
|
37
44
|
})
|
38
45
|
end
|
39
46
|
|
@@ -48,6 +55,12 @@ else
|
|
48
55
|
class S3
|
49
56
|
|
50
57
|
def get_object(bucket_name, object_name, options = {})
|
58
|
+
unless bucket_name
|
59
|
+
raise ArgumentError.new('bucket_name is required')
|
60
|
+
end
|
61
|
+
unless object_name
|
62
|
+
raise ArgumentError.new('object_name is required')
|
63
|
+
end
|
51
64
|
response = Fog::Response.new
|
52
65
|
if (bucket = Fog::AWS::S3.data[:buckets][bucket_name]) && (object = bucket[:objects][object_name])
|
53
66
|
if options['If-Match'] && options['If-Match'] != object['ETag']
|
@@ -9,7 +9,7 @@ unless Fog.mocking?
|
|
9
9
|
# ==== Parameters
|
10
10
|
# * bucket_name<~String> - Name of bucket to create object in
|
11
11
|
# * object_name<~String> - Name of object to create
|
12
|
-
# *
|
12
|
+
# * data<~File> - File or String to create object from
|
13
13
|
# * options<~Hash>:
|
14
14
|
# * 'Cache-Control'<~String> - Caching behaviour
|
15
15
|
# * 'Content-Disposition'<~String> - Presentational information for the object
|
@@ -24,11 +24,11 @@ unless Fog.mocking?
|
|
24
24
|
# * response<~Fog::AWS::Response>:
|
25
25
|
# * headers<~Hash>:
|
26
26
|
# * 'ETag'<~String> - etag of new object
|
27
|
-
def put_object(bucket_name, object_name,
|
28
|
-
|
29
|
-
headers =
|
27
|
+
def put_object(bucket_name, object_name, data, options = {})
|
28
|
+
data = parse_data(data)
|
29
|
+
headers = data[:headers].merge!(options)
|
30
30
|
request({
|
31
|
-
:body =>
|
31
|
+
:body => data[:body],
|
32
32
|
:expects => 200,
|
33
33
|
:headers => headers,
|
34
34
|
:host => "#{bucket_name}.#{@host}",
|
@@ -47,21 +47,21 @@ else
|
|
47
47
|
module AWS
|
48
48
|
class S3
|
49
49
|
|
50
|
-
def put_object(bucket_name, object_name,
|
51
|
-
|
50
|
+
def put_object(bucket_name, object_name, data, options = {})
|
51
|
+
data = parse_data(data)
|
52
52
|
response = Fog::Response.new
|
53
53
|
if (bucket = Fog::AWS::S3.data[:buckets][bucket_name])
|
54
54
|
response.status = 200
|
55
55
|
bucket[:objects][object_name] = {
|
56
|
-
:body =>
|
57
|
-
'Content-Type' => file[:headers]['Content-Type'],
|
56
|
+
:body => data[:body],
|
58
57
|
'ETag' => Fog::AWS::Mock.etag,
|
59
58
|
'Key' => object_name,
|
60
59
|
'LastModified' => Time.now.utc.strftime("%a, %d %b %Y %H:%M:%S +0000"),
|
61
60
|
'Owner' => { 'DisplayName' => 'owner', 'ID' => 'some_id'},
|
62
|
-
'Size' =>
|
61
|
+
'Size' => data[:headers]['Content-Length'],
|
63
62
|
'StorageClass' => 'STANDARD'
|
64
63
|
}
|
64
|
+
bucket[:objects][object_name]['Content-Type'] = data[:headers]['Content-Type']
|
65
65
|
else
|
66
66
|
response.status = 404
|
67
67
|
raise(Fog::Errors.status_error(200, 404, response))
|
@@ -41,14 +41,15 @@ else
|
|
41
41
|
def batch_put_attributes(domain_name, items, replace_attributes = Hash.new([]))
|
42
42
|
response = Fog::Response.new
|
43
43
|
if Fog::AWS::SimpleDB.data[:domains][domain_name]
|
44
|
-
for
|
45
|
-
for
|
46
|
-
|
47
|
-
|
44
|
+
for item_name, attributes in items do
|
45
|
+
for key, value in attributes do
|
46
|
+
Fog::AWS::SimpleDB.data[:domains][domain_name][item_name] ||= {}
|
47
|
+
if replace_attributes[item_name] && replace_attributes[item_name].include?(key)
|
48
|
+
Fog::AWS::SimpleDB.data[:domains][domain_name][item_name][key.to_s] = []
|
48
49
|
else
|
49
|
-
Fog::AWS::SimpleDB.data[:domains][domain_name][key] ||= []
|
50
|
+
Fog::AWS::SimpleDB.data[:domains][domain_name][item_name][key.to_s] ||= []
|
50
51
|
end
|
51
|
-
Fog::AWS::SimpleDB.data[:domains][domain_name][key] << value.to_s
|
52
|
+
Fog::AWS::SimpleDB.data[:domains][domain_name][item_name][key.to_s] << value.to_s
|
52
53
|
end
|
53
54
|
end
|
54
55
|
response.status = 200
|
@@ -34,7 +34,7 @@ else
|
|
34
34
|
|
35
35
|
def create_domain(domain_name)
|
36
36
|
response = Fog::Response.new
|
37
|
-
Fog::AWS::SimpleDB.data[:domains][domain_name] = {
|
37
|
+
Fog::AWS::SimpleDB.data[:domains][domain_name] = {}
|
38
38
|
response.status = 200
|
39
39
|
response.body = {
|
40
40
|
'BoxUsage' => Fog::AWS::Mock.box_usage,
|
@@ -1,34 +1,72 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
1
|
+
unless Fog.mocking?
|
2
|
+
|
3
|
+
module Fog
|
4
|
+
module AWS
|
5
|
+
class SimpleDB
|
6
|
+
|
7
|
+
# List metadata for SimpleDB domain
|
8
|
+
#
|
9
|
+
# ==== Parameters
|
10
|
+
# * domain_name<~String> - Name of domain. Must be between 3 and 255 of the
|
11
|
+
# following characters: a-z, A-Z, 0-9, '_', '-' and '.'.
|
12
|
+
# * item_name<~String> - Name of the item. May use any UTF-8 characters valid
|
13
|
+
# in xml. Control characters and sequences not allowed in xml are not
|
14
|
+
# valid. Can be up to 1024 bytes long.
|
15
|
+
# * attributes<~Hash> - Name/value pairs to remove from the item. Defaults to
|
16
|
+
# nil, which will delete the entire item. Attribute names and values may
|
17
|
+
# use any UTF-8 characters valid in xml. Control characters and sequences
|
18
|
+
# not allowed in xml are not valid. Each name and value can be up to 1024
|
19
|
+
# bytes long.
|
20
|
+
#
|
21
|
+
# ==== Returns
|
22
|
+
# * response<~Fog::AWS::Response>:
|
23
|
+
# * body<~Hash>:
|
24
|
+
# * 'BoxUsage'
|
25
|
+
# * 'RequestId'
|
26
|
+
def delete_attributes(domain_name, item_name, attributes = nil)
|
27
|
+
request({
|
28
|
+
'Action' => 'DeleteAttributes',
|
29
|
+
'DomainName' => domain_name,
|
30
|
+
'ItemName' => item_name
|
31
|
+
}.merge!(encode_attributes(attributes)), Fog::Parsers::AWS::SimpleDB::Basic.new(@nil_string))
|
32
|
+
end
|
33
|
+
|
30
34
|
end
|
35
|
+
end
|
36
|
+
end
|
31
37
|
|
38
|
+
else
|
39
|
+
|
40
|
+
module Fog
|
41
|
+
module AWS
|
42
|
+
class SimpleDB
|
43
|
+
|
44
|
+
def delete_attributes(domain_name, item_name, attributes = nil)
|
45
|
+
response = Fog::Response.new
|
46
|
+
if Fog::AWS::SimpleDB.data[:domains][domain_name]
|
47
|
+
if attributes
|
48
|
+
for key, value in attributes
|
49
|
+
if Fog::AWS::SimpleDB.data[:domains][domain_name][key]
|
50
|
+
Fog::AWS::SimpleDB.data[:domains][domain_name][key].delete('value')
|
51
|
+
end
|
52
|
+
end
|
53
|
+
else
|
54
|
+
Fog::AWS::SimpleDB.data[:domains].delete(domain_name)
|
55
|
+
end
|
56
|
+
response.status = 200
|
57
|
+
response.body = {
|
58
|
+
'BoxUsage' => Fog::AWS::Mock.box_usage,
|
59
|
+
'RequestId' => Fog::AWS::Mock.request_id
|
60
|
+
}
|
61
|
+
else
|
62
|
+
response.status = 400
|
63
|
+
raise(Fog::Errors.status_error(200, 400, response))
|
64
|
+
end
|
65
|
+
response
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
32
69
|
end
|
33
70
|
end
|
34
|
-
|
71
|
+
|
72
|
+
end
|
@@ -1,30 +1,80 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
1
|
+
unless Fog.mocking?
|
2
|
+
|
3
|
+
module Fog
|
4
|
+
module AWS
|
5
|
+
class SimpleDB
|
6
|
+
|
7
|
+
# List metadata for SimpleDB domain
|
8
|
+
#
|
9
|
+
# ==== Parameters
|
10
|
+
# * domain_name<~String> - Name of domain. Must be between 3 and 255 of the
|
11
|
+
# following characters: a-z, A-Z, 0-9, '_', '-' and '.'.
|
12
|
+
#
|
13
|
+
# ==== Returns
|
14
|
+
# * response<~Fog::AWS::Response>:
|
15
|
+
# * body<~Hash>:
|
16
|
+
# * 'AttributeNameCount' - number of unique attribute names in domain
|
17
|
+
# * 'AttributeNamesSizeBytes' - total size of unique attribute names, in bytes
|
18
|
+
# * 'AttributeValueCount' - number of all name/value pairs in domain
|
19
|
+
# * 'AttributeValuesSizeBytes' - total size of attributes, in bytes
|
20
|
+
# * 'BoxUsage'
|
21
|
+
# * 'ItemCount' - number of items in domain
|
22
|
+
# * 'ItemNameSizeBytes' - total size of item names in domain, in bytes
|
23
|
+
# * 'RequestId'
|
24
|
+
# * 'Timestamp' - last update time for metadata.
|
25
|
+
def domain_metadata(domain_name)
|
26
|
+
request({
|
27
|
+
'Action' => 'DomainMetadata',
|
28
|
+
'DomainName' => domain_name
|
29
|
+
}, Fog::Parsers::AWS::SimpleDB::DomainMetadata.new(@nil_string))
|
30
|
+
end
|
31
|
+
|
26
32
|
end
|
33
|
+
end
|
34
|
+
end
|
27
35
|
|
36
|
+
else
|
37
|
+
|
38
|
+
module Fog
|
39
|
+
module AWS
|
40
|
+
class SimpleDB
|
41
|
+
|
42
|
+
def domain_metadata(domain_name)
|
43
|
+
response = Fog::Response.new
|
44
|
+
if domain = Fog::AWS::SimpleDB.data[:domains][domain_name]
|
45
|
+
response.status = 200
|
46
|
+
|
47
|
+
attribute_names = []
|
48
|
+
attribute_values = []
|
49
|
+
for item in domain.values
|
50
|
+
for key, values in item
|
51
|
+
attribute_names << key
|
52
|
+
for value in values
|
53
|
+
attribute_values << value
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
response.body = {
|
59
|
+
'AttributeNameCount' => attribute_names.length,
|
60
|
+
'AttributeNamesSizeBytes' => attribute_names.join('').length,
|
61
|
+
'AttributeValueCount' => attribute_values.length,
|
62
|
+
'AttributeValuesSizeBytes' => attribute_values.join('').length,
|
63
|
+
'BoxUsage' => Fog::AWS::Mock.box_usage,
|
64
|
+
'ItemCount' => domain.keys.length,
|
65
|
+
'ItemNamesSizeBytes' => domain.keys.join('').length,
|
66
|
+
'RequestId' => Fog::AWS::Mock.request_id,
|
67
|
+
'Timestamp' => Time.now
|
68
|
+
}
|
69
|
+
else
|
70
|
+
response.status = 400
|
71
|
+
raise(Fog::Errors.status_error(200, 400, response))
|
72
|
+
end
|
73
|
+
response
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
28
77
|
end
|
29
78
|
end
|
79
|
+
|
30
80
|
end
|
@@ -1,35 +1,75 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
1
|
+
unless Fog.mocking?
|
2
|
+
|
3
|
+
module Fog
|
4
|
+
module AWS
|
5
|
+
class SimpleDB
|
6
|
+
|
7
|
+
# List metadata for SimpleDB domain
|
8
|
+
#
|
9
|
+
# ==== Parameters
|
10
|
+
# * domain_name<~String> - Name of domain. Must be between 3 and 255 of the
|
11
|
+
# following characters: a-z, A-Z, 0-9, '_', '-' and '.'.
|
12
|
+
# * item_name<~String> - Name of the item. May use any UTF-8 characters valid
|
13
|
+
# in xml. Control characters and sequences not allowed in xml are not
|
14
|
+
# valid. Can be up to 1024 bytes long.
|
15
|
+
# * attributes<~Array> - Attributes to return from the item. Defaults to
|
16
|
+
# nil, which will return all attributes. Attribute names and values may use
|
17
|
+
# any UTF-8 characters valid in xml. Control characters and sequences not
|
18
|
+
# allowed in xml are not valid. Each name and value can be up to 1024
|
19
|
+
# bytes long.
|
20
|
+
#
|
21
|
+
# ==== Returns
|
22
|
+
# * response<~Fog::AWS::Response>:
|
23
|
+
# * body<~Hash>:
|
24
|
+
# * 'Attributes' - list of attribute name/values for the item
|
25
|
+
# * 'BoxUsage'
|
26
|
+
# * 'RequestId'
|
27
|
+
def get_attributes(domain_name, item_name, attributes = nil)
|
28
|
+
request({
|
29
|
+
'Action' => 'GetAttributes',
|
30
|
+
'DomainName' => domain_name,
|
31
|
+
'ItemName' => item_name,
|
32
|
+
}.merge!(encode_attribute_names(attributes)), Fog::Parsers::AWS::SimpleDB::GetAttributes.new(@nil_string))
|
33
|
+
end
|
34
|
+
|
31
35
|
end
|
36
|
+
end
|
37
|
+
end
|
32
38
|
|
39
|
+
else
|
40
|
+
|
41
|
+
module Fog
|
42
|
+
module AWS
|
43
|
+
class SimpleDB
|
44
|
+
|
45
|
+
def get_attributes(domain_name, item_name, attributes = nil)
|
46
|
+
response = Fog::Response.new
|
47
|
+
if Fog::AWS::SimpleDB.data[:domains][domain_name]
|
48
|
+
object = {}
|
49
|
+
if attributes
|
50
|
+
for attribute in attributes
|
51
|
+
if Fog::AWS::SimpleDB.data[:domains][domain_name][item_name] && Fog::AWS::SimpleDB.data[:domains][domain_name][item_name]
|
52
|
+
object[attribute] = Fog::AWS::SimpleDB.data[:domains][domain_name][item_name][attribute]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
elsif Fog::AWS::SimpleDB.data[:domains][domain_name][item_name]
|
56
|
+
object = Fog::AWS::SimpleDB.data[:domains][domain_name][item_name]
|
57
|
+
end
|
58
|
+
response.status = 200
|
59
|
+
response.body = {
|
60
|
+
'Attributes' => object,
|
61
|
+
'BoxUsage' => Fog::AWS::Mock.box_usage,
|
62
|
+
'RequestId' => Fog::AWS::Mock.request_id
|
63
|
+
}
|
64
|
+
else
|
65
|
+
response.status = 400
|
66
|
+
raise(Fog::Errors.status_error(200, 400, response))
|
67
|
+
end
|
68
|
+
response
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
33
72
|
end
|
34
73
|
end
|
74
|
+
|
35
75
|
end
|
@@ -1,29 +1,47 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
1
|
+
unless Fog.mocking?
|
2
|
+
|
3
|
+
module Fog
|
4
|
+
module AWS
|
5
|
+
class SimpleDB
|
6
|
+
|
7
|
+
# Put item attributes into a SimpleDB domain
|
8
|
+
#
|
9
|
+
# ==== Parameters
|
10
|
+
# * domain_name<~String> - Name of domain. Must be between 3 and 255 of the
|
11
|
+
# following characters: a-z, A-Z, 0-9, '_', '-' and '.'.
|
12
|
+
# * item_name<~String> - Name of the item. May use any UTF-8 characters valid
|
13
|
+
# in xml. Control characters and sequences not allowed in xml are not
|
14
|
+
# valid. Can be up to 1024 bytes long.
|
15
|
+
# * attributes<~Hash> - Name/value pairs to add to the item. Attribute names
|
16
|
+
# and values may use any UTF-8 characters valid in xml. Control characters
|
17
|
+
# and sequences not allowed in xml are not valid. Each name and value can
|
18
|
+
# be up to 1024 bytes long.
|
19
|
+
#
|
20
|
+
# ==== Returns
|
21
|
+
# * response<~Fog::AWS::Response>:
|
22
|
+
# * body<~Hash>:
|
23
|
+
# * 'BoxUsage'
|
24
|
+
# * 'RequestId'
|
25
|
+
def put_attributes(domain_name, item_name, attributes, replace_attributes = [])
|
26
|
+
batch_put_attributes(domain_name, { item_name => attributes }, { item_name => replace_attributes })
|
27
|
+
end
|
28
|
+
|
25
29
|
end
|
30
|
+
end
|
31
|
+
end
|
26
32
|
|
33
|
+
else
|
34
|
+
|
35
|
+
module Fog
|
36
|
+
module AWS
|
37
|
+
class SimpleDb
|
38
|
+
|
39
|
+
def put_attributes(domain_name, item_name, attributes, replace_attributes = [])
|
40
|
+
batch_put_attributes(domain_name, { item_name => attributes }, { item_name => replace_attributes })
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
27
44
|
end
|
28
45
|
end
|
46
|
+
|
29
47
|
end
|
data/lib/fog/aws/s3.rb
CHANGED
@@ -81,20 +81,24 @@ module Fog
|
|
81
81
|
|
82
82
|
private
|
83
83
|
|
84
|
-
def
|
84
|
+
def parse_data(data)
|
85
85
|
metadata = {
|
86
86
|
:body => nil,
|
87
87
|
:headers => {}
|
88
88
|
}
|
89
89
|
|
90
|
-
|
91
|
-
|
92
|
-
metadata[:headers]['Content-
|
90
|
+
if data.is_a?(String)
|
91
|
+
metadata[:body] = data
|
92
|
+
metadata[:headers]['Content-Length'] = metadata[:body].size.to_s
|
93
|
+
else
|
94
|
+
filename = File.basename(data.path)
|
95
|
+
unless (mime_types = MIME::Types.of(filename)).empty?
|
96
|
+
metadata[:headers]['Content-Type'] = mime_types.first.content_type
|
97
|
+
end
|
98
|
+
metadata[:body] = data.read
|
99
|
+
metadata[:headers]['Content-Length'] = File.size(data.path)
|
93
100
|
end
|
94
|
-
|
95
|
-
metadata[:body] = file.read
|
96
|
-
metadata[:headers]['Content-Length'] = metadata[:body].size.to_s
|
97
|
-
metadata[:headers]['Content-MD5'] = Base64.encode64(Digest::MD5.digest(metadata[:body])).strip
|
101
|
+
# metadata[:headers]['Content-MD5'] = Base64.encode64(Digest::MD5.digest(metadata[:body])).strip
|
98
102
|
metadata
|
99
103
|
end
|
100
104
|
|
@@ -137,6 +141,7 @@ DATA
|
|
137
141
|
params[:headers]['Authorization'] = "AWS #{@aws_access_key_id}:#{signature}"
|
138
142
|
|
139
143
|
response = @connection.request({
|
144
|
+
:block => params[:block],
|
140
145
|
:body => params[:body],
|
141
146
|
:expects => params[:expects],
|
142
147
|
:headers => params[:headers],
|
data/lib/fog/connection.rb
CHANGED
@@ -34,15 +34,26 @@ unless Fog.mocking?
|
|
34
34
|
request = "#{params[:method]} #{params[:path]} HTTP/1.1\r\n"
|
35
35
|
params[:headers] ||= {}
|
36
36
|
params[:headers]['Host'] = params[:host]
|
37
|
-
if params[:body]
|
37
|
+
if params[:body] && !params[:headers]['Content-Length']
|
38
38
|
params[:headers]['Content-Length'] = params[:body].length
|
39
39
|
end
|
40
40
|
for key, value in params[:headers]
|
41
41
|
request << "#{key}: #{value}\r\n"
|
42
42
|
end
|
43
|
-
request << "\r\n
|
43
|
+
request << "\r\n"
|
44
44
|
@connection.write(request)
|
45
45
|
|
46
|
+
if params[:body]
|
47
|
+
if params[:body].is_a?(String)
|
48
|
+
body = StringIO.new(params[:body])
|
49
|
+
else
|
50
|
+
body = params[:body]
|
51
|
+
end
|
52
|
+
while chunk = body.read(1048576) # 1 megabyte
|
53
|
+
@connection.write(chunk)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
46
57
|
response = Fog::Response.new
|
47
58
|
response.request = params
|
48
59
|
response.status = @connection.readline[9..11].to_i
|
@@ -65,19 +76,30 @@ unless Fog.mocking?
|
|
65
76
|
parser = params[:parser]
|
66
77
|
end
|
67
78
|
body = Nokogiri::XML::SAX::PushParser.new(parser)
|
79
|
+
elsif params[:block]
|
80
|
+
body = nil
|
68
81
|
else
|
69
82
|
body = ''
|
70
83
|
end
|
71
84
|
|
72
85
|
unless params[:method] == 'HEAD'
|
73
86
|
if response.headers['Content-Length']
|
74
|
-
|
87
|
+
content = @connection.read(response.headers['Content-Length'].to_i)
|
88
|
+
unless params[:block]
|
89
|
+
body << content
|
90
|
+
else
|
91
|
+
params[:block].call(content)
|
92
|
+
end
|
75
93
|
elsif response.headers['Transfer-Encoding'] == 'chunked'
|
76
94
|
while true
|
77
95
|
# 2 == "/r/n".length
|
78
96
|
chunk_size = @connection.readline.chomp!.to_i(16) + 2
|
79
|
-
chunk = @connection.read(chunk_size)
|
80
|
-
|
97
|
+
chunk = @connection.read(chunk_size)[0...-2]
|
98
|
+
unless params[:block]
|
99
|
+
body << chunk
|
100
|
+
else
|
101
|
+
params[:block].call(chunk)
|
102
|
+
end
|
81
103
|
if chunk_size == 2
|
82
104
|
break
|
83
105
|
end
|
@@ -26,6 +26,15 @@ describe 'S3.get_object' do
|
|
26
26
|
actual.headers['Last-Modified'].should be_a(String)
|
27
27
|
end
|
28
28
|
|
29
|
+
it 'should return chunks with optional block' do
|
30
|
+
file = File.open(File.dirname(__FILE__) + '/../../../lorem.txt', 'r')
|
31
|
+
data = ''
|
32
|
+
s3.get_object('foggetobject', 'fog_get_object') do |chunk|
|
33
|
+
data << chunk
|
34
|
+
end
|
35
|
+
data.should == file.read
|
36
|
+
end
|
37
|
+
|
29
38
|
end
|
30
39
|
describe 'failure' do
|
31
40
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fog
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Wesley Beary
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-09-
|
12
|
+
date: 2009-09-09 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|