Guest User

Untitled

a guest
Jun 21st, 2018
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.40 KB | None | 0 0
  1. require "tempfile"
  2. require "stringio"
  3.  
  4. module RestClient
  5. module Payload
  6. extend self
  7.  
  8. def generate(params)
  9. if params.is_a?(String)
  10. Base.new(params)
  11. elsif params.delete(:multipart) == true ||
  12. params.any? { |_,v| v.respond_to?(:path) && v.respond_to?(:read) }
  13. Multipart.new(params)
  14. else
  15. UrlEncoded.new(params)
  16. end
  17. end
  18.  
  19. class Base
  20. def initialize(params)
  21. build_stream(params)
  22. end
  23.  
  24. def build_stream(params)
  25. @stream = StringIO.new(params)
  26. @stream.seek(0)
  27. end
  28.  
  29. def read(bytes=nil)
  30. @stream.read(bytes)
  31. end
  32. alias :to_s :read
  33.  
  34. def escape(v)
  35. URI.escape(v.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
  36. end
  37.  
  38. def headers
  39. { 'Content-Length' => size.to_s }
  40. end
  41.  
  42. def size
  43. @stream.size
  44. end
  45. alias :length :size
  46.  
  47. def close
  48. @stream.close
  49. end
  50. end
  51.  
  52. class UrlEncoded < Base
  53. def build_stream(params)
  54. @stream = StringIO.new(params.map do |k,v|
  55. "#{escape(k)}=#{escape(v)}"
  56. end.join("&"))
  57. @stream.seek(0)
  58. end
  59.  
  60. def headers
  61. super.merge({ 'Content-Type' => 'application/x-www-form-urlencoded' })
  62. end
  63. end
  64.  
  65. class Multipart < Base
  66. EOL = "\r\n"
  67.  
  68. def build_stream(params)
  69. b = "--#{boundary}"
  70.  
  71. @stream = Tempfile.new("RESTClient.Stream.#{rand(1000)}")
  72. @stream.write(b + EOL)
  73. params.each do |k,v|
  74. if v.respond_to?(:read) && v.respond_to?(:path)
  75. create_file_field(@stream, k,v)
  76. else
  77. create_regular_field(@stream, k,v)
  78. end
  79. @stream.write(EOL + b)
  80. end
  81. @stream.write('--')
  82. @stream.write(EOL)
  83. @stream.seek(0)
  84. end
  85.  
  86. def create_regular_field(s, k, v)
  87. s.write("Content-Disposition: multipart/form-data; name=\"#{k}\"")
  88. s.write(EOL)
  89. s.write(EOL)
  90. s.write(v)
  91. end
  92.  
  93. def create_file_field(s, k, v)
  94. begin
  95. s.write("Content-Disposition: multipart/form-data; name=\"#{k}\"; filename=\"#{v.path}\"#{EOL}")
  96. s.write("Content-Type: #{mime_for(v.path)}#{EOL}")
  97. s.write(EOL)
  98. while data = v.read(8124)
  99. s.write(data)
  100. end
  101. ensure
  102. v.close
  103. end
  104. end
  105.  
  106. def mime_for(path)
  107. ext = File.extname(path)[1..-1]
  108. MIME_TYPES[ext] || 'text/plain'
  109. end
  110.  
  111. def boundary
  112. @boundary ||= rand(1_000_000).to_s
  113. end
  114.  
  115. def headers
  116. super.merge({'Content-Type' => %Q{multipart/form-data; boundary="#{boundary}"}})
  117. end
  118.  
  119. def close
  120. @stream.close
  121. end
  122. end
  123.  
  124. # :stopdoc:
  125. # From WEBrick.
  126. MIME_TYPES = {
  127. "ai" => "application/postscript",
  128. "asc" => "text/plain",
  129. "avi" => "video/x-msvideo",
  130. "bin" => "application/octet-stream",
  131. "bmp" => "image/bmp",
  132. "class" => "application/octet-stream",
  133. "cer" => "application/pkix-cert",
  134. "crl" => "application/pkix-crl",
  135. "crt" => "application/x-x509-ca-cert",
  136. "css" => "text/css",
  137. "dms" => "application/octet-stream",
  138. "doc" => "application/msword",
  139. "dvi" => "application/x-dvi",
  140. "eps" => "application/postscript",
  141. "etx" => "text/x-setext",
  142. "exe" => "application/octet-stream",
  143. "gif" => "image/gif",
  144. "gz" => "application/x-gzip",
  145. "htm" => "text/html",
  146. "html" => "text/html",
  147. "jpe" => "image/jpeg",
  148. "jpeg" => "image/jpeg",
  149. "jpg" => "image/jpeg",
  150. "js" => "text/javascript",
  151. "lha" => "application/octet-stream",
  152. "lzh" => "application/octet-stream",
  153. "mov" => "video/quicktime",
  154. "mpe" => "video/mpeg",
  155. "mpeg" => "video/mpeg",
  156. "mpg" => "video/mpeg",
  157. "pbm" => "image/x-portable-bitmap",
  158. "pdf" => "application/pdf",
  159. "pgm" => "image/x-portable-graymap",
  160. "png" => "image/png",
  161. "pnm" => "image/x-portable-anymap",
  162. "ppm" => "image/x-portable-pixmap",
  163. "ppt" => "application/vnd.ms-powerpoint",
  164. "ps" => "application/postscript",
  165. "qt" => "video/quicktime",
  166. "ras" => "image/x-cmu-raster",
  167. "rb" => "text/plain",
  168. "rd" => "text/plain",
  169. "rtf" => "application/rtf",
  170. "sgm" => "text/sgml",
  171. "sgml" => "text/sgml",
  172. "tif" => "image/tiff",
  173. "tiff" => "image/tiff",
  174. "txt" => "text/plain",
  175. "xbm" => "image/x-xbitmap",
  176. "xls" => "application/vnd.ms-excel",
  177. "xml" => "text/xml",
  178. "xpm" => "image/x-xpixmap",
  179. "xwd" => "image/x-xwindowdump",
  180. "zip" => "application/zip",
  181. }
  182. # :startdoc:
  183. end
  184. end
Add Comment
Please, Sign In to add comment