Skip to content

Instantly share code, notes, and snippets.

@rkh
Forked from jergason/app.rb
Created August 10, 2011 10:12
Show Gist options
  • Save rkh/1136499 to your computer and use it in GitHub Desktop.
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
@jacaetevha
Copy link

Lines 63 & 65 should be 'Content-Length'

@rkh
Copy link
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