The channel mechanism is actually quite flexible out of the box. Anything Tcl lets you do, you can do with the stdout channel in Rivet. For example:
fconfigure stdout -buffersize 1000000 -buffering full And you have almost a megabyte of output before the channel will flush (unless you [flush stdout] yourself). I know that having to output the headers before any data can be annoying sometimes, but it’s really the proper way to do it. If you’re going to redirect to another page, you should have done so LONG before you output any data. In my case, I’m using a pretty standard MVC model where the controller determines that a redirect is required before the view is ever rendered. If we wanted to try and support his proposal, we could alter the [headers redirect] command, and if headers have already been sent, then we output the <meta> tag, but this has its problems as well. Though most browsers would probably let it slide, the meta tag should really be inside the <head> of the page. So, once again, you have a limitation. Just my thoughts, take ‘em or leave ‘em. :) D > On Dec 13, 2014, at 4:50 AM, Massimo Manghi <[email protected]> wrote: > > Rani Ahmad gave me permission to forward to rivet-dev his proposal for an > alternate way to force redirection to a different URL using the <meta ....> > tag. Rani claims this approach could attain the same effect while preventing > the scripts from failing with the "headers already sent" error. It still > makes sense that a script which could issue a redirect has in principle to > determine whether to divert to a different URL *before* any output is sent to > the channel. admittedly this is rigid because forces a certain design (though > a sane one), it's largely undocumented and in the end there should be a > better more flexible way to do this > > We obtain redirection with the 301 HTTP code and when the headers command is > called the code checks for the headers_sent flag > > TCL_CMD_HEADER( Rivet_Headers ) > { > ... > if (globals->req->headers_printed != 0) > { > Tcl_AddObjErrorInfo(interp ,"Cannot manipulate headers - already > sent", -1); > return TCL_ERROR; > } > > globals->req->headers_printed is set when the Rivet channel output procedure > is called by Tcl I/O subsystem and I wonder if there are different ways to do > it, for example making the channel implementation more flexible about > buffering. Of course this doesn't rule out the possibility of exploiting > other ways (like in Rani's proposal), but it seems to me the HTTP protocol > has to be supported in the best possible way > > -- Massimo > > ---------- Forwarded message ---------- > From: Rani Ahmed <[email protected] <mailto:[email protected]>> > Date: Thu, Dec 11, 2014 at 8:37 PM > Subject: Hi. A suggestion. > To: Massimo Manghi <[email protected] <mailto:[email protected]>> > > Hi Massimo. > > Well I suggest that you add a better redirect function/procedure other than > the [headers redirect $url ] . This one always makes many people go into the > annoying error message of headers already sent . > > The procedure will be the following, I found it on Stackoverflow. I > understand that I can put it for my own, but this little thing - I think - > can be the key that makes Rivet attractive. > > proc http_redirect { url } { > > ?> > <meta http-equiv="refresh" content="0;url='<?=$url;?>'"> > <? > > }
