Skip to content

Instantly share code, notes, and snippets.

@rkh
Forked from jergason/app.rb
Created August 10, 2011 10:12
Show Gist options
  • Select an option

  • Save rkh/1136499 to your computer and use it in GitHub Desktop.

Select an option

Save rkh/1136499 to your computer and use it in GitHub Desktop.
Checking size of each request
require 'rack'
##
# Tries to calculate size of the complete response.
# This middleware should be chained in front of everything else.
# Middleware taking care of compression, etag handling etc could
# produce wrong results.
#
# Leaves streaming intact and does work file bodies from sockets
# and files.
#
# Assumes server supports keep-alive for HTTP 1.0 requests.
#
# This code has not been tested, I just wrote it down to
# demonstrate the general approach!
#
# Usage:
#
# use(ResponseSize) { |size| puts "size is: #{size}" }
#
# Enjoy!
class ResponseSize
# we need this to not sabotage streaming
class Proxy < Rack::BodyProxy
def initialize(body, size, &callback)
super(body) { callback.call(@size) }
@size = size
end
def each
@body.each do |str|
@size += str.bytesize
yield str
end
end
end
BASE_OVERHEAD = "HTTP/1.1 xxx \r\n\r\n".bytesize
KEEP_ALIVE = "Connection: Keep-Alive\r\n".bytesize
HEADER_OVERHEAD = ": \r\n".bytesize
def initialize(app, &callback)
@app, @callback = app, callback
end
def call(env)
status, headers, body = @app.call(env)
# base overhead for every response
size = BASE_OVERHEAD
# size of the http messsage, like the "OK" in "HTTP/1.1 200 OK"
size += Rack::Utils::HTTP_STATUS_CODES[status.to_i].bytesize
# header size
header.each do |key, values|
values.split("\n").each do |value|
size += key.bytesize + value.bytesize + HEADER_OVERHEAD
end
end
# body size
if headers['Content-Length'] or [204, 304].include?(status.to_i)
size += KEEP_ALIVE if env['HTTP_VERSION'] == 'HTTP/1.0'
size += Integer headers['Content-Length']
callback.call(size)
else
body = Proxy.new(body, size, &callback)
end
# you still want to send that response, right?
[status, headers, body]
end
end
@rkh
Copy link
Copy Markdown
Author

rkh commented Aug 14, 2011

thanks, updated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment