Class: RestBuilder::Payload::Multipart

Inherits:
Streamed show all
Defined in:
lib/rest-builder/payload.rb

Constant Summary collapse

EOL =
"\r\n"

Instance Attribute Summary

Attributes inherited from RestBuilder::Payload

#io

Instance Method Summary collapse

Methods inherited from RestBuilder::Payload

#closed?, generate, generate_with_headers, #read, #size

Constructor Details

#initialize(payload) ⇒ Multipart

Returns a new instance of Multipart.



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/rest-builder/payload.rb', line 96

def initialize payload
  super(Tempfile.new("rest-core.payload.#{boundary}"))

  io.binmode

  payload.each_with_index do |(k, v), i|
    if v.kind_of?(Array)
      v.each{ |vv| part(k, vv) }
    else
      part(k, v)
    end
  end
  io.write("--#{boundary}--#{EOL}")
  io.rewind
end

Instance Method Details

#boundaryObject



159
160
161
# File 'lib/rest-builder/payload.rb', line 159

def boundary
  @boundary ||= rand(1_000_000).to_s
end

#closeObject



168
169
170
# File 'lib/rest-builder/payload.rb', line 168

def close
  io.close! unless io.closed?
end

#headersObject



163
164
165
166
# File 'lib/rest-builder/payload.rb', line 163

def headers
  super.merge('Content-Type' =>
                "multipart/form-data; boundary=#{boundary}")
end

#mime_type(path) ⇒ Object



154
155
156
157
# File 'lib/rest-builder/payload.rb', line 154

def mime_type path
  mime = MIME::Types.type_for(path)
  mime.first && mime.first.content_type
end

#part(k, v) ⇒ Object



112
113
114
115
116
117
118
119
120
# File 'lib/rest-builder/payload.rb', line 112

def part k, v
  io.write("--#{boundary}#{EOL}Content-Disposition: form-data")
  io.write("; name=\"#{k}\"") if k
  if v.respond_to?(:read)
    part_binary(k, v)
  else
    part_plantext(k, v)
  end
end

#part_binary(k, v) ⇒ Object



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/rest-builder/payload.rb', line 126

def part_binary k, v
  if v.respond_to?(:original_filename)                   # Rails
    io.write("; filename=\"#{v.original_filename}\"#{EOL}")
  elsif v.respond_to?(:path)                             # files
    io.write("; filename=\"#{File.basename(v.path)}\"#{EOL}")
  else                                                   # io
    io.write("; filename=\"#{k}\"#{EOL}")
  end

  # supply your own content type for regular files, will you?
  if v.respond_to?(:content_type)                        # Rails
    io.write("Content-Type: #{v.content_type}#{EOL}#{EOL}")
  elsif v.respond_to?(:path) && type = mime_type(v.path) # files
    io.write("Content-Type: #{type}#{EOL}#{EOL}")
  else
    io.write(EOL)
  end

  while data = v.read(8192)
    io.write(data)
  end

  io.write(EOL)

ensure
  v.close if v.respond_to?(:close)
end

#part_plantext(k, v) ⇒ Object



122
123
124
# File 'lib/rest-builder/payload.rb', line 122

def part_plantext k, v
  io.write("#{EOL}#{EOL}#{v}#{EOL}")
end