class UploadIO

Overview

UploadIO supports chunked uploads with a built-in progress callback and provides upload cancellation through either a callback or direct method call.

require "upload_io"
require "http/client"

file = File.open("/path/to/file")
size = file.size
uploaded_total = 0

upload_io = UploadIO.new(file, 4096, ->(uploaded_chunk : Int32) {
  uploaded_total += uploaded_chunk
  puts "Uploaded: #{uploaded_total} / #{size} bytes"
})

headers = HTTP::Headers{
  "Content-Type"   => "application/octet-stream",
  "Content-Length" => size.to_s,
}

response = HTTP::Client.post("http://example.com/upload", headers: headers, body: upload_io)
puts "Upload complete! Response: #{response.status_code}"

Defined in:

upload_io.cr

Constant Summary

CHUNK_SIZE = 4096
VERSION = {{ (`shards version /srv/crystaldoc.info/github-mamantoha-upload_io-v0.5.3/src`).chomp.stringify }}

Constructors

Instance Method Summary

Constructor Detail

def self.new(data : HTTP::Client::BodyType, chunk_size : Int32, on_progress : Proc(Int32, Nil) | Nil = nil, should_cancel : Proc(Bool) | Nil = nil, *, max_speed : Int64 | Nil = nil) #

Creates a new UploadIO with given arguments.

  • data - the upload data source
  • chunk_size - the size of each chunk to be read
  • #on_progress - optional callback to track progress
  • #should_cancel - optional callback to control upload cancellation
  • #max_speed - optional maximum upload speed in bytes per second

[View source]
def self.new(data : HTTP::Client::BodyType, chunk_size : Int32 = CHUNK_SIZE, &block : self -> ) #

Creates a new UploadIO with a block for configuration.

file = File.open("/path/to/file")
size = file.size
uploaded_total = 0

upload_io = UploadIO.new(file) do |io|
  io.on_progress ->(uploaded_chunk : Int32) do
    uploaded_total += uploaded_chunk
    puts "Uploaded: #{uploaded_total} / #{size} bytes"
  end

  io.should_cancel -> { uploaded_total >= size / 2 }
  io.max_speed = 125_000 # 1 Mbps
end

response = HTTP::Client.post("http://example.com/upload", body: upload_io)

[View source]
def self.new(data : HTTP::Client::BodyType, on_progress : Proc(Int32, Nil) | Nil = nil, should_cancel : Proc(Bool) | Nil = nil, *, max_speed : Int64 | Nil = nil) #

[View source]

Instance Method Detail

def cancel #

Cancels the upload process. After calling this method:

  • Subsequent reads will return 0 bytes
  • If the data source is an IO, it will be closed
  • The upload cannot be resumed

[View source]
def cancelled? : Bool #

Returns true if the upload has been cancelled


[View source]
def max_speed : Int64 | Nil #

Maximum upload speed in bytes per second. If nil, no speed limit is applied.


[View source]
def max_speed=(max_speed : Int64 | Nil) #

Maximum upload speed in bytes per second. If nil, no speed limit is applied.


[View source]
def on_progress(on_progress : Proc(Int32, Nil)) #

Optional callback function that receives the size of each uploaded chunk.

file = File.open("/path/to/file")
size = file.size
uploaded_total = 0

upload_io = UploadIO.new(file)
upload_io.on_progress ->(uploaded_chunk : Int32) do
  uploaded_total += uploaded_chunk
  puts "Uploaded: #{uploaded_total} / #{size} bytes"
end

response = HTTP::Client.post("http://example.com/upload", body: upload_io)

[View source]
def pause #

Pauses the upload process. While paused:

  • Subsequent reads will block until #resume is called
  • The upload can be resumed using the #resume method

[View source]
def paused? : Bool #

Returns true if the upload is currently paused


[View source]
def read(slice : Bytes) : Int32 #

Reads the next chunk of data and copies it into the provided buffer.

This method is called automatically by HTTP::Client when sending data. It reads up to chunk_size bytes and updates the upload progress.

Returns the number of bytes that will be sent to the server (not the total sent bytes).

Since UploadIO only provides data to HTTP::Client, we can only track the amount of data read and not the actual bytes transmitted to the server.


[View source]
def resume #

Resumes a paused upload. After calling this method:

  • Subsequent reads will continue from where they left off

[View source]
def rewind #
Description copied from class IO

Rewinds this IO. By default this method raises, but including types may implement it.


[View source]
def should_cancel(should_cancel : Proc(Bool)) #

Optional callback function that determines if the upload should be cancelled. Return true to cancel the upload.

file = File.open("/path/to/file")
start_time = Time.monotonic

upload_io = UploadIO.new(file)
# Stop upload after 5 seconds
upload_io.should_cancel -> { (Time.monotonic - start_time).total_seconds > 5 }

response = HTTP::Client.post("http://example.com/upload", body: upload_io)

[View source]
def uploaded : Int64 #

Tracks the total bytes uploaded so far.


[View source]
def write(slice : Bytes) : Nil #

Required method by IO but not used in UploadIO.

UploadIO is read-only, so #write does nothing.


[View source]