Class: Candid::Internal::Multipart::Encoder Private
- Inherits:
-
Object
- Object
- Candid::Internal::Multipart::Encoder
- Defined in:
- lib/candid/internal/multipart/multipart_encoder.rb
Overview
This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.
Encodes parameters into a ‘multipart/form-data` payload as described by RFC 2388:
https://tools.ietf.org/html/rfc2388
This is most useful for transferring file-like objects.
Parameters should be added with ‘#encode`. When ready, use `#body` to get the encoded result and `#content_type` to get the value that should be placed in the `Content-Type` header of a subsequent request (which includes a boundary value).
This abstraction is heavily inspired by Stripe’s multipart/form-data implementation, which can be found here:
https://github.com/stripe/stripe-ruby/blob/ca00b676f04ac421cf5cb5ff0325f243651677b6/lib/stripe/multipart_encoder.rb#L18
Constant Summary collapse
- CONTENT_TYPE =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
"multipart/form-data"- CRLF =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
"\r\n"
Instance Attribute Summary collapse
- #body ⇒ Object readonly private
- #boundary ⇒ Object readonly private
Instance Method Summary collapse
-
#close ⇒ nil
private
Finalizes the encoder by writing the final boundary.
-
#content_type ⇒ String
private
Gets the content type string including the boundary.
-
#encode(form_data) ⇒ String
private
Encode the given FormData object into a multipart/form-data payload.
-
#initialize ⇒ Encoder
constructor
private
A new instance of Encoder.
-
#write_field(name:, data:, filename: nil, headers: nil) ⇒ nil
private
Writes a field to the encoder.
-
#write_part(part) ⇒ nil
private
Writes a FormDataPart to the encoder.
Constructor Details
#initialize ⇒ Encoder
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns a new instance of Encoder.
30 31 32 33 34 35 36 37 38 39 |
# File 'lib/candid/internal/multipart/multipart_encoder.rb', line 30 def initialize # Chose the same number of random bytes that Go uses in its standard # library implementation. Easily enough entropy to ensure that it won't # be present in a file we're sending. @boundary = SecureRandom.hex(30) @body = String.new @closed = false @first_field = true end |
Instance Attribute Details
#body ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
28 29 30 |
# File 'lib/candid/internal/multipart/multipart_encoder.rb', line 28 def body @body end |
#boundary ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
28 29 30 |
# File 'lib/candid/internal/multipart/multipart_encoder.rb', line 28 def boundary @boundary end |
Instance Method Details
#close ⇒ nil
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Finalizes the encoder by writing the final boundary.
119 120 121 122 123 124 125 126 127 |
# File 'lib/candid/internal/multipart/multipart_encoder.rb', line 119 def close raise "Encoder already closed" if @closed @body << CRLF @body << "--#{@boundary}--" @closed = true nil end |
#content_type ⇒ String
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Gets the content type string including the boundary.
44 45 46 |
# File 'lib/candid/internal/multipart/multipart_encoder.rb', line 44 def content_type "#{CONTENT_TYPE}; boundary=#{@boundary}" end |
#encode(form_data) ⇒ String
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Encode the given FormData object into a multipart/form-data payload.
52 53 54 55 56 57 58 59 60 61 |
# File 'lib/candid/internal/multipart/multipart_encoder.rb', line 52 def encode(form_data) return "" if form_data.parts.empty? form_data.parts.each do |part| write_part(part) end close @body end |
#write_field(name:, data:, filename: nil, headers: nil) ⇒ nil
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Writes a field to the encoder.
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/candid/internal/multipart/multipart_encoder.rb', line 87 def write_field(name:, data:, filename: nil, headers: nil) raise "Cannot write to closed encoder" if @closed if @first_field @first_field = false else @body << CRLF end @body << "--#{@boundary}#{CRLF}" @body << %(Content-Disposition: form-data; name="#{escape(name.to_s)}") @body << %(; filename="#{escape(filename)}") if filename @body << CRLF if headers headers.each do |key, value| @body << "#{key}: #{value}#{CRLF}" end elsif filename # Default content type for files. @body << "Content-Type: application/octet-stream#{CRLF}" end @body << CRLF @body << data.to_s nil end |
#write_part(part) ⇒ nil
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Writes a FormDataPart to the encoder.
67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/candid/internal/multipart/multipart_encoder.rb', line 67 def write_part(part) raise "Cannot write to closed encoder" if @closed write_field( name: part.name, data: part.contents, filename: part.filename, headers: part.headers ) nil end |