ファイルアップロード
Rubyからファイルをアップロードする方法を探してみたけど見つからない。受けるサーバー側のコードはcgi.rbにあるのだけど。いろいろやってみたけど、普通にNet::HTTP::Postでセットするだけではmultipart/form-dataが送れないっぽい。できればnet/httpだけでやりたい...ということで、頭を悩ませつつWeb上のコードとRFCを参考にベタベタ書く事にした。
Net::HTTP::Postで作ったリクエストに対して、content-typeをmultipart/form-dataで設定。 body部分を生成してセット。それを通常通り送る方法でいけました。API用に作ったので、user/passとhttpオブジェクトが分離しています。
@username = "user" @password = "pass" @http = Net::HTTP.start("somedomain.com",80) def file_upload(path,options = Array.new) case File.extname(path) when ".jpg" then mime = "image/jpeg" when ".gif" then mime = "image/gif" when ".png" then mime = "image/png" end mime = options['mime'] unless options['mime'].nil? boundary = "AaB03x" data = "--#{boundary}\r\n" + "content-disposition: form-data; name=\"file\"; filename=\"#{File.basename(path)} \"\r\n" + "content-type: #{mime}\r\n" + "content-transfer-encoding: binary\r\n\r\n" + File.open(path).read + "\r\n" options.each{|k,v| data += "--#{boundary}\r\n" + "content-disposition: form-data; name=\"#{k}\"\r\n\r\n#{URI.encode(v)}\r\n" } data += "--#{boundary}--\r\n" req = Net::HTTP::Post.new("/file_upload.cgi") req['content-type'] = "multipart/form-data; boundary=#{boundary}" # req.basic_auth(@username,@password) req.body = data res = @http.request(req) res.body end