tcl-websh-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dav...@dedasys.com (David N. Welton)
Subject Re: putx of empty string before first brace does not send headers
Date Fri, 28 Dec 2001 10:35:25 GMT
Ronnie Brunner <ronnie@netcetera.ch> writes:

> > > 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.

> I still have a problem with your "buffering" solution: 

> - changing the buffer size and hoping that it is sufficiently large
> to hold the first block is too shaky in my opinion. 

It's not beautiful, but 1024 * 1024 bytes is pretty good.  I'm not
wholly satisfied with it either, but it ought to do the job.

> btw I'm not sure whether Tcl actually has to fill the buffer before
> it flushes anything. (The man page just says: "Tcl will normally
> delay output until the buffer is full or the channel is closed."
> This sounds too wage for my taste to be reliable.)

        /*
         * The current buffer is ready for output if it is full, or if it
         * contains a newline and this channel is line-buffered, or if it
         * contains any output and this channel is unbuffered.
         */

        outBufPtr->nextAdded += destCopied;
        if (!(statePtr->flags & BUFFER_READY)) {
            if (outBufPtr->nextAdded == outBufPtr->bufLength) {
                statePtr->flags |= BUFFER_READY;
            } else if (statePtr->flags & CHANNEL_LINEBUFFERED) {
                for (sPtr = src, i = 0, foundNewline = 0;
		     (i < srcCopied) && (!foundNewline);
		     i++, sPtr++) {
                    if (*sPtr == '\n') {
                        foundNewline = 1;
                        break;
                    }
                }
                if (foundNewline) {
                    statePtr->flags |= BUFFER_READY;
                }
            } else if (statePtr->flags & CHANNEL_UNBUFFERED) {
                statePtr->flags |= BUFFER_READY;
            }
        }

You're right that it's vague, but from a cursory look at the sources,
I don't see anything problematic.

> - Doesn't the CGI setup of websh make your solution very ugly?
>   Modifying the headers after something is written two the (buffered)
>   output requires reading back the buffer (w/o flushing), writing the
>   headers and rewriting the previous buffer content. I can't imaginge
>   how you want to do this in a not-ugly fashion.

It works like this: headers are set and manipulated in one buffer,
regular output in another.  WebSH already seperates these out.  What
happens in the channel implementation is that Tcl itself buffers
everything, and then when the output proc is finally called (by a user
flush, the channel being closed, or whatever) headers are printed.
I'm using the Tcl buffering, not the Apache system.

I'm not sure it's the perfect solution, but I am happy with in
dtcl/Rivet.  It has made the code smaller and cleaner.

That said, I asked in the first place because I hoped to discuss the
merits of each one, and this discussion has been quite useful.

The problem, or potential problem I see with buffering, is that it is
a non-minor rehaul of a low level system, and there might well be a
few side effects that I can't see at the moment.  It's definitely
"rocking the boat", which I'm not terribly enthusiastic about.  I've
presented it as one solution that I've used, and which appears to work
well, reducing code size and complexity.

-- 
David N. Welton
   Consulting: http://www.dedasys.com/
Free Software: http://people.debian.org/~davidw/
   Apache Tcl: http://tcl.apache.org/
     Personal: http://www.efn.org/~davidw/

Mime
View raw message