awsum 0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +1 -0
- data/.gitignore +5 -0
- data/.rspec +1 -0
- data/Gemfile +15 -0
- data/Gemfile.lock +44 -0
- data/LICENSE +19 -0
- data/README.rdoc +42 -0
- data/Rakefile +75 -0
- data/awsum.gemspec +199 -0
- data/lib/awsum.rb +20 -0
- data/lib/awsum/ec2.rb +741 -0
- data/lib/awsum/ec2/address.rb +67 -0
- data/lib/awsum/ec2/availability_zone.rb +16 -0
- data/lib/awsum/ec2/image.rb +62 -0
- data/lib/awsum/ec2/instance.rb +57 -0
- data/lib/awsum/ec2/keypair.rb +16 -0
- data/lib/awsum/ec2/parsers/address_parser.rb +61 -0
- data/lib/awsum/ec2/parsers/availability_zone_parser.rb +57 -0
- data/lib/awsum/ec2/parsers/image_parser.rb +74 -0
- data/lib/awsum/ec2/parsers/instance_parser.rb +90 -0
- data/lib/awsum/ec2/parsers/keypair_parser.rb +64 -0
- data/lib/awsum/ec2/parsers/purchase_reserved_instances_offering_parser.rb +34 -0
- data/lib/awsum/ec2/parsers/region_parser.rb +56 -0
- data/lib/awsum/ec2/parsers/register_image_parser.rb +34 -0
- data/lib/awsum/ec2/parsers/reserved_instance_parser.rb +64 -0
- data/lib/awsum/ec2/parsers/reserved_instances_offering_parser.rb +63 -0
- data/lib/awsum/ec2/parsers/security_group_parser.rb +106 -0
- data/lib/awsum/ec2/parsers/snapshot_parser.rb +64 -0
- data/lib/awsum/ec2/parsers/volume_parser.rb +77 -0
- data/lib/awsum/ec2/region.rb +54 -0
- data/lib/awsum/ec2/reserved_instance.rb +24 -0
- data/lib/awsum/ec2/reserved_instances_offering.rb +20 -0
- data/lib/awsum/ec2/security_group.rb +74 -0
- data/lib/awsum/ec2/snapshot.rb +23 -0
- data/lib/awsum/ec2/volume.rb +65 -0
- data/lib/awsum/error.rb +53 -0
- data/lib/awsum/net_fix.rb +100 -0
- data/lib/awsum/parser.rb +18 -0
- data/lib/awsum/requestable.rb +216 -0
- data/lib/awsum/s3.rb +220 -0
- data/lib/awsum/s3/bucket.rb +28 -0
- data/lib/awsum/s3/headers.rb +24 -0
- data/lib/awsum/s3/object.rb +138 -0
- data/lib/awsum/s3/parsers/bucket_parser.rb +43 -0
- data/lib/awsum/support.rb +94 -0
- data/spec/fixtures/ec2/addresses.xml +10 -0
- data/spec/fixtures/ec2/allocate_address.xml +5 -0
- data/spec/fixtures/ec2/associate_address.xml +5 -0
- data/spec/fixtures/ec2/attach_volume.xml +9 -0
- data/spec/fixtures/ec2/authorize_ip_access.xml +5 -0
- data/spec/fixtures/ec2/authorize_owner_group_access.xml +5 -0
- data/spec/fixtures/ec2/authorize_owner_group_access_error.xml +2 -0
- data/spec/fixtures/ec2/availability_zones.xml +16 -0
- data/spec/fixtures/ec2/available_volume.xml +14 -0
- data/spec/fixtures/ec2/create_key_pair.xml +29 -0
- data/spec/fixtures/ec2/create_security_group.xml +5 -0
- data/spec/fixtures/ec2/create_snapshot.xml +9 -0
- data/spec/fixtures/ec2/create_volume.xml +10 -0
- data/spec/fixtures/ec2/delete_key_pair.xml +5 -0
- data/spec/fixtures/ec2/delete_security_group.xml +5 -0
- data/spec/fixtures/ec2/delete_snapshot.xml +5 -0
- data/spec/fixtures/ec2/delete_volume.xml +5 -0
- data/spec/fixtures/ec2/deregister_image.xml +5 -0
- data/spec/fixtures/ec2/detach_volume.xml +9 -0
- data/spec/fixtures/ec2/disassociate_address.xml +5 -0
- data/spec/fixtures/ec2/image.xml +15 -0
- data/spec/fixtures/ec2/images.xml +77 -0
- data/spec/fixtures/ec2/instance.xml +36 -0
- data/spec/fixtures/ec2/instances.xml +88 -0
- data/spec/fixtures/ec2/internal_error.xml +2 -0
- data/spec/fixtures/ec2/invalid_amiid_error.xml +2 -0
- data/spec/fixtures/ec2/invalid_request_error.xml +2 -0
- data/spec/fixtures/ec2/key_pairs.xml +10 -0
- data/spec/fixtures/ec2/purchase_reserved_instances_offering.xml +5 -0
- data/spec/fixtures/ec2/purchase_reserved_instances_offerings.xml +6 -0
- data/spec/fixtures/ec2/regions.xml +14 -0
- data/spec/fixtures/ec2/register_image.xml +5 -0
- data/spec/fixtures/ec2/release_address.xml +5 -0
- data/spec/fixtures/ec2/reserved_instances.xml +18 -0
- data/spec/fixtures/ec2/reserved_instances_offering.xml +15 -0
- data/spec/fixtures/ec2/reserved_instances_offerings.xml +276 -0
- data/spec/fixtures/ec2/revoke_ip_access.xml +5 -0
- data/spec/fixtures/ec2/revoke_owner_group_access.xml +5 -0
- data/spec/fixtures/ec2/run_instances.xml +30 -0
- data/spec/fixtures/ec2/security_groups.xml +159 -0
- data/spec/fixtures/ec2/snapshots.xml +13 -0
- data/spec/fixtures/ec2/terminate_instances.xml +17 -0
- data/spec/fixtures/ec2/unassociated_address.xml +10 -0
- data/spec/fixtures/ec2/volumes.xml +23 -0
- data/spec/fixtures/errors/invalid_parameter_value.xml +2 -0
- data/spec/fixtures/s3/buckets.xml +2 -0
- data/spec/fixtures/s3/copy_failure.xml +23 -0
- data/spec/fixtures/s3/invalid_request_signature.xml +5 -0
- data/spec/fixtures/s3/keys.xml +2 -0
- data/spec/lib/awsum/ec2/address_spec.rb +149 -0
- data/spec/lib/awsum/ec2/availability_zones_spec.rb +21 -0
- data/spec/lib/awsum/ec2/image_spec.rb +92 -0
- data/spec/lib/awsum/ec2/instance_spec.rb +125 -0
- data/spec/lib/awsum/ec2/keypair_spec.rb +55 -0
- data/spec/lib/awsum/ec2/parsers/address_parser_spec.rb +51 -0
- data/spec/lib/awsum/ec2/parsers/availability_zone_parser_spec.rb +28 -0
- data/spec/lib/awsum/ec2/parsers/image_parser_spec.rb +66 -0
- data/spec/lib/awsum/ec2/parsers/instance_parser_spec.rb +75 -0
- data/spec/lib/awsum/ec2/parsers/keypair_parser_spec.rb +74 -0
- data/spec/lib/awsum/ec2/parsers/purchase_reserved_instances_offering_parser_spec.rb +14 -0
- data/spec/lib/awsum/ec2/parsers/region_parser_spec.rb +27 -0
- data/spec/lib/awsum/ec2/parsers/register_image_parser_spec.rb +15 -0
- data/spec/lib/awsum/ec2/parsers/reserved_instance_parser_spec.rb +35 -0
- data/spec/lib/awsum/ec2/parsers/reserved_instances_offering_parser_spec.rb +32 -0
- data/spec/lib/awsum/ec2/parsers/security_group_parser_spec.rb +78 -0
- data/spec/lib/awsum/ec2/parsers/snapshot_parser_spec.rb +30 -0
- data/spec/lib/awsum/ec2/parsers/volume_parser_spec.rb +35 -0
- data/spec/lib/awsum/ec2/region_spec.rb +73 -0
- data/spec/lib/awsum/ec2/reserved_instance_spec.rb +61 -0
- data/spec/lib/awsum/ec2/reserved_instances_offering_spec.rb +33 -0
- data/spec/lib/awsum/ec2/security_group_spec.rb +179 -0
- data/spec/lib/awsum/ec2/snapshots_spec.rb +69 -0
- data/spec/lib/awsum/ec2/volume_spec.rb +107 -0
- data/spec/lib/awsum/ec2_spec.rb +6 -0
- data/spec/lib/awsum/error_spec.rb +31 -0
- data/spec/lib/awsum/requestable_spec.rb +126 -0
- data/spec/lib/awsum/s3/bucket_spec.rb +95 -0
- data/spec/lib/awsum/s3/object_spec.rb +128 -0
- data/spec/lib/awsum/s3/parsers/bucket_parser_spec.rb +41 -0
- data/spec/lib/awsum/s3/parsers/object_parser_spec.rb +41 -0
- data/spec/spec_helper.rb +16 -0
- metadata +240 -0
@@ -0,0 +1,77 @@
|
|
1
|
+
module Awsum
|
2
|
+
class Ec2
|
3
|
+
class VolumeParser < Awsum::Parser #:nodoc:
|
4
|
+
def initialize(ec2)
|
5
|
+
@ec2 = ec2
|
6
|
+
@volumes = []
|
7
|
+
@text = nil
|
8
|
+
@stack = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def tag_start(tag, attributes)
|
12
|
+
#Quick hack so we can use the same parser for CreateVolume which doesn't use the item tag to wrap the volume information
|
13
|
+
if tag == 'CreateVolumeResponse'
|
14
|
+
@stack << 'volumeSet'
|
15
|
+
end
|
16
|
+
|
17
|
+
case tag
|
18
|
+
when 'volumeSet'
|
19
|
+
@stack << 'volumeSet'
|
20
|
+
when 'attachmentSet'
|
21
|
+
@stack << 'attachmentSet'
|
22
|
+
when 'item', 'CreateVolumeResponse'
|
23
|
+
case @stack[-1]
|
24
|
+
when 'volumeSet'
|
25
|
+
@current = {}
|
26
|
+
when 'attachmentSet'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
@text = ''
|
30
|
+
end
|
31
|
+
|
32
|
+
def text(text)
|
33
|
+
@text << text unless @text.nil?
|
34
|
+
end
|
35
|
+
|
36
|
+
def tag_end(tag)
|
37
|
+
case tag
|
38
|
+
when 'DescribeVolumesResponse'
|
39
|
+
#no-op
|
40
|
+
when 'volumeSet', 'attachmentSet'
|
41
|
+
@stack.pop
|
42
|
+
when 'item', 'CreateVolumeResponse'
|
43
|
+
case @stack[-1]
|
44
|
+
when 'volumeSet'
|
45
|
+
@volumes << Volume.new(
|
46
|
+
@ec2,
|
47
|
+
@current['volumeId'],
|
48
|
+
@current['instanceId'],
|
49
|
+
@current['size'].to_i,
|
50
|
+
@current['status'],
|
51
|
+
@current['createTime'].blank? ? nil :Time.parse(@current['createTime']),
|
52
|
+
@current['snapshotId'],
|
53
|
+
@current['device'],
|
54
|
+
@current['attachTime'].blank? ? nil :Time.parse(@current['attachTime']),
|
55
|
+
@current['availabilityZone'],
|
56
|
+
@current['attachment_status']
|
57
|
+
)
|
58
|
+
end
|
59
|
+
else
|
60
|
+
unless @text.nil? || @current.nil?
|
61
|
+
text = @text.strip
|
62
|
+
#Handle special case for attachmentSet/status
|
63
|
+
if @stack[-1] == 'attachmentSet' && tag == 'status'
|
64
|
+
@current['attachment_status'] = (text == '' ? nil : text)
|
65
|
+
else
|
66
|
+
@current[tag] = (text == '' ? nil : text)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def result
|
73
|
+
@volumes
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'awsum/ec2/parsers/region_parser'
|
2
|
+
|
3
|
+
module Awsum
|
4
|
+
class Ec2
|
5
|
+
class Region
|
6
|
+
attr_reader :name, :end_point
|
7
|
+
|
8
|
+
def initialize(ec2, name, end_point) #:nodoc:
|
9
|
+
@ec2 = ec2
|
10
|
+
@name = name
|
11
|
+
@end_point = end_point
|
12
|
+
end
|
13
|
+
|
14
|
+
# List the AvailabilityZone(s) of this Region
|
15
|
+
def availability_zones
|
16
|
+
use do
|
17
|
+
@ec2.availability_zones
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Operate all Awsum::Ec2 methods against this Region
|
22
|
+
#
|
23
|
+
# ====Example
|
24
|
+
#
|
25
|
+
# ec2.region('eu-west-1').use
|
26
|
+
# ec2.availability_zones #Will give you all the availability zones in the eu-west-1 region
|
27
|
+
#
|
28
|
+
# Alternative:
|
29
|
+
# ec2.region('eu-west-1') do |region|
|
30
|
+
# region.availability_zones
|
31
|
+
# end
|
32
|
+
def use(&block)
|
33
|
+
old_host = @ec2.host
|
34
|
+
@ec2.host = end_point
|
35
|
+
if block_given?
|
36
|
+
block.arity < 1 ? instance_eval(&block) : block[self]
|
37
|
+
else
|
38
|
+
self
|
39
|
+
end
|
40
|
+
ensure
|
41
|
+
@ec2.host = old_host
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
#--
|
46
|
+
# Will pass all missing methods onto the ec2 object
|
47
|
+
def method_missing(method_name, *args, &block)
|
48
|
+
use do
|
49
|
+
@ec2.send(method_name, *args, &block)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'awsum/ec2/parsers/purchase_reserved_instances_offering_parser'
|
2
|
+
require 'awsum/ec2/parsers/reserved_instance_parser'
|
3
|
+
|
4
|
+
module Awsum
|
5
|
+
class Ec2
|
6
|
+
class ReservedInstance
|
7
|
+
attr_reader :id, :instance_type, :availability_zone, :start, :duration, :fixed_price, :usage_price, :instance_count, :product_description, :state
|
8
|
+
|
9
|
+
def initialize(ec2, id, instance_type, availability_zone, start, duration, fixed_price, usage_price, instance_count, product_description, state)
|
10
|
+
@ec2 = ec2
|
11
|
+
@id = id
|
12
|
+
@instance_type = instance_type
|
13
|
+
@availability_zone = availability_zone
|
14
|
+
@start = start
|
15
|
+
@duration = duration
|
16
|
+
@fixed_price = fixed_price
|
17
|
+
@usage_price = usage_price
|
18
|
+
@instance_count = instance_count
|
19
|
+
@product_description = product_description
|
20
|
+
@state = state
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'awsum/ec2/parsers/reserved_instances_offering_parser'
|
2
|
+
|
3
|
+
module Awsum
|
4
|
+
class Ec2
|
5
|
+
class ReservedInstancesOffering
|
6
|
+
attr_reader :id, :instance_type, :availability_zone, :duration, :fixed_price, :usage_price, :product_description
|
7
|
+
|
8
|
+
def initialize(ec2, id, instance_type, availability_zone, duration, fixed_price, usage_price, product_description)
|
9
|
+
@ec2 = ec2
|
10
|
+
@id = id
|
11
|
+
@instance_type = instance_type
|
12
|
+
@availability_zone = availability_zone
|
13
|
+
@duration = duration
|
14
|
+
@fixed_price = fixed_price
|
15
|
+
@usage_price = usage_price
|
16
|
+
@product_description = product_description
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'awsum/ec2/parsers/security_group_parser'
|
2
|
+
|
3
|
+
module Awsum
|
4
|
+
class Ec2
|
5
|
+
class SecurityGroup
|
6
|
+
attr_reader :name, :description, :owner_id, :ip_permissions, :group_permissions
|
7
|
+
|
8
|
+
def initialize(ec2, name, description, owner_id, ip_permissions, group_permissions)
|
9
|
+
@ec2 = ec2
|
10
|
+
@name = name
|
11
|
+
@description = description
|
12
|
+
@owner_id = owner_id
|
13
|
+
@ip_permissions = ip_permissions
|
14
|
+
@group_permissions = group_permissions
|
15
|
+
end
|
16
|
+
|
17
|
+
# Authorize access for a group
|
18
|
+
def authorize_group(group_name, owner_id)
|
19
|
+
@ec2.authorize_security_group_ingress(@name, :source_security_group_name => group_name, :source_security_group_owner_id => owner_id)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Revoke access for a group
|
23
|
+
def revoke_group(group_name, owner_id)
|
24
|
+
@ec2.revoke_security_group_ingress(@name, :source_security_group_name => group_name, :source_security_group_owner_id => owner_id)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Authorize access for an ip address
|
28
|
+
def authorize_ip(from_port, to_port, protocol = 'tcp', cidr_ip = '0.0.0.0/0')
|
29
|
+
@ec2.authorize_security_group_ingress(@name, :ip_protocol => protocol, :from_port => from_port, :to_port => to_port, :cidr_ip => cidr_ip)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Revoke access from an ip address
|
33
|
+
def revoke_ip(from_port, to_port, protocol = 'tcp', cidr_ip = '0.0.0.0/0')
|
34
|
+
@ec2.revoke_security_group_ingress(@name, :ip_protocol => protocol, :from_port => from_port, :to_port => to_port, :cidr_ip => cidr_ip)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Delete this SecurityGroup
|
38
|
+
def delete
|
39
|
+
@ec2.delete_security_group(@name)
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
class Permission #:nodoc:
|
44
|
+
attr_reader :protocol, :from_port, :to_port
|
45
|
+
|
46
|
+
def initialize(protocol, from_port, to_port)
|
47
|
+
@protocol = protocol
|
48
|
+
@from_port = from_port.to_i
|
49
|
+
@to_port = to_port.to_i
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
protected
|
54
|
+
class IpPermission < Permission
|
55
|
+
attr_reader :ip
|
56
|
+
|
57
|
+
def initialize(protocol, from_port, to_port, ip)
|
58
|
+
super(protocol, from_port, to_port)
|
59
|
+
@ip = ip
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
class GroupPermission < Permission
|
64
|
+
attr_reader :group, :user_id
|
65
|
+
|
66
|
+
def initialize(protocol, from_port, to_port, group, user_id)
|
67
|
+
super(protocol, from_port, to_port)
|
68
|
+
@group = group
|
69
|
+
@user_id = user_id
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'awsum/ec2/parsers/snapshot_parser'
|
2
|
+
|
3
|
+
module Awsum
|
4
|
+
class Ec2
|
5
|
+
class Snapshot
|
6
|
+
attr_reader :id, :volume_id, :status, :start_time, :progress
|
7
|
+
|
8
|
+
def initialize(ec2, id, volume_id, status, start_time, progress) #:nodoc:
|
9
|
+
@ec2 = ec2
|
10
|
+
@id = id
|
11
|
+
@volume_id = volume_id
|
12
|
+
@status = status
|
13
|
+
@start_time = start_time
|
14
|
+
@progress = progress
|
15
|
+
end
|
16
|
+
|
17
|
+
# Delete this Snapshot
|
18
|
+
def delete
|
19
|
+
@ec2.delete_snapshot id
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'awsum/ec2/parsers/volume_parser'
|
2
|
+
|
3
|
+
module Awsum
|
4
|
+
class Ec2
|
5
|
+
class Volume
|
6
|
+
attr_reader :id, :instance_id, :size, :status, :create_time, :snapshot_id, :device, :attach_time, :availability_zone, :attachment_status
|
7
|
+
|
8
|
+
def initialize(ec2, id, instance_id, size, status, create_time, snapshot_id, device, attach_time, availability_zone, attachment_status) #:nodoc:
|
9
|
+
@ec2 = ec2
|
10
|
+
@id = id
|
11
|
+
@instance_id = instance_id
|
12
|
+
@size = size
|
13
|
+
@status = status
|
14
|
+
@create_time = create_time
|
15
|
+
@snapshot_id = snapshot_id
|
16
|
+
@device = device
|
17
|
+
@attach_time = attach_time
|
18
|
+
@availability_zone = availability_zone
|
19
|
+
@attachment_status = attachment_status
|
20
|
+
end
|
21
|
+
|
22
|
+
# Will reload the information about this Volume
|
23
|
+
#
|
24
|
+
# Useful for when a volume has just been created but is not yet available
|
25
|
+
# while volume.status != 'available'
|
26
|
+
# volume.reload
|
27
|
+
# end
|
28
|
+
def reload
|
29
|
+
reloaded_volume = @ec2.volume id
|
30
|
+
|
31
|
+
@id = id
|
32
|
+
@instance_id = reloaded_volume.instance_id
|
33
|
+
@size = reloaded_volume.size
|
34
|
+
@status = reloaded_volume.status
|
35
|
+
@create_time = reloaded_volume.create_time
|
36
|
+
@snapshot_id = reloaded_volume.snapshot_id
|
37
|
+
@device = reloaded_volume.device
|
38
|
+
@attach_time = reloaded_volume.attach_time
|
39
|
+
@availability_zone = reloaded_volume.availability_zone
|
40
|
+
@attachment_status = reloaded_volume.attachment_status
|
41
|
+
end
|
42
|
+
|
43
|
+
# Detach this volume
|
44
|
+
def detach(force = false)
|
45
|
+
@ec2.detach_volume id, :force => force
|
46
|
+
end
|
47
|
+
|
48
|
+
# Delete this volume
|
49
|
+
def delete
|
50
|
+
@ec2.delete_volume id
|
51
|
+
end
|
52
|
+
|
53
|
+
# Creates a Snapshot of this Volume
|
54
|
+
def create_snapshot
|
55
|
+
@ec2.create_snapshot id
|
56
|
+
end
|
57
|
+
|
58
|
+
# Lists the Snapshot(s) of this Volume
|
59
|
+
def snapshots
|
60
|
+
snapshots = @ec2.snapshots
|
61
|
+
snapshots.delete_if {|s| s.volume_id != id}
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/lib/awsum/error.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
module Awsum
|
2
|
+
class Error < StandardError
|
3
|
+
attr_reader :response_code, :code, :message, :request_id, :additional
|
4
|
+
|
5
|
+
def initialize(response)
|
6
|
+
@response_code = response.code
|
7
|
+
parser = ErrorParser.new
|
8
|
+
parser.parse(response.body)
|
9
|
+
@code = parser.code
|
10
|
+
@message = parser.message
|
11
|
+
@request_id = parser.request_id
|
12
|
+
@additional = parser.additional
|
13
|
+
end
|
14
|
+
|
15
|
+
def inspect
|
16
|
+
"#<Awsum::Error response_code=#{@response_code} code=#{@code} request_id=#{@request_id} message=#{@message}>"
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
class ErrorParser < Awsum::Parser #:nodoc:
|
21
|
+
attr_reader :code, :message, :request_id, :additional
|
22
|
+
|
23
|
+
def initialize
|
24
|
+
@additional = {}
|
25
|
+
@text = ""
|
26
|
+
end
|
27
|
+
|
28
|
+
def tag_start(tag, attributes)
|
29
|
+
end
|
30
|
+
|
31
|
+
def text(text)
|
32
|
+
@text << text unless @text.nil?
|
33
|
+
end
|
34
|
+
|
35
|
+
def tag_end(tag)
|
36
|
+
text = @text.strip
|
37
|
+
return if text.blank?
|
38
|
+
|
39
|
+
case tag
|
40
|
+
when 'Code'
|
41
|
+
@code = text
|
42
|
+
when 'Message'
|
43
|
+
@message = text
|
44
|
+
when 'RequestID', 'RequestId'
|
45
|
+
@request_id = text
|
46
|
+
else
|
47
|
+
@additional[tag] = text
|
48
|
+
end
|
49
|
+
@text = ''
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# Some fixes for the net/http libraries to better suppport S3
|
2
|
+
module Net
|
3
|
+
class BufferedIO
|
4
|
+
#Increase the default read size for streaming from the socket
|
5
|
+
def rbuf_fill
|
6
|
+
timeout(@read_timeout) {
|
7
|
+
@rbuf << @io.sysread(1024 * 16)
|
8
|
+
}
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class HTTPGenericRequest
|
13
|
+
@@local_read_size = 1024 * 16
|
14
|
+
|
15
|
+
# Added limit which can be one of :headers or :body to limit the sending of
|
16
|
+
# a request to either the headers or the body in order to make use of
|
17
|
+
# 100-continue processing for S3
|
18
|
+
def exec(sock, ver, path, limit = nil) #:nodoc: internal use only
|
19
|
+
if @body
|
20
|
+
send_request_with_body sock, ver, path, @body, limit
|
21
|
+
elsif @body_stream
|
22
|
+
send_request_with_body_stream sock, ver, path, @body_stream, limit
|
23
|
+
else
|
24
|
+
write_header sock, ver, path
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
# Will send both headers and body unless limit is set to either
|
31
|
+
# :headers or :body to restrict to one
|
32
|
+
def send_request_with_body(sock, ver, path, body, limit = nil)
|
33
|
+
self.content_length = body.length
|
34
|
+
delete 'Transfer-Encoding'
|
35
|
+
supply_default_content_type
|
36
|
+
write_header sock, ver, path unless limit == :body
|
37
|
+
sock.write body unless limit == :headers
|
38
|
+
end
|
39
|
+
|
40
|
+
# Will send both headers and body unless limit is set to either
|
41
|
+
# :headers or :body to restrict to one
|
42
|
+
#
|
43
|
+
# Increased the default read size for streaming from local streams to 1MB
|
44
|
+
def send_request_with_body_stream(sock, ver, path, f, limit = nil)
|
45
|
+
unless content_length() or chunked?
|
46
|
+
raise ArgumentError,
|
47
|
+
"Content-Length not given and Transfer-Encoding is not `chunked'"
|
48
|
+
end
|
49
|
+
supply_default_content_type
|
50
|
+
write_header sock, ver, path unless limit == :body
|
51
|
+
if limit != :headers
|
52
|
+
if chunked?
|
53
|
+
while s = f.read(1024 * 1024)
|
54
|
+
sock.write(sprintf("%x\r\n", s.length) << s << "\r\n")
|
55
|
+
end
|
56
|
+
sock.write "0\r\n\r\n"
|
57
|
+
else
|
58
|
+
while s = f.read(1024 * 1024)
|
59
|
+
sock.write s
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class HTTP < Protocol
|
67
|
+
# Patched to handle 100-continue processing for S3
|
68
|
+
def request(req, body = nil, &block) # :yield: +response+
|
69
|
+
unless started?
|
70
|
+
start {
|
71
|
+
req['connection'] ||= 'close'
|
72
|
+
return request(req, body, &block)
|
73
|
+
}
|
74
|
+
end
|
75
|
+
if proxy_user()
|
76
|
+
unless use_ssl?
|
77
|
+
req.proxy_basic_auth proxy_user(), proxy_pass()
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
req.set_body_internal body
|
82
|
+
begin_transport req
|
83
|
+
# Send only the headers if a 100-continue request
|
84
|
+
limit = ((req.is_a?(Post) || req.is_a?(Put)) && req['expect'] == '100-continue') ? :headers : nil
|
85
|
+
req.exec @socket, @curr_http_version, edit_path(req.path), limit
|
86
|
+
begin
|
87
|
+
res = HTTPResponse.read_new(@socket)
|
88
|
+
if res.is_a?(HTTPContinue) && limit && req['content-length'].to_i > 0
|
89
|
+
req.exec @socket, @curr_http_version, edit_path(req.path), :body
|
90
|
+
end
|
91
|
+
end while res.kind_of?(HTTPContinue)
|
92
|
+
res.reading_body(@socket, req.response_body_permitted?) {
|
93
|
+
yield res if block_given?
|
94
|
+
}
|
95
|
+
end_transport req, res
|
96
|
+
|
97
|
+
res
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|