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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
|
# stdlib
require "securerandom"
# internal
require "http/form_data/multipart/param"
module HTTP
module FormData
# `multipart/form-data` form data.
class Multipart
# @param [#to_h, Hash] data form data key-value Hash
def initialize(data)
@parts = Param.coerce FormData.ensure_hash data
@boundary = ("-" * 21) << SecureRandom.hex(21)
@content_length = nil
end
# Returns content to be used for HTTP request body.
#
# @return [String]
def to_s
head + @parts.map(&:to_s).join(glue) + tail
end
# Returns MIME type to be used for HTTP request `Content-Type` header.
#
# @return [String]
def content_type
"multipart/form-data; boundary=#{@boundary}"
end
# Returns form data content size to be used for HTTP request
# `Content-Length` header.
#
# @return [Fixnum]
def content_length
unless @content_length
@content_length = head.bytesize + tail.bytesize
@content_length += @parts.map(&:size).reduce(:+)
@content_length += (glue.bytesize * (@parts.count - 1))
end
@content_length
end
private
# @return [String]
def head
@head ||= "--#{@boundary}#{CRLF}"
end
# @return [String]
def glue
@glue ||= "#{CRLF}--#{@boundary}#{CRLF}"
end
# @return [String]
def tail
@tail ||= "#{CRLF}--#{@boundary}--"
end
end
end
end
|