Sha256: 647634f3100640b19c7e4f97a094cb46db9fb27e6f7c88835d163416d281e2c5
Contents?: true
Size: 1.93 KB
Versions: 9
Compression:
Stored size: 1.93 KB
Contents
# frozen_string_literal: true require 'rack/utils' module Rack # Middleware that applies chunked transfer encoding to response bodies # when the response does not include a Content-Length header. class Chunked include Rack::Utils # A body wrapper that emits chunked responses class Body TERM = "\r\n" TAIL = "0#{TERM}" include Rack::Utils def initialize(body) @body = body end def each(&block) term = TERM @body.each do |chunk| size = chunk.bytesize next if size == 0 chunk = chunk.b yield [size.to_s(16), term, chunk, term].join end yield TAIL insert_trailers(&block) yield TERM end def close @body.close if @body.respond_to?(:close) end private def insert_trailers(&block) end end class TrailerBody < Body private def insert_trailers(&block) @body.trailers.each_pair do |k, v| yield "#{k}: #{v}\r\n" end end end def initialize(app) @app = app end # pre-HTTP/1.0 (informally "HTTP/0.9") HTTP requests did not have # a version (nor response headers) def chunkable_version?(ver) case ver when 'HTTP/1.0', nil, 'HTTP/0.9' false else true end end def call(env) status, headers, body = @app.call(env) headers = HeaderHash.new(headers) if ! chunkable_version?(env[SERVER_PROTOCOL]) || STATUS_WITH_NO_ENTITY_BODY.key?(status.to_i) || headers[CONTENT_LENGTH] || headers[TRANSFER_ENCODING] [status, headers, body] else headers.delete(CONTENT_LENGTH) headers[TRANSFER_ENCODING] = 'chunked' if headers['Trailer'] [status, headers, TrailerBody.new(body)] else [status, headers, Body.new(body)] end end end end end
Version data entries
9 entries across 9 versions & 1 rubygems