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.
release
chris.double 2006-09-02 06:01:22 +00:00
parent d891d8e92b
commit 1b7877d072
1 changed files with 26 additions and 5 deletions

View File

@ -2,24 +2,45 @@
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
IN: file-responder IN: file-responder
USING: calendar embedded errors html httpd io kernel math namespaces parser USING: calendar embedded errors html httpd io kernel math namespaces parser
sequences strings ; sequences strings hashtables ;
: serving-path ( filename -- filename ) : serving-path ( filename -- filename )
[ "" ] unless* "doc-root" get swap append ; [ "" ] 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 -- ) : file-response ( filename mime-type length -- )
[ [
number>string "Content-Length" set number>string "Content-Length" set
"Content-Type" 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 now timestamp>http-string "Date" set
] make-hash "200 OK" response terpri ; ] 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 -- ) : serve-static ( filename mime-type -- )
dupd pick file-length file-response "method" get "head" = [ over last-modified-matches? [
drop drop not-modified-response
] [ ] [
<file-reader> stdio get stream-copy dupd pick file-length file-response "method" get "head" = [
drop
] [
<file-reader> stdio get stream-copy
] if
] if ; ] if ;
SYMBOL: page SYMBOL: page