Skip to content

Instantly share code, notes, and snippets.

@mimosa
Created July 19, 2013 05:52
Show Gist options
  • Save mimosa/6036945 to your computer and use it in GitHub Desktop.
Save mimosa/6036945 to your computer and use it in GitHub Desktop.
```ruby multi_part = nil File.open('/Users/howl/Downloads/babyhead.gif', 'rb') { |photo| multi_part = Nestful::MultiPart.new 'https://open.t.qq.com/api/t/add', { content: 'helloworld', longitude: 113.421234, latitude: 22.354231, syncflag: 0, compatibleflag: 0, format: 'json', access_token: '9895a065c73a06a6d43d9491cc7cfea7', oauth_consumer_key: …
# -*- encoding: utf-8 -*-
require 'mime/types'
require 'nestful'
require 'uri'
module Nestful
class MultiPart
def initialize(url, parts, crlf = nil)
@crlf = crlf || "\r\n"
@url = url
build_multipart_bodies(parts)
end
def url
@url
end
def body
@body
end
def headers
@headers
end
protected
def build_multipart_bodies(parts)
boundary = Time.now.to_i.to_s(16)
body = bin_encode('')
parts.each do |key, value|
esc_key = escape(key.to_s)
body << bin_encode("--#{boundary}#{@crlf}")
if value.respond_to?(:read)
filename = File.basename(value.path)
mime_type = mime_type( filename )
body << bin_encode("Content-Disposition: form-data; name=\"#{esc_key}\"; filename=\"#{filename}\"#{@crlf}")
body << bin_encode("Content-Type: #{mime_type}#{@crlf}")
body << bin_encode("Content-Transfer-Encoding: binary#{@crlf*2}")
body << bin_encode(value.read)
else
body << bin_encode("Content-Disposition: form-data; name=\"#{esc_key}\"#{@crlf*2}#{value}")
end
body << bin_encode(@crlf)
end
body << bin_encode("--#{boundary}--#{@crlf*2}")
@headers = { "Content-Type" => "multipart/form-data; boundary=#{boundary}" }
@body = request(body).execute.body
end
private
def request(body)
req = Nestful::Request.new(@url)
req.body = body
req.headers = @headers
req.method = :post
return req
end
def escape(s)
URI.encode_www_form_component(s)
end
def bin_encode(chunk)
chunk.force_encoding(Encoding::BINARY) if chunk.respond_to? :force_encoding
end
def mime_type(filename)
MIME::Types.type_for( filename ).first.to_s
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment