class Agouti::Rack::PackageLimiter

Public: rack middleware that truncates the gzipped response. Useful for testing critical rendering path optimization.

Constants

DEFAULT_LIMIT

Public: Default limit of bytes.

ENABLE_HEADER
LIMIT_HEADER

Public Class Methods

new(app) click to toggle source

Public: Constructor.

app - rack app instance

Returns an instance of Agouti::Rack::PackageLimiter middleware.

# File lib/agouti/rack/package_limiter.rb, line 20
def initialize(app)
  @app = app
end

Public Instance Methods

call(env) click to toggle source

Public: Apply middleware to request.

env - environment.

Raises Agouti::Rack::PackageLimiter::InvalidHeaderException if headers are not valid. The following values are accepted:

X-Agouti-Enable:
- header not present or set with value 0(disabled).
- header set with value 1 (enabled).
X-Agouti-Limit: a positive integer.

The response body is gzipped only when the following conditions are met:

Header X-Agouti-Enable set with value 1 and header Content-Type with value 'text/html'.
If header X-Agouti-Limit is set, response body will be truncated to the given number of bytes.
Otherwise, body will be truncated to the default limit, which is 14000 bytes.

If header X-Agouti-Enable is enabled but header Content-Type does not have value ‘text/html’, the middleware will return a response with status code 204 and empty body.

If header X-Agouti-Enable has value 0 or is empty, the response will not be modified.

# File lib/agouti/rack/package_limiter.rb, line 43
def call(env)
  raise InvalidHeaderException unless valid?(env)

  status, headers, body = @app.call(env)

  set_limit(env)

  if enabled?(env)
    unless headers['Content-Type'] && headers['Content-Type'].include?('text/html')
      return [204, {}, []]
    end

    headers = ::Rack::Utils::HeaderHash.new(headers)

    headers['Content-Encoding'] = 'gzip'
    headers.delete('Content-Length')
    mtime = headers.key?('Last-Modified') ? Time.httpdate(headers['Last-Modified']) : Time.now

    [status, headers, GzipTruncatedStream.new(body, mtime, @limit)]
  else
    [status, headers, body]
  end
end

Private Instance Methods

enabled?(env) click to toggle source
# File lib/agouti/rack/package_limiter.rb, line 73
def enabled? env
  get_http_header(env, ENABLE_HEADER).to_i == 1
end
get_http_header(env, header) click to toggle source
# File lib/agouti/rack/package_limiter.rb, line 69
def get_http_header env, header
  env["HTTP_#{header.upcase.gsub('-', '_')}"]
end
parseable?(header) click to toggle source
# File lib/agouti/rack/package_limiter.rb, line 85
def parseable?(header)
  (header =~ /^[0-9]+$/) == 0
end
set_limit(env) click to toggle source
# File lib/agouti/rack/package_limiter.rb, line 77
def set_limit env
  @limit = (get_http_header(env, LIMIT_HEADER)) ? get_http_header(env, LIMIT_HEADER).to_i : DEFAULT_LIMIT
end
valid?(env) click to toggle source
# File lib/agouti/rack/package_limiter.rb, line 81
def valid? env
  valid_enable_header?(env) && valid_limit_header?(env)
end