factor/basis/furnace/utilities/utilities.factor

132 lines
3.4 KiB
Factor
Raw Normal View History

2010-09-28 00:45:31 -04:00
! Copyright (C) 2008, 2010 Slava Pestov.
2008-06-16 04:34:17 -04:00
! See http://factorcode.org/license.txt for BSD license.
USING: accessors arrays assocs classes combinators continuations
definitions fry http http.server http.server.redirection
http.server.remapping io.pathnames kernel make namespaces
sequences splitting strings urls words xml.syntax ;
2008-06-16 04:34:17 -04:00
IN: furnace.utilities
: word>string ( word -- string )
2008-12-03 20:10:41 -05:00
[ vocabulary>> ] [ name>> ] bi ":" glue ;
2008-06-16 04:34:17 -04:00
: words>strings ( seq -- seq' )
[ word>string ] map ;
ERROR: no-such-word name vocab ;
: string>word ( string -- word )
2011-11-06 18:57:24 -05:00
":" split1 swap 2dup lookup-word dup
[ 2nip ] [ drop no-such-word ] if ;
2008-06-16 04:34:17 -04:00
: strings>words ( seq -- seq' )
[ string>word ] map ;
2008-11-24 21:26:11 -05:00
: nested-responders ( -- seq )
responder-nesting get values ;
: each-responder ( quot: ( ... responder -- ... ) -- )
2008-11-24 21:26:11 -05:00
nested-responders swap each ; inline
2010-09-28 00:45:31 -04:00
ERROR: no-such-responder responder ;
: base-path ( string -- seq )
2008-11-24 21:26:11 -05:00
dup responder-nesting get
[ second class-of superclasses-of [ name>> = ] with any? ] with find nip
[ first ] [ no-such-responder ] ?if ;
2008-11-24 21:26:11 -05:00
: resolve-base-path ( string -- string' )
"$" ?head [
[
"/" split1 [ base-path [ "/" % % ] each "/" % ] dip %
2008-11-24 21:26:11 -05:00
] "" make
] when ;
: resolve-word-path ( word -- path/f )
where [ first parent-directory ] [ f ] if* ;
2008-11-24 21:26:11 -05:00
: resolve-template-path ( pair -- path )
first2 [ resolve-word-path ] dip append-path ;
2008-11-24 21:26:11 -05:00
GENERIC: modify-query ( query responder -- query' )
M: object modify-query drop ;
GENERIC: modify-redirect-query ( query responder -- query' )
M: object modify-redirect-query drop ;
GENERIC: adjust-url ( url -- url' )
M: url adjust-url
clone
[ [ modify-query ] each-responder ] change-query
[ resolve-base-path ] change-path
relative-to-request ;
M: string adjust-url ;
GENERIC: adjust-redirect-url ( url -- url' )
M: url adjust-redirect-url
adjust-url
[ [ modify-redirect-query ] each-responder ] change-query ;
M: string adjust-redirect-url ;
GENERIC: link-attr ( tag responder -- )
M: object link-attr 2drop ;
2009-02-08 21:32:11 -05:00
GENERIC: modify-form ( responder -- xml/f )
2008-11-24 21:26:11 -05:00
2009-02-08 22:17:59 -05:00
M: object modify-form drop f ;
2008-11-24 21:26:11 -05:00
2009-02-08 21:32:11 -05:00
: form-modifications ( -- xml )
2009-02-08 22:17:59 -05:00
[ [ modify-form [ , ] when* ] each-responder ] { } make ;
2009-02-08 21:32:11 -05:00
: hidden-form-field ( value name -- xml )
2008-11-24 21:26:11 -05:00
over [
XML-CHUNK[[ <input type="hidden" value=<-> name=<->/> ]]
2009-02-06 12:44:58 -05:00
] [ drop ] if ;
CONSTANT: nested-forms-key "__n"
2008-11-24 21:26:11 -05:00
: referrer ( -- referrer/f )
2015-09-08 19:15:10 -04:00
! Typo is intentional, it's in the HTTP spec!
request get "referer" header
dup [ >url ensure-port [ remap-port ] change-port ] when ;
2008-11-24 21:26:11 -05:00
: user-agent ( -- user-agent )
request get "user-agent" header "" or ;
2008-11-24 21:26:11 -05:00
: same-host? ( url -- ? )
dup [
url get [
[ protocol>> ]
[ host>> ]
[ port>> remap-port ]
tri 3array
2012-07-21 13:22:44 -04:00
] same?
2008-11-24 21:26:11 -05:00
] when ;
: cookie-client-state ( key request -- value/f )
swap get-cookie dup [ value>> ] when ;
: post-client-state ( key request -- value/f )
request-params at ;
: client-state ( key -- value/f )
request get dup method>> {
{ "GET" [ cookie-client-state ] }
{ "HEAD" [ cookie-client-state ] }
{ "POST" [ post-client-state ] }
} case ;
SYMBOL: exit-continuation
: exit-with ( value -- * )
2008-11-24 21:26:11 -05:00
exit-continuation get continue-with ;
: with-exit-continuation ( quot -- value )
'[ exit-continuation set @ ] callcc1 exit-continuation off ; inline