Class: Appship::MultipartBody

Inherits:
Object
  • Object
show all
Defined in:
lib/appship/uploader.rb

Instance Method Summary collapse

Constructor Details

#initialize(fields, file, boundary, progress: nil) ⇒ MultipartBody

Returns a new instance of MultipartBody.



430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
# File 'lib/appship/uploader.rb', line 430

def initialize(fields, file, boundary, progress: nil)
  @progress = progress
  @file_size = File.size(file)
  @segments = []
  fields.each do |name, value|
    @segments << "--#{boundary}\r\n"
    @segments << "Content-Disposition: form-data; name=\"#{name}\"\r\n\r\n"
    @segments << value.to_s
    @segments << "\r\n"
  end
  @segments << "--#{boundary}\r\n"
  @segments << "Content-Disposition: form-data; name=\"file\"; filename=\"#{File.basename(file)}\"\r\n"
  @segments << "Content-Type: application/octet-stream\r\n\r\n"
  @file = File.open(file, "rb")
  @segments << @file
  @segments << "\r\n--#{boundary}--\r\n"
  @index = 0
  @offset = 0
  @length = @segments.sum { |segment| segment.respond_to?(:read) ? segment.size : segment.bytesize }
end

Instance Method Details

#lengthObject



451
452
453
# File 'lib/appship/uploader.rb', line 451

def length
  @length
end

#read(length = nil, out_buffer = nil) ⇒ Object



455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
# File 'lib/appship/uploader.rb', line 455

def read(length = nil, out_buffer = nil)
  requested = length || 16 * 1024
  result = out_buffer || +""
  result.clear
  while result.bytesize < requested && @index < @segments.length
    segment = @segments[@index]
    if segment.respond_to?(:read)
      chunk = segment.read(requested - result.bytesize)
      if chunk.nil? || chunk.empty?
        segment.close unless segment.closed?
        @index += 1
      else
        result << chunk
        if segment.equal?(@file)
          @progress&.call(@file.tell, @file_size)
        end
      end
    else
      remaining = segment.byteslice(@offset, requested - result.bytesize)
      if remaining.nil? || remaining.empty?
        @index += 1
        @offset = 0
      else
        result << remaining
        @offset += remaining.bytesize
        if @offset >= segment.bytesize
          @index += 1
          @offset = 0
        end
      end
    end
  end
  result.empty? ? nil : result
end