class Upload

Includes
Protocol::Multipart::Readable

A field-constrained streaming upload.

Nested Classes and Modules

class LimitError

Raised when a streaming upload exceeds its field size limit.

Definitions

def initialize(delegate, size_limit: nil)

Initialize a constrained upload.

Signature

parameter delegate Object

The underlying streaming upload.

parameter size_limit Integer | Nil

The maximum accepted size.

Implementation

def initialize(delegate, size_limit: nil)
	@delegate = delegate
	@size_limit = size_limit
	@size = 0
	@declared_media_type = nil
	
	if header = delegate.headers["content-type"]
		@declared_media_type = Protocol::Media::Type.parse(header.to_s)
	end
	
	@media_type = @declared_media_type
	
	# Fall back to the submitted filename when the declared type carries no useful classification:
	if !@media_type || @media_type.name == GENERIC_MEDIA_TYPE
		if record = Protocol::Media::Registry.for_path(self.filename)
			if record.type.name != GENERIC_MEDIA_TYPE
				@media_type = record.type
			end
		end
	end
end

def filename

The submitted filename.

Implementation

def filename
	return @delegate.filename
end

def headers

The multipart headers associated with this upload.

Implementation

def headers
	return @delegate.headers
end

attr :declared_media_type

The media type declared by the submitting client, if present.

attr :media_type

The declared media type, or the type inferred from the filename when the declaration is absent or generic.

attr :size_limit

The maximum accepted size, if configured.

attr :size

The number of bytes consumed through this constrained upload.

def ended?

Whether the complete upload has been consumed.

Implementation

def ended?
	return @delegate.ended?
end

def each(chunk_size = 8192)

Iterate over the upload while enforcing its field size limit.

Signature

parameter chunk_size Integer

The maximum chunk size.

yields {|chunk| ...}

Each upload chunk.

returns self

The upload.

raises LimitError

If the upload exceeds its field size limit.

Implementation

def each(chunk_size = 8192)
	return to_enum(:each, chunk_size) unless block_given?
	
	@delegate.each(chunk_size) do |chunk|
		@size += chunk.bytesize
		
		if @size_limit && @size > @size_limit
			raise LimitError, "Upload size exceeded field limit of #{@size_limit}!"
		end
		
		yield chunk
	end
	
	return self
end

def discard

Consume any unread upload content while enforcing the field size limit.

Signature

returns Nil

The upload content is discarded.

Implementation

def discard
	each {|_chunk|}
	return nil
end