Index: library/lib/nx-zip.tcl =================================================================== diff -u -N -r8bb94eca8ef26804ab3ba6f93c2d3d068c3f8ccc -r94dce307a006cd07e3495cfab84e643258e83df3 --- library/lib/nx-zip.tcl (.../nx-zip.tcl) (revision 8bb94eca8ef26804ab3ba6f93c2d3d068c3f8ccc) +++ library/lib/nx-zip.tcl (.../nx-zip.tcl) (revision 94dce307a006cd07e3495cfab84e643258e83df3) @@ -19,7 +19,7 @@ package require Trf } -package provide nx::zip 1.3 +package provide nx::zip 1.4 namespace eval ::nx::zip { @@ -31,7 +31,7 @@ # - addString (add the file-content from a string to the archive) # # - writeToZipFile (produce a Zip file) - # - ns_returnZipFile (return a zip file via AOLserver ns_return) + # - ns_returnZipFile (return a zip file via NaviServer ns_return) # # - writeToStream (for already opened and configured # output streams) @@ -73,6 +73,23 @@ close $fout } + :public method flushBuffer {channel } { + # + # When using ns_connchan, flush the internal buffer. + # + if {[string match *ns_connchan* ${:writer}]} { + while {1} { + set status [ns_connchan status $channel] + if {[dict get $status sendbuffer] > 0} { + ns_connchan write -buffered $channel "" + ns_sleep 1ms + } else { + break + } + } + } + } + # # return the added files via aolserver/NaviServer to the client # @@ -94,15 +111,7 @@ set :writer [list ns_connchan write -buffered $channel] ns_connchan write -buffered $channel $header :writeToStream $channel - while {1} { - set status [ns_connchan status $channel] - if {[dict get $status sendbuffer] > 0} { - ns_connchan write -buffered $channel "" - ns_sleep 1ms - } else { - break - } - } + :flushBuffer $channel ns_connchan close $channel } else { ns_write $header @@ -126,6 +135,16 @@ set descriptionList [list] foreach {type in fnOut} ${:files} { lappend descriptionList [:addSingleFile $type $in $fnOut] + # + # The max size of an int is 2147483647 under tcl 8.*, which is + # as well the limit of a Tcl_DString. Since channel buffer + # leftovers from partial write operations, it can be that two + # files slightly smaller than the size limit are written in + # sequence, which requires a buffering of larger content which + # might lead to integer overruns in Tcl. To avoid such + # situations, we flush the send buffer after every file. + # + :flushBuffer $outputStream } # # we have no