Protocol::HTTPSourceProtocolHTTPBodyDigestable

class Digestable

Invokes a callback once the body has finished reading.

Definitions

def self.wrap(message, digest = Digest::SHA256.new, &block)

Wrap a message body with a callback. If the body is empty, the callback is not invoked, as there is no data to digest.

Signature

parameter message Request | Response

the message body.

parameter digest Digest

the digest to use.

parameter block Proc

the callback to invoke when the body is closed.

Implementation

def self.wrap(message, digest = Digest::SHA256.new, &block)
	if body = message&.body and !body.empty?
		message.body = self.new(message.body, digest, block)
	end
end

def initialize(body, digest = Digest::SHA256.new, callback = nil)

Initialize the digestable body with a callback.

Signature

parameter body Readable

the body to wrap.

parameter digest Digest

the digest to use.

parameter callback Block

The callback is invoked when the digest is complete.

Implementation

def initialize(body, digest = Digest::SHA256.new, callback = nil)
	super(body)
	
	@digest = digest
	@callback = callback
end

attr :digest

Signature

attribute Digest

digest the digest object.

def etag(weak: false)

Generate an appropriate ETag for the digest, assuming it is complete. If you call this method before the body is fully read, the ETag will be incorrect.

Signature

parameter weak Boolean

If true, the ETag is marked as weak.

returns String

the ETag.

Implementation

def etag(weak: false)
	if weak
		"W/\"#{digest.hexdigest}\""
	else
		"\"#{digest.hexdigest}\""
	end
end

def read

Read the body and update the digest. When the body is fully read, the callback is invoked with self as the argument.

Signature

returns String | Nil

the next chunk of data, or nil if the body is fully read.

Implementation

def read
	if chunk = super
		@digest.update(chunk)
		
		return chunk
	else
		@callback&.call(self)
		
		return nil
	end
end