# notfound handler to provide centralised repository of .css and image files
# also searches path from docroot down for files called .nf, which it package require struct rename Doc_NotFound Doc_Notfound_org proc Doc_NotFound {sock} { global Doc Referer upvar #0 Httpd$sock data Stderr "Doc_NotFound [array get data]" # try to redirect some well-known types .css, .jpg etc # to a centralised repository set redirect "" switch [file extension $data(suffix)] { .css { set redirect [file join /css [file tail $data(suffix)]] } .js { set redirect [file join /jscript [file tail $data(suffix)]] } .gif - .jpg { set redirect [file join /images [file tail $data(suffix)]] } } if {($redirect != "") && ([string trim $data(suffix) /] != [string trim $redirect /])} { Redirect_Self $redirect } else { # fallback to using a .nf file in each directory on the path # as a template to generate the desired file if {[catch {Doc_GetPath $sock} path]} { set path {} } foreach dir [::struct::list::Lreverse $path] { set file [file join $dir .nf] if {[file exists $file]} { global Template Stderr "Notfound handling: $sock / [array get data] / $file" set html [TemplateInstantiate $sock $file $data(path) $data(suffix) dynamic \ $Template(templateInterp)] # If the content type was set, use it. Otherwise, use the default. if {[info exists data(contentType)]} { set ctype $data(contentType) } else { set ctype "text/html" } if {$dynamic} { return [Httpd_ReturnData $sock $ctype $html] } else { # Use ReturnFile so remote end knows it can cache the file. # This file may have been generated by TemplateInstantiate above. return [Httpd_ReturnFile $sock $ctype $data(path)] } } } # finally, default to the old behavior Doc_Notfound_org $sock } }