awsum 0.5

Sign up to get free protection for your applications and to get access to all the features.
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