tcl-websh-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From (David N. Welton)
Subject Re: putx of empty string before first brace does not send headers
Date Wed, 26 Dec 2001 17:31:33 GMT
Ronnie Brunner <> writes:

> > Positives: 
> >         Makes it possible to fool around with the headers.

> This is a must. I don't think we could live without it.

Ok, then I guess we find a solution for it.

> > Negatives:
> >         Requires coding around things in the parser.

> I see that.

> >         Arbitrary - including even a " " will make it not work
> >         correctly.  This might confuse people.

> I only partially have a problem with this. Meddling with headers
> only works as long as you haven't sent anything over the channel: ''
> is nothing vs. ' ' is something.

What I don't like about it is that it is another rule you have to
explain to people, although it's difficult to get around having some
sort of rule in these situations - buffering it still requires that
you explain that headers be manipulated in the first block of Tcl).

> > I avoided this in mod_dtcl by buffering the first bit of non-Tcl,
> > so that instead of having to make sure there is no space, you can
> > manipulate headers in the first chunk of Tcl code (or you can set
> > up buffering there so that you can manipulate headers wherever you
> > want).

> Does that really solve the problem of "coding around things"? Would
> you always buffer the first non-Tcl junk? Buffering as such requires
> some "coding around things", or am I wrong?

Yes, but the code that results is less ugly, in my opinion, because
you end up using more standard Tcl things rather than doing it at the
parser level.  Doing it at the parser level requires us to say 

        there was no space between the start of the string and the

        don't add a '"\n' to the output buffer after the first

        don't add a 'web::put' to the beginning of the block of code
        to eval.

This requires the addition of a couple of state variables that get
modified to do the comparison and then act on it.  There are worse
things, but it doesn't feel very clean, either.

Doing it via buffering just requires you to turn buffering off, and
then after the first puts, you can turn it back on again.  In Rivet, I
think we currently just skip the flush after the initial 'puts' and
leave it up to the user.

My comments to the rivet list:

        How it should work:

        1) Buffering is done by the stream itself, which starts with
           full buffering.

        2) After the first puts, each puts generates a flush (or we
           could just put the buffer size to a smaller value so that
           they happen automatically).  The first puts can't ever
           generate a flush, because there is always a bit of 'html'
           between the beginning of the file, and the first <? ?>

           At least that's the way I've always done things in
           mod_dtcl, which seemed like a good compromise: if you want
           to set the headers, you either do it at the start of the
           file, or you turn off buffering/flushing explicitly.

        3) A finally flush is performed at the end.

        I guess the complicated thing is that we have to move a few
        more things over into the channel implementation.  We also
        need to prevent the first puts from ever flushing - maybe by
        setting the buffer size to a huge value (the maximum is

So the tradeoff comes down to having one state variable checking
whether something has already been "puts'ed" vs not having incremental
page updats (or requiring the user to do them manually with 'flush').

It's not perfect, but it does feel cleaner.

> The key feature we need is the ability to fiddle around with headers
> in a "ASP"-style template environment: mod_websh setup that just
> "web::putxfile"s a file from the file system.

Ok, some way of doing it is necessary.

> I wouldn't mind if we need to put some preparing statements in the
> handling code for the templates such as turn on buffering or
> something, but it would need to be something that does not have any
> impact on the later execution of the template.

> What would your solution look like?

I suppose the simplest way would be to just do the hack in the parser,
but I'm still experimenting some...

David N. Welton
Free Software:
   Apache Tcl:

View raw message