https://github.com/sonots/ruby/compare/chunked?expand=1
config.ru
class Streamer
include Rack::Utils
def initialize(sleep=0.05)
@sleep = sleep
@strings = ("a".."e").collect {|n| n * 50 + "\n" }
end
def call(env)
req = Rack::Request.new(env)
headers = {"Content-Type" => "text/plain"}
headers["Transfer-Encoding"] = "chunked"
[200, headers, self.dup]
end
def each
term = "\r\n"
@strings.each do |chunk|
size = bytesize(chunk)
sleep @sleep
yield [size.to_s(16), term, chunk, term].join
end
yield ["0", term, "", term].join
end
end
# if no content-length is provided and the response isn't streamed,
# make sure the headers get a content length.
use Rack::ContentLength
map "/" do
run lambda { |env| [200, {"Content-Type" => "text/plain"}, ["ALL GOOD"]] }
end
map "/stream" do
run Streamer.new
end
map "/slow_stream" do
run Streamer.new(1)
end
http client
#!/usr/bin/env ruby
# coding: utf-8
require 'net/http'
require 'uri'
http = Net::HTTP.new "localhost", 9292
request = Net::HTTP::Get.new "/slow_stream"
request['Connection'] = 'keep-alive'
http.request(request){|response|
puts "content-length: #{response.content_length}"
body = []
response.read_body{|x|
body << Time.now
puts "read_block: #{body.size}, #{x.size}byte(s), #{x[0]}"
}
puts body
}
start webrick server
send request
response, which has
content-length
header