Class: Agouti::Rack::PackageLimiter

Inherits:
Object
  • Object
show all
Defined in:
lib/agouti/rack/package_limiter.rb

Overview

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

Defined Under Namespace

Classes: GzipTruncatedStream, InvalidHeaderException

Constant Summary

ENABLE_HEADER =
'X-Agouti-Enable'
LIMIT_HEADER =
'X-Agouti-Limit'
DEFAULT_LIMIT =

Public: Default limit of bytes.

14000

Instance Method Summary (collapse)

Constructor Details

- (PackageLimiter) initialize(app)

Public: Constructor.

app - rack app instance

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



20
21
22
# File 'lib/agouti/rack/package_limiter.rb', line 20

def initialize(app)
  @app = app
end

Instance Method Details

- (Object) call(env)

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.



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# 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'] == '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