Skip to content

Instantly share code, notes, and snippets.

@sonots
Last active October 11, 2019 15:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sonots/8058865 to your computer and use it in GitHub Desktop.
Save sonots/8058865 to your computer and use it in GitHub Desktop.
WebRick should delete Content-Length for Chunked Transfer

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
}
@sonots
Copy link
Author

sonots commented Dec 20, 2013

start webrick server

$ rackup config.ru

send request

$ telnet localhost 9292
GET /slow_stream HTTP/1.1
Host: localhost:9292
Transfer-Encoding: chunked

response, which has content-length header

HTTP/1.1 400 Bad Request
Content-Type: text/html; charset=ISO-8859-1
Server: WEBrick/1.3.1 (Ruby/2.0.0/2013-06-27)
Date: Fri, 20 Dec 2013 18:28:14 GMT
Content-Length: 277
Connection: close

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<HTML>
  <HEAD><TITLE>Bad Request</TITLE></HEAD>
  <BODY>
    <H1>Bad Request</H1>
    bad chunk `\r\n'.
    <HR>
    <ADDRESS>
     WEBrick/1.3.1 (Ruby/2.0.0/2013-06-27) at
     localhost:9292
    </ADDRESS>
  </BODY>
</HTML>

@sonots
Copy link
Author

sonots commented Dec 20, 2013

start unicorn server

$ unicorn -l 9292 config.ru

send request

telnet localhost 9292
GET /slow_stream HTTP/1.1
Host: localhost:9292
Transfer-Encoding: chunked

response

HTTP/1.1 200 OK
Date: Fri, 20 Dec 2013 18:24:22 GMT
Status: 200 OK
Connection: close
Content-Type: text/plain
Transfer-Encoding: chunked

33
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

33
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb

33
cccccccccccccccccccccccccccccccccccccccccccccccccc

33
dddddddddddddddddddddddddddddddddddddddddddddddddd

33
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee

0

@sonots
Copy link
Author

sonots commented Dec 20, 2013

webrick after fix

response. あれー?なんか変だな

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment