diff options
Diffstat (limited to 'lib/yahns/http_response.rb')
-rw-r--r-- | lib/yahns/http_response.rb | 38 |
1 files changed, 26 insertions, 12 deletions
diff --git a/lib/yahns/http_response.rb b/lib/yahns/http_response.rb index b157ee4..32d1a45 100644 --- a/lib/yahns/http_response.rb +++ b/lib/yahns/http_response.rb @@ -4,12 +4,14 @@ # frozen_string_literal: true require_relative 'stream_file' require_relative 'wbuf_str' +require_relative 'chunk_body' # Writes a Rack response to your client using the HTTP/1.1 specification. # You use it by simply doing: # +# opt = http_response_prep(env) # res = rack_app.call(env) -# http_response_write(res, env['REQUEST_METHOD']=='HEAD') +# http_response_write(res, opt) # # Most header correctness (including Content-Length and Content-Type) # is the job of Rack, with the exception of the "Date" header. @@ -120,14 +122,14 @@ module Yahns::HttpResponse # :nodoc: # writes the rack_response to socket as an HTTP response # returns :wait_readable, :wait_writable, :forget, or nil - def http_response_write(res, hdr_only) + def http_response_write(res, opt) status, headers, body = res offset = 0 count = hijack = nil - k = self.class - alive = @hs.next? && k.persistent_connections + alive = @hs.next? && self.class.persistent_connections flags = MSG_DONTWAIT term = false + hdr_only, chunk_ok = opt if @hs.headers? code = status.to_i @@ -161,6 +163,11 @@ module Yahns::HttpResponse # :nodoc: kv_str(buf, key, value) end end + if !term && chunk_ok + term = true + body = Yahns::ChunkBody.new(body, opt) + buf << "Transfer-Encoding: chunked\r\n".freeze + end alive &&= term buf << (alive ? "Connection: keep-alive\r\n\r\n".freeze : "Connection: close\r\n\r\n".freeze) @@ -173,7 +180,7 @@ module Yahns::HttpResponse # :nodoc: flags = MSG_DONTWAIT buf = rv # unlikely, hope the skb grows when :wait_writable, :wait_readable # unlikely - if k.output_buffering + if self.class.output_buffering alive = hijack ? hijack : alive rv = response_header_blocked(buf, body, alive, offset, count) body = nil # ensure we do not close body in ensure @@ -193,19 +200,19 @@ module Yahns::HttpResponse # :nodoc: end wbuf = rv = nil - body.each do |chunk| + body.each do |x| if wbuf - rv = wbuf.wbuf_write(self, chunk) + rv = wbuf.wbuf_write(self, x) else - case rv = kgio_trywrite(chunk) + case rv = String === x ? kgio_trywrite(x) : kgio_trywritev(x) when nil # all done, likely and good! break - when String - chunk = rv # hope the skb grows when we loop into the trywrite + when String, Array + x = rv # hope the skb grows when we loop into the trywrite when :wait_writable, :wait_readable - if k.output_buffering + if self.class.output_buffering wbuf = Yahns::Wbuf.new(body, alive) - rv = wbuf.wbuf_write(self, chunk) + rv = wbuf.wbuf_write(self, x) break else response_wait_write(rv) or return :close @@ -278,4 +285,11 @@ module Yahns::HttpResponse # :nodoc: return rv end while true end + + # must be called before app dispatch, since the app can + # do all sorts of nasty things to env + def http_response_prep(env) + [ env['REQUEST_METHOD'] == 'HEAD'.freeze, # hdr_only + env['HTTP_VERSION'] == 'HTTP/1.1'.freeze ] # chunk_ok + end end |