awsum 0.5

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.
Files changed (127) hide show
  1. data/.autotest +1 -0
  2. data/.gitignore +5 -0
  3. data/.rspec +1 -0
  4. data/Gemfile +15 -0
  5. data/Gemfile.lock +44 -0
  6. data/LICENSE +19 -0
  7. data/README.rdoc +42 -0
  8. data/Rakefile +75 -0
  9. data/awsum.gemspec +199 -0
  10. data/lib/awsum.rb +20 -0
  11. data/lib/awsum/ec2.rb +741 -0
  12. data/lib/awsum/ec2/address.rb +67 -0
  13. data/lib/awsum/ec2/availability_zone.rb +16 -0
  14. data/lib/awsum/ec2/image.rb +62 -0
  15. data/lib/awsum/ec2/instance.rb +57 -0
  16. data/lib/awsum/ec2/keypair.rb +16 -0
  17. data/lib/awsum/ec2/parsers/address_parser.rb +61 -0
  18. data/lib/awsum/ec2/parsers/availability_zone_parser.rb +57 -0
  19. data/lib/awsum/ec2/parsers/image_parser.rb +74 -0
  20. data/lib/awsum/ec2/parsers/instance_parser.rb +90 -0
  21. data/lib/awsum/ec2/parsers/keypair_parser.rb +64 -0
  22. data/lib/awsum/ec2/parsers/purchase_reserved_instances_offering_parser.rb +34 -0
  23. data/lib/awsum/ec2/parsers/region_parser.rb +56 -0
  24. data/lib/awsum/ec2/parsers/register_image_parser.rb +34 -0
  25. data/lib/awsum/ec2/parsers/reserved_instance_parser.rb +64 -0
  26. data/lib/awsum/ec2/parsers/reserved_instances_offering_parser.rb +63 -0
  27. data/lib/awsum/ec2/parsers/security_group_parser.rb +106 -0
  28. data/lib/awsum/ec2/parsers/snapshot_parser.rb +64 -0
  29. data/lib/awsum/ec2/parsers/volume_parser.rb +77 -0
  30. data/lib/awsum/ec2/region.rb +54 -0
  31. data/lib/awsum/ec2/reserved_instance.rb +24 -0
  32. data/lib/awsum/ec2/reserved_instances_offering.rb +20 -0
  33. data/lib/awsum/ec2/security_group.rb +74 -0
  34. data/lib/awsum/ec2/snapshot.rb +23 -0
  35. data/lib/awsum/ec2/volume.rb +65 -0
  36. data/lib/awsum/error.rb +53 -0
  37. data/lib/awsum/net_fix.rb +100 -0
  38. data/lib/awsum/parser.rb +18 -0
  39. data/lib/awsum/requestable.rb +216 -0
  40. data/lib/awsum/s3.rb +220 -0
  41. data/lib/awsum/s3/bucket.rb +28 -0
  42. data/lib/awsum/s3/headers.rb +24 -0
  43. data/lib/awsum/s3/object.rb +138 -0
  44. data/lib/awsum/s3/parsers/bucket_parser.rb +43 -0
  45. data/lib/awsum/support.rb +94 -0
  46. data/spec/fixtures/ec2/addresses.xml +10 -0
  47. data/spec/fixtures/ec2/allocate_address.xml +5 -0
  48. data/spec/fixtures/ec2/associate_address.xml +5 -0
  49. data/spec/fixtures/ec2/attach_volume.xml +9 -0
  50. data/spec/fixtures/ec2/authorize_ip_access.xml +5 -0
  51. data/spec/fixtures/ec2/authorize_owner_group_access.xml +5 -0
  52. data/spec/fixtures/ec2/authorize_owner_group_access_error.xml +2 -0
  53. data/spec/fixtures/ec2/availability_zones.xml +16 -0
  54. data/spec/fixtures/ec2/available_volume.xml +14 -0
  55. data/spec/fixtures/ec2/create_key_pair.xml +29 -0
  56. data/spec/fixtures/ec2/create_security_group.xml +5 -0
  57. data/spec/fixtures/ec2/create_snapshot.xml +9 -0
  58. data/spec/fixtures/ec2/create_volume.xml +10 -0
  59. data/spec/fixtures/ec2/delete_key_pair.xml +5 -0
  60. data/spec/fixtures/ec2/delete_security_group.xml +5 -0
  61. data/spec/fixtures/ec2/delete_snapshot.xml +5 -0
  62. data/spec/fixtures/ec2/delete_volume.xml +5 -0
  63. data/spec/fixtures/ec2/deregister_image.xml +5 -0
  64. data/spec/fixtures/ec2/detach_volume.xml +9 -0
  65. data/spec/fixtures/ec2/disassociate_address.xml +5 -0
  66. data/spec/fixtures/ec2/image.xml +15 -0
  67. data/spec/fixtures/ec2/images.xml +77 -0
  68. data/spec/fixtures/ec2/instance.xml +36 -0
  69. data/spec/fixtures/ec2/instances.xml +88 -0
  70. data/spec/fixtures/ec2/internal_error.xml +2 -0
  71. data/spec/fixtures/ec2/invalid_amiid_error.xml +2 -0
  72. data/spec/fixtures/ec2/invalid_request_error.xml +2 -0
  73. data/spec/fixtures/ec2/key_pairs.xml +10 -0
  74. data/spec/fixtures/ec2/purchase_reserved_instances_offering.xml +5 -0
  75. data/spec/fixtures/ec2/purchase_reserved_instances_offerings.xml +6 -0
  76. data/spec/fixtures/ec2/regions.xml +14 -0
  77. data/spec/fixtures/ec2/register_image.xml +5 -0
  78. data/spec/fixtures/ec2/release_address.xml +5 -0
  79. data/spec/fixtures/ec2/reserved_instances.xml +18 -0
  80. data/spec/fixtures/ec2/reserved_instances_offering.xml +15 -0
  81. data/spec/fixtures/ec2/reserved_instances_offerings.xml +276 -0
  82. data/spec/fixtures/ec2/revoke_ip_access.xml +5 -0
  83. data/spec/fixtures/ec2/revoke_owner_group_access.xml +5 -0
  84. data/spec/fixtures/ec2/run_instances.xml +30 -0
  85. data/spec/fixtures/ec2/security_groups.xml +159 -0
  86. data/spec/fixtures/ec2/snapshots.xml +13 -0
  87. data/spec/fixtures/ec2/terminate_instances.xml +17 -0
  88. data/spec/fixtures/ec2/unassociated_address.xml +10 -0
  89. data/spec/fixtures/ec2/volumes.xml +23 -0
  90. data/spec/fixtures/errors/invalid_parameter_value.xml +2 -0
  91. data/spec/fixtures/s3/buckets.xml +2 -0
  92. data/spec/fixtures/s3/copy_failure.xml +23 -0
  93. data/spec/fixtures/s3/invalid_request_signature.xml +5 -0
  94. data/spec/fixtures/s3/keys.xml +2 -0
  95. data/spec/lib/awsum/ec2/address_spec.rb +149 -0
  96. data/spec/lib/awsum/ec2/availability_zones_spec.rb +21 -0
  97. data/spec/lib/awsum/ec2/image_spec.rb +92 -0
  98. data/spec/lib/awsum/ec2/instance_spec.rb +125 -0
  99. data/spec/lib/awsum/ec2/keypair_spec.rb +55 -0
  100. data/spec/lib/awsum/ec2/parsers/address_parser_spec.rb +51 -0
  101. data/spec/lib/awsum/ec2/parsers/availability_zone_parser_spec.rb +28 -0
  102. data/spec/lib/awsum/ec2/parsers/image_parser_spec.rb +66 -0
  103. data/spec/lib/awsum/ec2/parsers/instance_parser_spec.rb +75 -0
  104. data/spec/lib/awsum/ec2/parsers/keypair_parser_spec.rb +74 -0
  105. data/spec/lib/awsum/ec2/parsers/purchase_reserved_instances_offering_parser_spec.rb +14 -0
  106. data/spec/lib/awsum/ec2/parsers/region_parser_spec.rb +27 -0
  107. data/spec/lib/awsum/ec2/parsers/register_image_parser_spec.rb +15 -0
  108. data/spec/lib/awsum/ec2/parsers/reserved_instance_parser_spec.rb +35 -0
  109. data/spec/lib/awsum/ec2/parsers/reserved_instances_offering_parser_spec.rb +32 -0
  110. data/spec/lib/awsum/ec2/parsers/security_group_parser_spec.rb +78 -0
  111. data/spec/lib/awsum/ec2/parsers/snapshot_parser_spec.rb +30 -0
  112. data/spec/lib/awsum/ec2/parsers/volume_parser_spec.rb +35 -0
  113. data/spec/lib/awsum/ec2/region_spec.rb +73 -0
  114. data/spec/lib/awsum/ec2/reserved_instance_spec.rb +61 -0
  115. data/spec/lib/awsum/ec2/reserved_instances_offering_spec.rb +33 -0
  116. data/spec/lib/awsum/ec2/security_group_spec.rb +179 -0
  117. data/spec/lib/awsum/ec2/snapshots_spec.rb +69 -0
  118. data/spec/lib/awsum/ec2/volume_spec.rb +107 -0
  119. data/spec/lib/awsum/ec2_spec.rb +6 -0
  120. data/spec/lib/awsum/error_spec.rb +31 -0
  121. data/spec/lib/awsum/requestable_spec.rb +126 -0
  122. data/spec/lib/awsum/s3/bucket_spec.rb +95 -0
  123. data/spec/lib/awsum/s3/object_spec.rb +128 -0
  124. data/spec/lib/awsum/s3/parsers/bucket_parser_spec.rb +41 -0
  125. data/spec/lib/awsum/s3/parsers/object_parser_spec.rb +41 -0
  126. data/spec/spec_helper.rb +16 -0
  127. 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
@@ -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