Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Keep-Alive. #2

Open
postmodern opened this issue Apr 6, 2011 · 3 comments
Open

Add support for Keep-Alive. #2

postmodern opened this issue Apr 6, 2011 · 3 comments

Comments

@postmodern
Copy link
Owner

The Server Daemon does not support re-using the socket when the Keep-Alive header is specified.

@postmodern
Copy link
Owner Author

This can be implemented using Deferrable Connections with EventMachine. See Issue #3.

@gavv
Copy link
Contributor

gavv commented Oct 26, 2016

Related note

Rack::Handler::HTTP uses Rack::RewindableInput for request body:

env['rack.input'] = Rack::RewindableInput.new(stream)

which calls Stream#read:

def make_rewindable
  ...
  while @io.read(1024 * 4, buffer)

which reads from socket until provided limit or EOF reached:

def read(length=4096,buffer='')
  @socket.read(length,buffer)
end

When client uses Keep-Alive, it doesn't close socket after sending request body. Thus, Stream#read hangs, because request body is often smaller than 4096 bytes and there is no EOF.

A quick workaround is to limit maximum length that can be read from stream with Content-Length header, if provided. Something like this:

def read(length=4096,buffer='')
  unless @content_length.nil?
    max_length = @content_length - @current_offset
    length = max_length if length > max_length
  end
  return nil if length == 0 # don't forget to return nil instead of zero
  bytes = @socket.read(length,buffer)
  @current_offset += bytes.length unless bytes.nil?
  bytes
end

With this fix, net-http-server still ignores Keep-Alive and closes socket, but at least it doesn't hang, which allows to use it with modern clients.

Though, I didn't test this workaround very much, it probably has some other pitfalls.

Note that Keep-Alive is default in HTTP/1.1 (i.e. it should be used even if Keep-Alive header is omitted), and HTTP/1.1 is default in Golang http client, so net-http-server usually hangs when handling requests from clients written in Go.

@gavv
Copy link
Contributor

gavv commented Oct 26, 2016

Also, it seems that Rack::RewindableInput creates a temporary file for every request. It's weird (thought I didn't try to benchmark it).

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

No branches or pull requests

2 participants