Webrick streaming bodies

P

Phlip

Rubies:

Ogle this Webrick GET handler:

def do_GET(req, res)
res["content-type"] = "text/plain"
res.body = "Hello, world.\n"
end

That string "Hello, world.\n" is much shorter than typical web page
contents.

The longer the string assigned to response.body, the tackier this situation.
Ideally, the handler would prep the HTTP headers, then would pass a stream
into my application code. That would push bytes into the stream, and the
stream would push them out the raw TCP/IP ports synchronously.

(I'm also not talking about arbitary efficiency. Application code to push
data into a stream is much cleaner than code that assembles a huge
string...)

So is there some way to plug a real or virtual stream into the .body member?
Some of the documentation seems to imply there's a way...
 
G

GOTOU Yuuzou

Hi,

In message said:
Rubies:

Ogle this Webrick GET handler:

def do_GET(req, res)
res["content-type"] = "text/plain"
res.body = "Hello, world.\n"
end

That string "Hello, world.\n" is much shorter than typical web page
contents.

The longer the string assigned to response.body, the tackier this situation.
Ideally, the handler would prep the HTTP headers, then would pass a stream
into my application code. That would push bytes into the stream, and the
stream would push them out the raw TCP/IP ports synchronously.

res.body can take an IO object.

def do_GET(req, res)
res["content-type"] = "text/plain"
res.chunked = true if res.keep_alive?
res.body = IO.popen("dmesg")
end

If the content-length header field is present, HTTPResponse
will read specified length data from the IO.
 
P

Phlip

GOTOU said:
res.body can take an IO object.

def do_GET(req, res)
res["content-type"] = "text/plain"
res.chunked = true if res.keep_alive?
res.body = IO.popen("dmesg")

I fear popen. I use Win32. (Not my idea.) It will try to fork, then its
object will throw an error because Win32 can't fork.

Is there an IOstream object, like the C++ std::stringstream? All I need is
to call the application such that each call to .write goes out the TCP/IP
port.
 
T

Tim Sutherland

GOTOU said:
res.body can take an IO object.

def do_GET(req, res)
res["content-type"] = "text/plain"
res.chunked = true if res.keep_alive?
res.body = IO.popen("dmesg")

I fear popen. I use Win32. (Not my idea.) It will try to fork, then its
object will throw an error because Win32 can't fork.

Is there an IOstream object, like the C++ std::stringstream? All I need is
to call the application such that each call to .write goes out the TCP/IP
port.

popen was just an example. The equivalent of std::stringstream is StringIO.

require 'stringio'
def do_GET(req, res)
res["content-type"] = "text/plain"
res.chunked = true if res.keep_alive?
res.body = StringIO.new(@my_big_string)
end
 
P

Phlip

Tim said:
require 'stringio'
def do_GET(req, res)
res["content-type"] = "text/plain"
res.chunked = true if res.keep_alive?
res.body = StringIO.new(@my_big_string)
end

I'm afraid 'std::streamstring' was a red-herring; I'l ask a different way.

Suppose I use 'cgi.rb' and write a script for a CGI server to serve. It
serves by collecting $stdout and pushing that out its port.

So I can cook a page like this:

cookPage($stdout, query)

def cookPage(out, query)
...
out.write('<html/>')
end

Inside that cookPage(), calls to out.write() immediately send characters out
$stdout. Hence, these immediately pipe into the CGI server, who immediately
pipes them out the TCP/IP port. All with minimal buffering.

(This is post-mature optimization, folks; web servers must be responsive!)

The problem with res.body = anything is that anything must already have
contents, and this requires a big slow memory buffer, on this side, to store
its contents. So is there some other architecture within Webrick to avoid
slinging around this big buffer, while the actual port starves?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top