Class: Protocol::HTTP::AcceptEncoding

Inherits:
Middleware show all
Defined in:
lib/protocol/http/accept_encoding.rb

Overview

A middleware that sets the accept-encoding header and decodes the response according to the content-encoding header.

Constant Summary collapse

ACCEPT_ENCODING =

The header used to request encodings.

"accept-encoding".freeze
CONTENT_ENCODING =

The header used to specify encodings.

"content-encoding".freeze
DEFAULT_WRAPPERS =

The default wrappers to use for decoding content.

{
	"gzip" => Body::Inflate.method(:for),
	"identity" => ->(body) {body}, # Identity means no encoding
	
	# There is no point including this:
	# 'identity' => ->(body){body},
}

Constants inherited from Methods

Methods::CONNECT, Methods::DELETE, Methods::GET, Methods::HEAD, Methods::OPTIONS, Methods::PATCH, Methods::POST, Methods::PUT, Methods::TRACE

Instance Attribute Summary

Attributes inherited from Middleware

#delegate

Instance Method Summary collapse

Methods inherited from Middleware

#The delegate object that is used for passing along requests that are not handled by *this* middleware.=, build, #close, for

Methods inherited from Methods

each, valid?

Constructor Details

#initialize(delegate, wrappers = DEFAULT_WRAPPERS) ⇒ AcceptEncoding

Initialize the middleware with the given delegate and wrappers.



34
35
36
37
38
39
# File 'lib/protocol/http/accept_encoding.rb', line 34

def initialize(delegate, wrappers = DEFAULT_WRAPPERS)
	super(delegate)
	
	@accept_encoding = wrappers.keys.join(", ")
	@wrappers = wrappers
end

Instance Method Details

#call(request) ⇒ Object

Set the accept-encoding header and decode the response body.



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/protocol/http/accept_encoding.rb', line 45

def call(request)
	request.headers[ACCEPT_ENCODING] = @accept_encoding
	
	response = super
	
	if body = response.body and !body.empty?
		if content_encoding = response.headers[CONTENT_ENCODING]
			# Process encodings in reverse order and remove them when they are decoded:
			while name = content_encoding.last
				# Look up wrapper with case-insensitive matching:
				wrapper = @wrappers[name.downcase]
				
				if wrapper
					body = wrapper.call(body)
					# Remove the encoding we just processed:
					content_encoding.pop
				else
					# Unknown encoding - stop processing here:
					break
				end
			end
			
			# Update the response body:
			response.body = body
			
			# Remove the content-encoding header if we decoded all encodings:
			if content_encoding.empty?
				response.headers.delete(CONTENT_ENCODING)
			end
		end
	end
	
	return response
end