Skip to content

Instantly share code, notes, and snippets.

@akostadinov
Forked from trevorrowe/client.rb
Last active March 28, 2018 12:47
Show Gist options
  • Save akostadinov/224c73f5317ce51eacc993a6048984d2 to your computer and use it in GitHub Desktop.
Save akostadinov/224c73f5317ce51eacc993a6048984d2 to your computer and use it in GitHub Desktop.
Ruby Net::HTTP Expect-100 continue PUT bug
# Start the sample server. This server alternates between responding with 100-continue and
# resopnding with a 403 Forbidden. The client **should** be able to handle both responses.
$ ruby server.rb
# In another terminal window, run the client code twice. The first invocation will succeed.
# The second invocation will fail the client with an error.
$ ruby client.rb
$ ruby client.rb
require 'net/http'
require 'logger'
req = Net::HTTP::Put.new('/', { 'expect' => '100-continue' })
req.body = 'data'
http = Net::HTTP.new('localhost', 3000)
http.continue_timeout = 1
http.set_debug_output(Logger.new($stdout))
http.request(req)
# This example server accepts a simple PUT request with the 'Excpect: 100-continue'
# header. It alternates between the following two responses:
#
# * 100 Continue, accepting the body, then 200 OK
# * 403 Forbidden, not accepting the body
#
require 'socket'
server = TCPServer.new('localhost', 3000)
n = 0
loop do
socket = server.accept
req_method, req_uri, http_version = socket.gets.split(/\s+/)
req_headers = {}
line = socket.gets
until line == "\r\n"
key, value = line.split(/:\s*/, 2)
req_headers[key.downcase] = value
line = socket.gets
end
content_length = req_headers['content-length'].to_i
if n % 2 == 0
socket.print("HTTP/1.1 100 Continue\r\n")
socket.print("\r\n")
socket.read(content_length)
socket.print("HTTP/1.1 200 OK\r\n")
socket.print("\r\n")
else
socket.print("HTTP/1.1 403 Forbidden\r\n")
socket.print("\r\n")
end
n += 1
socket.close
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment