The enclosed code (for tclhttpd) provides the [Cache_Fetch] and [Cache_Store] procs which will transparently cache typed content to the filesystem, and return it to the client.
This generic caching allows [Doc_$type] commands to serve cached generated content by processing a file of $type. An example of this is the application/x-tcl-session handler in tclhttpd session templates.
# cache.tcl # # Provide support for caching arbitrary content in tclhttpd # # CMcC 20040929 - Created package provide tclhttpd::cache 1.0 # Cache module data # suffix the string suffix appended to a cache copy array set Cache { suffix _cache } # Cache_Fetch # Check for the existence of a file ${path}_cache. # if it exists, send it to client. # # Arguments: # path The file about to be processed # bcache Is the data cacheable in the browser? # # Results: # Returns 1 if the cached version was sent, 0 otherwise # # Side Effects: # Send the data down the socket proc Cache_Fetch {path {bcache 1}} { global Cache # handle cached generated files if {[file exists ${path}$Cache(suffix)] && ([file mtime $path] <= [file mtime ${path}$Cache(suffix)])} { # file exists ... return it set fd [open ${path}$Cache(suffix) r] set ctype [gets $fd] ;# get the stored mime type set content [read $fd] ;# get the generated content close $fd # return the file to the client socket if {$bcache} { Httpd_ReturnCacheableData $sock $ctype $content [file mtime ${path}$Cache(suffix)] } else { Httpd_ReturnData $sock $ctype $content } # indicate success return 1 } # there was no cache entry - indicate failure return 0 } # Cache_Store # Filter and store a file in ${path}$Cache(suffix) # Send it to the client socket after running data(filters) # # Arguments: # sock The socket connection. # path The file system pathname of the file. # content The data to be returned to the client # ctype The mime content-type of content # bcache Is the data cacheable in the browser? # # Results: # nothing # # Side Effects: # data(filters) are run over content, # a file ${path}$Cache(suffix) is created # $content is returned to the client socket proc Cache_Store {sock path content ctype {bcache 1}} { global Cache upvar #0 Httpd$sock data catch {file delete -force ${path}$Cache(suffix)} # process filters now, so they'll be incorporated in cached version if {[info exists data(filter)]} { while {[llength $data(filter)]} { set cmd [lindex $data(filter) end] set data(filter) [lrange $data(filter) 0 end-1] catch { set content [eval $cmd $sock [list $content]] } } unset data(filter) ;# we've already filtered it - no more } if {[catch {open ${path}$Cache(suffix) w} out eo]} { Log $sock "stml" "no write permission" } else { puts $out $ctype ;# record the mime type puts -nonewline $out $content close $out } # return the result - filters will be applied en route if {$bcache} { Httpd_ReturnCacheableData $sock $ctype $content [clock scan now]] } else { Httpd_ReturnData $sock $ctype $content } }