Module: Hyperion::Adapter::Rack
- Defined in:
- lib/hyperion/adapter/rack.rb
Overview
NOTE: this is Hyperion::Adapter::Rack, not the Rack gem. Reference the Rack gem as ::Rack inside this module if needed.
Constant Summary collapse
- HTTP_KEY_CACHE =
Pre-frozen mapping for the 16 most common HTTP request headers. Skips the per-request ‘“HTTP_#’_’)”‘ allocation (5–15 string ops per request × N headers). Uncached header names fall back to the dynamic computation. Keys are lowercased to match the parser’s normalisation.
{ 'host' => 'HTTP_HOST', 'user-agent' => 'HTTP_USER_AGENT', 'accept' => 'HTTP_ACCEPT', 'accept-encoding' => 'HTTP_ACCEPT_ENCODING', 'accept-language' => 'HTTP_ACCEPT_LANGUAGE', 'connection' => 'HTTP_CONNECTION', 'content-type' => 'HTTP_CONTENT_TYPE', 'content-length' => 'HTTP_CONTENT_LENGTH', 'cookie' => 'HTTP_COOKIE', 'authorization' => 'HTTP_AUTHORIZATION', 'cache-control' => 'HTTP_CACHE_CONTROL', 'referer' => 'HTTP_REFERER', 'origin' => 'HTTP_ORIGIN', 'x-forwarded-for' => 'HTTP_X_FORWARDED_FOR', 'x-forwarded-proto' => 'HTTP_X_FORWARDED_PROTO', 'x-real-ip' => 'HTTP_X_REAL_IP' }.freeze
- ENV_POOL =
Hyperion::Pool.new( max_size: 256, factory: -> { {} }, reset: ->(env) { env.clear } )
- INPUT_POOL =
Hyperion::Pool.new( max_size: 256, factory: -> { StringIO.new }, reset: lambda { |io| io.string = +'' io.rewind } )
Class Method Summary collapse
Class Method Details
.call(app, request) ⇒ Object
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/hyperion/adapter/rack.rb', line 52 def call(app, request) env, input = build_env(request) status, headers, body = app.call(env) [status, headers, body] rescue StandardError => e Hyperion.metrics.increment(:app_errors) Hyperion.logger.error do { message: 'app raised', error: e., error_class: e.class.name, backtrace: (e.backtrace || []).first(20).join(' | ') } end [500, { 'content-type' => 'text/plain' }, ['Internal Server Error']] ensure # Return env + input to pools after the response has been fully # iterated by the writer. We can't release here because Rack body # is iterated lazily — release happens after the writer. # For Phase 5 simplicity we release synchronously since the writer # buffers fully. Phase 7 (HTTP/2 streaming) will revisit. ENV_POOL.release(env) if env INPUT_POOL.release(input) if input end |