Version 0 of Tclhttpd Error Handling

Updated 2004-05-29 14:27:44 by CMCc

# 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
        }
    }