Skip to content

Instantly share code, notes, and snippets.

@troelskn
Created October 27, 2017 09:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save troelskn/98b4863e7e1b2606bb8a32a78f06a625 to your computer and use it in GitHub Desktop.
Save troelskn/98b4863e7e1b2606bb8a32a78f06a625 to your computer and use it in GitHub Desktop.
Low level implementation of multipart post, using net/http
# Low level implementation of multipart post, using net/http
class MultipartPost
def initialize(uri:)
@uri = uri
@post_body = []
end
def send
request = Net::HTTP::Post.new(@uri.request_uri)
request.body = build_body
request["Content-Type"] = "multipart/form-data; boundary=#{multipart_boundary}"
request["Origin"] = "http://#{@uri.host}"
http_connection.request(request)
end
def multipart_boundary
@multipart_boundary ||= SecureRandom.hex
end
def http_connection
@http_connection ||= Net::HTTP.new(@uri.host, @uri.port)
end
def build_body
fail "No post fields added" if @post_body.empty?
@post_body.join + "--#{multipart_boundary}--\r\n"
end
def add_field(name:, value:)
@post_body << "--#{multipart_boundary}\r\n"
@post_body << "Content-Disposition: form-data; name=\"#{name}\"\r\n"
@post_body << "\r\n"
@post_body << value
@post_body << "\r\n"
end
def add_file(name:, contents:, filename:, content_type: "application/octet-stream")
@post_body << "--#{multipart_boundary}\r\n"
@post_body << "Content-Disposition: form-data; name=\"#{name}\"; filename=\"#{filename}\"\r\n"
@post_body << "Content-Type: #{content_type}; charset=#{contents.encoding.to_s}\r\n"
@post_body << "\r\n"
@post_body << contents
@post_body << "\r\n"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment