Google Groups Home
Help | Sign in
Thin & Keep alive
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  5 messages - Collapse all
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
Alex MacCaw  
View profile
 More options May 16, 6:09 am
From: Alex MacCaw <macc...@gmail.com>
Date: Fri, 16 May 2008 03:09:21 -0700 (PDT)
Local: Fri, May 16 2008 6:09 am
Subject: Thin & Keep alive
I'm trying to get keep alive support working in Thin (for a JSON RPC
server)
The following code is based on Thin's tests:

require 'socket'
socket = TCPSocket.new('0.0.0.0', 3000)
def urlencode(str)
  str.gsub(/[^a-zA-Z0-9_\.\-]/n) {|s| sprintf('%%%02x', s[0]) }
end
params = {:data => %{{"id":1,"method":"test","params":
[],"version":"0.1"}}}
data = params.map {|k,v|
"#{urlencode(k.to_s)}=#{urlencode(v.to_s)}" }.join('&')
socket.write %{POST /rpc HTTP/1.1\r\nConnection: keep-alive\r\nContent-
Type: application/x-www-form-urlencoded\r\nContent-Length:
#{data.length}\r\n\r\n#{data}}
socket.flush
socket.write %{POST /rpc HTTP/1.1\r\nConnection: keep-alive\r\nContent-
Type: application/x-www-form-urlencoded\r\nContent-Length:
#{data.length}\r\n\r\n#{data}}
response = socket.read
p response
socket.close

However, Thin seems to mangle the second request into the first:

>> @env['rack.input'].read

=> "data=%7b%22id%22%3a1%2c%22method%22%3a%22test%22%2c%22params%22%3a
%5b%5d%2c%22version%22%3a%220.1%22%7dPOST /rpc HTTP/1.1\r\nConnection:
keep-alive\r\nContent-Type: application/x-www-form-urlencoded\r
\nContent-Length: 103\r\n\r\ndata=%7b%22id%22%3a1%2c%22method%22%3a
%22test%22%2c%22params%22%3a%5b%5d%2c%22version%22%3a%220.1%22%7d"

Is this expected behavior? Am I doing something stupid?


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Alex MacCaw  
View profile
 More options May 16, 7:31 am
From: Alex MacCaw <macc...@gmail.com>
Date: Fri, 16 May 2008 04:31:37 -0700 (PDT)
Local: Fri, May 16 2008 7:31 am
Subject: Re: Thin & Keep alive
Sorry, that might not be clear (google groups formatting problem).
Here's a slightly cleaner client:

require 'socket'
socket = TCPSocket.new('0.0.0.0', 3000)
params = 'data=123'
socket.write %{POST /rpc HTTP/1.1\r\nContent-Length: #{params.length}\r
\n\r\n#{params}}
socket.flush
socket.write %{POST /rpc HTTP/1.1\r\nContent-Length: #{params.length}\r
\n\r\n#{params}}
response = socket.read
p response
socket.close

On May 16, 11:09 am, Alex MacCaw <macc...@gmail.com> wrote:


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
macournoyer  
View profile
 More options May 16, 9:47 am
From: macournoyer <macourno...@gmail.com>
Date: Fri, 16 May 2008 06:47:05 -0700 (PDT)
Local: Fri, May 16 2008 9:47 am
Subject: Re: Thin & Keep alive
Hey Alex,

What you're doing here is sending 2 requests to Thin at the same time
(pipelining them) so Thin replies w/ 2 responses one after the other,
like you did w/ the requests. This is called http pipelining:
http://en.wikipedia.org/wiki/HTTP_pipelining

Keep-alive is just a something that removes the need to close the
connection between each request.

So if you'd normally do:
# 1st request
socket = TCPSocket.new('0.0.0.0', 3000)
socket.write(...)
socket.read
socket.close
# 2nd request
socket = TCPSocket.new('0.0.0.0', 3000)
socket.write(...)
socket.read
socket.close

w/ keep-alive, it's the same, w/out the close, but you need to use
readpartial since the FIN segment has not been received yet (hm, not
sure it's FIN):
# 1st request
socket = TCPSocket.new('0.0.0.0', 3000)
socket.write(...)
socket.readpartial(1024)
# 2nd request
socket.write(...)
socket.readpartial(1024)
socket.close

Let me know if this doesn't works for you.

Marc

On May 16, 7:31 am, Alex MacCaw <macc...@gmail.com> wrote:


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Alex MacCaw  
View profile
 More options May 16, 10:11 am
From: Alex MacCaw <macc...@gmail.com>
Date: Fri, 16 May 2008 07:11:56 -0700 (PDT)
Local: Fri, May 16 2008 10:11 am
Subject: Re: Thin & Keep alive
Ok, brilliant, that all works.
Here's the new problem ;) :
The content length never seems to get set on the response.
This means that when the response checks if it's persistent or not, it
always reverts to a 'Connection: close' since it checks to see whether
the response has a length or not (and it never seems to).
putting this at the top of the method headers_output on response.rb
seems to solve the problem:

@headers[CONTENT_LENGTH] = @body.join('').length if @body

btw, any idea why rack requires the body to be an array?
Also, do you know how do make the method .eof? on a socket non
blocking, it seems to block until the socket is actually at eof.
Thanks
Alex

On May 16, 2:47 pm, macournoyer <macourno...@gmail.com> wrote:


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
macournoyer  
View profile
 More options May 16, 2:02 pm
From: macournoyer <macourno...@gmail.com>
Date: Fri, 16 May 2008 11:02:55 -0700 (PDT)
Local: Fri, May 16 2008 2:02 pm
Subject: Re: Thin & Keep alive
You need to set the Content-Length yourself in your Rack application,
This prevent Thin from having to read the full body to get the size.
Also the body can be a string or anything that respond to each and
yields a string.

I think readpartial will return nil if there is no data left.

On May 16, 10:11 am, Alex MacCaw <macc...@gmail.com> wrote:


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »

Create a group - Google Groups - Google Home - Terms of Service - Privacy Policy
©2008 Google