From 1b7877d0722d6afd767fd304322b1b02415b4906 Mon Sep 17 00:00:00 2001 From: "chris.double" Date: Sat, 2 Sep 2006 06:01:22 +0000 Subject: [PATCH] Implement If-Modified-Since header in httpd A browser sends If-Modified-Since when requesting a resource, the server should send a '304 Not Modified' if the Last-Modified time of the resource matches the date in 'If-Modified-Since'. Googlebot also uses If-Modified-Since so this addition to httpd can save some bandwidth. --- contrib/httpd/file-responder.factor | 31 ++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/contrib/httpd/file-responder.factor b/contrib/httpd/file-responder.factor index 2bfa60efb7..8d0dd35561 100644 --- a/contrib/httpd/file-responder.factor +++ b/contrib/httpd/file-responder.factor @@ -2,24 +2,45 @@ ! See http://factorcode.org/license.txt for BSD license. IN: file-responder USING: calendar embedded errors html httpd io kernel math namespaces parser -sequences strings ; +sequences strings hashtables ; : serving-path ( filename -- filename ) [ "" ] unless* "doc-root" get swap append ; +: file-http-date ( filename -- string ) + #! Return the date in HTTP Date format (see RFC 2616). + #! Returns false if no time information available for the file. + stat [ fourth unix>gmt timestamp>http-string ] [ f ] if* ; + : file-response ( filename mime-type length -- ) [ number>string "Content-Length" set "Content-Type" set - stat [ fourth unix>gmt timestamp>http-string "Last-Modified" set ] when* + file-http-date [ "Last-Modified" set ] when* now timestamp>http-string "Date" set ] make-hash "200 OK" response terpri ; +: last-modified-matches? ( filename -- bool ) + file-http-date [ + "If-Modified-Since" "header" get hash = + ] [ + f + ] if* ; + +: not-modified-response ( -- ) + [ + now timestamp>http-string "Date" set + ] make-hash "304 Not Modified" response terpri ; + : serve-static ( filename mime-type -- ) - dupd pick file-length file-response "method" get "head" = [ - drop + over last-modified-matches? [ + drop not-modified-response ] [ - stdio get stream-copy + dupd pick file-length file-response "method" get "head" = [ + drop + ] [ + stdio get stream-copy + ] if ] if ; SYMBOL: page