Class: RestCore::Payload::Multipart

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

Constant Summary collapse

EOL =
"\r\n"

Constants included from RestCore

ASYNC, CLIENT, DRY, FAIL, HIJACK, LOG, RestCore::PROMISE, REQUEST_HEADERS, REQUEST_METHOD, REQUEST_PATH, REQUEST_PAYLOAD, REQUEST_QUERY, REQUEST_URI, RESPONSE_BODY, RESPONSE_HEADERS, RESPONSE_KEY, RESPONSE_SOCKET, RESPONSE_STATUS, Simple, TIMER, Universal, VERSION

Instance Attribute Summary

Attributes inherited from RestCore::Payload

#io

Instance Method Summary collapse

Methods inherited from RestCore::Payload

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

Methods included from RestCore

eagerload, id

Constructor Details

#initialize(payload) ⇒ Multipart

Returns a new instance of Multipart.



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/rest-core/util/payload.rb', line 93

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



156
157
158
# File 'lib/rest-core/util/payload.rb', line 156

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

#closeObject



165
166
167
# File 'lib/rest-core/util/payload.rb', line 165

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

#headersObject



160
161
162
163
# File 'lib/rest-core/util/payload.rb', line 160

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

#mime_type(path) ⇒ Object



151
152
153
154
# File 'lib/rest-core/util/payload.rb', line 151

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

#part(k, v) ⇒ Object



109
110
111
112
113
114
115
116
117
# File 'lib/rest-core/util/payload.rb', line 109

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



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

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



119
120
121
# File 'lib/rest-core/util/payload.rb', line 119

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