2005-02-14 17:19:09 -05:00
|
|
|
! Copyright (C) 2004 Chris Double.
|
2006-04-27 21:36:29 -04:00
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
|
|
|
|
|
2006-07-17 04:27:43 -04:00
|
|
|
USING: http httpd math namespaces io strings kernel html hashtables
|
|
|
|
|
parser generic sequences callback-responder ;
|
2006-04-27 21:36:29 -04:00
|
|
|
IN: cont-responder
|
2005-02-20 19:47:08 -05:00
|
|
|
|
2006-07-17 04:27:43 -04:00
|
|
|
#! Name of the variable holding the continuation used to exit
|
|
|
|
|
#! back to the httpd responder.
|
|
|
|
|
SYMBOL: exit-continuation
|
2005-02-14 17:19:09 -05:00
|
|
|
|
2006-07-17 04:27:43 -04:00
|
|
|
#! Tuple to hold global request data. This gets passed to
|
|
|
|
|
#! the continuation when resumed so it can restore things
|
2006-07-17 05:09:40 -04:00
|
|
|
#! like 'stdio' so it writes to the correct socket.
|
|
|
|
|
TUPLE: request stream exitcc method url raw-query query header response ;
|
2006-03-13 06:38:05 -05:00
|
|
|
|
2006-07-17 04:27:43 -04:00
|
|
|
C: request ( -- request )
|
|
|
|
|
[ stdio get swap set-request-stream ] keep
|
2006-07-17 05:09:40 -04:00
|
|
|
[ "method" get swap set-request-method ] keep
|
|
|
|
|
[ "request" get swap set-request-url ] keep
|
|
|
|
|
[ "raw-query" get swap set-request-raw-query ] keep
|
|
|
|
|
[ "query" get swap set-request-query ] keep
|
|
|
|
|
[ "header" get swap set-request-header ] keep
|
|
|
|
|
[ "response" get swap set-request-response ] keep
|
2006-07-17 04:27:43 -04:00
|
|
|
[ exit-continuation get swap set-request-exitcc ] keep ;
|
2006-03-13 06:38:05 -05:00
|
|
|
|
2006-07-17 04:27:43 -04:00
|
|
|
: restore-request ( request -- )
|
|
|
|
|
dup request-stream stdio set
|
2006-07-17 05:09:40 -04:00
|
|
|
dup request-method "method" set
|
|
|
|
|
dup request-raw-query "raw-query" set
|
|
|
|
|
dup request-query "query" set
|
|
|
|
|
dup request-header "header" set
|
|
|
|
|
dup request-response "response" set
|
2006-07-17 04:27:43 -04:00
|
|
|
request-exitcc exit-continuation set ;
|
2005-02-14 17:19:09 -05:00
|
|
|
|
2005-09-18 01:36:59 -04:00
|
|
|
: >callable ( quot|interp|f -- interp )
|
2006-07-17 04:27:43 -04:00
|
|
|
dup continuation? [
|
|
|
|
|
[ <request> swap continue-with ] curry
|
|
|
|
|
[ with-exit-continuation ] curry
|
2006-04-27 21:36:29 -04:00
|
|
|
] when ;
|
2005-09-18 01:36:59 -04:00
|
|
|
|
2005-02-14 17:19:09 -05:00
|
|
|
: with-exit-continuation ( quot -- )
|
2006-07-17 04:27:43 -04:00
|
|
|
#! Call the quotation with the variable exit-continuation bound
|
|
|
|
|
#! such that when the exit continuation is called, computation
|
|
|
|
|
#! will resume from the end of this 'with-exit-continuation' call.
|
|
|
|
|
[
|
|
|
|
|
exit-continuation set call exit-continuation get continue
|
|
|
|
|
] callcc0 drop ;
|
2005-02-14 17:19:09 -05:00
|
|
|
|
|
|
|
|
: forward-to-url ( url -- )
|
2006-04-27 21:36:29 -04:00
|
|
|
#! When executed inside a 'show' call, this will force a
|
|
|
|
|
#! HTTP 302 to occur to instruct the browser to forward to
|
|
|
|
|
#! the request URL.
|
|
|
|
|
[
|
|
|
|
|
"HTTP/1.1 302 Document Moved\nLocation: " % %
|
|
|
|
|
"\nContent-Length: 0\nContent-Type: text/plain\n\n" %
|
2006-07-17 04:27:43 -04:00
|
|
|
] "" make write exit-continuation get continue ;
|
2005-02-14 17:19:09 -05:00
|
|
|
|
2005-10-10 18:17:56 -04:00
|
|
|
: forward-to-id ( id -- )
|
2006-04-27 21:36:29 -04:00
|
|
|
#! When executed inside a 'show' call, this will force a
|
|
|
|
|
#! HTTP 302 to occur to instruct the browser to forward to
|
|
|
|
|
#! the request URL.
|
|
|
|
|
>r "request" get r> id>url append forward-to-url ;
|
2005-10-10 18:17:56 -04:00
|
|
|
|
2006-07-17 04:27:43 -04:00
|
|
|
: (show) ( quot -- hashtable )
|
2006-04-27 21:36:29 -04:00
|
|
|
#! See comments for show. The difference is the
|
|
|
|
|
#! quotation MUST set the content-type using 'serving-html'
|
|
|
|
|
#! or similar.
|
|
|
|
|
[
|
2006-07-17 04:27:43 -04:00
|
|
|
>callable t register-callback swap with-scope
|
|
|
|
|
exit-continuation get continue
|
2006-07-17 05:09:40 -04:00
|
|
|
] callcc1 nip restore-request "response" get ;
|
2006-04-27 21:36:29 -04:00
|
|
|
|
2005-02-14 17:19:09 -05:00
|
|
|
: show ( quot -- namespace )
|
2006-04-27 21:36:29 -04:00
|
|
|
#! Call the quotation with the URL associated with the current
|
|
|
|
|
#! continuation. All output from the quotation goes to the client
|
|
|
|
|
#! browser. When the URL is later referenced then
|
2006-07-17 04:27:43 -04:00
|
|
|
#! computation will resume from this 'show' call with a hashtable on
|
2006-04-27 21:36:29 -04:00
|
|
|
#! the stack containing any query or post parameters.
|
2006-07-17 04:27:43 -04:00
|
|
|
#! 'quot' has stack effect ( url -- )
|
2006-04-27 21:36:29 -04:00
|
|
|
#! NOTE: On return from 'show' the stack is exactly the same as
|
2006-07-17 04:27:43 -04:00
|
|
|
#! initial entry with 'quot' popped off and the hashtable pushed on. Even
|
2006-04-27 21:36:29 -04:00
|
|
|
#! if the quotation consumes items on the stack.
|
2006-05-25 00:06:50 -04:00
|
|
|
[ serving-html ] swap append (show) ;
|
2005-10-11 17:48:06 -04:00
|
|
|
|
|
|
|
|
: (show-final) ( quot -- namespace )
|
2006-04-27 21:36:29 -04:00
|
|
|
#! See comments for show-final. The difference is the
|
|
|
|
|
#! quotation MUST set the content-type using 'serving-html'
|
|
|
|
|
#! or similar.
|
2006-07-17 04:27:43 -04:00
|
|
|
with-scope exit-continuation get continue ;
|
2005-02-14 17:19:09 -05:00
|
|
|
|
2005-02-20 19:47:08 -05:00
|
|
|
: show-final ( quot -- namespace )
|
2006-04-27 21:36:29 -04:00
|
|
|
#! Similar to 'show', except the quotation does not receive the URL
|
|
|
|
|
#! to resume computation following 'show-final'. No continuation is
|
|
|
|
|
#! stored for this resumption. As a result, 'show-final' is for use
|
|
|
|
|
#! when a page is to be displayed with no further action to occur. Its
|
|
|
|
|
#! use is an optimisation to save having to generate and save a continuation
|
|
|
|
|
#! in that special case.
|
2006-07-17 04:27:43 -04:00
|
|
|
#! 'quot' has stack effect ( -- ).
|
2006-05-25 00:06:50 -04:00
|
|
|
[ serving-html ] swap append (show-final) ;
|
2005-02-20 19:47:08 -05:00
|
|
|
|
|
|
|
|
#! Name of variable for holding initial continuation id that starts
|
|
|
|
|
#! the responder.
|
2006-07-17 04:27:43 -04:00
|
|
|
SYMBOL: root-callback
|
2005-02-20 19:47:08 -05:00
|
|
|
|
|
|
|
|
: cont-get/post-responder ( id-or-f -- )
|
2006-07-17 04:27:43 -04:00
|
|
|
#! httpd responder that handles the root continuation request.
|
|
|
|
|
#! The requests for actual continuation are processed by the
|
|
|
|
|
#! 'callback-responder'.
|
|
|
|
|
[
|
|
|
|
|
root-callback get call
|
|
|
|
|
exit-continuation get continue
|
|
|
|
|
] with-exit-continuation ;
|
2006-01-23 18:01:46 -05:00
|
|
|
|
|
|
|
|
: quot-url ( quot -- url )
|
2006-07-17 04:27:43 -04:00
|
|
|
t register-callback ;
|
2006-01-23 18:01:46 -05:00
|
|
|
|
2005-02-14 17:19:09 -05:00
|
|
|
: quot-href ( text quot -- )
|
2006-04-27 21:36:29 -04:00
|
|
|
#! Write to standard output an HTML HREF where the href,
|
|
|
|
|
#! when referenced, will call the quotation and then return
|
|
|
|
|
#! back to the most recent 'show' call (via the callback-cc).
|
|
|
|
|
#! The text of the link will be the 'text' argument on the
|
|
|
|
|
#! stack.
|
|
|
|
|
<a quot-url =href a> write </a> ;
|
2005-02-14 17:19:09 -05:00
|
|
|
|
|
|
|
|
: install-cont-responder ( name quot -- )
|
2006-04-27 21:36:29 -04:00
|
|
|
#! Install a cont-responder with the given name
|
|
|
|
|
#! that will initially run the given quotation.
|
|
|
|
|
#!
|
|
|
|
|
#! Convert the quotation so it is run within a session namespace
|
|
|
|
|
#! and that namespace is initialized first.
|
2006-07-17 04:27:43 -04:00
|
|
|
[
|
2006-04-27 21:36:29 -04:00
|
|
|
[ cont-get/post-responder ] "get" set
|
|
|
|
|
[ cont-get/post-responder ] "post" set
|
|
|
|
|
swap "responder" set
|
2006-07-17 04:27:43 -04:00
|
|
|
root-callback set
|
2006-04-27 21:36:29 -04:00
|
|
|
] make-responder ;
|
2005-02-20 19:47:08 -05:00
|
|
|
|
2005-02-14 17:19:09 -05:00
|
|
|
: simple-page ( title quot -- )
|
2006-04-27 21:36:29 -04:00
|
|
|
#! Call the quotation, with all output going to the
|
|
|
|
|
#! body of an html page with the given title.
|
|
|
|
|
<html>
|
|
|
|
|
<head> <title> swap write </title> </head>
|
|
|
|
|
<body> call </body>
|
|
|
|
|
</html> ;
|
2005-02-14 17:19:09 -05:00
|
|
|
|
|
|
|
|
: styled-page ( title stylesheet-quot quot -- )
|
2006-04-27 21:36:29 -04:00
|
|
|
#! Call the quotation, with all output going to the
|
|
|
|
|
#! body of an html page with the given title. stylesheet-quot
|
|
|
|
|
#! is called to generate the required stylesheet.
|
|
|
|
|
<html>
|
|
|
|
|
<head>
|
|
|
|
|
<title> rot write </title>
|
|
|
|
|
swap call
|
|
|
|
|
</head>
|
|
|
|
|
<body> call </body>
|
|
|
|
|
</html> ;
|
2005-02-14 17:19:09 -05:00
|
|
|
|
|
|
|
|
: paragraph ( str -- )
|
2006-04-27 21:36:29 -04:00
|
|
|
#! Output the string as an html paragraph
|
|
|
|
|
<p> write </p> ;
|
2005-02-14 17:19:09 -05:00
|
|
|
|
|
|
|
|
: show-message-page ( message -- )
|
2006-04-27 21:36:29 -04:00
|
|
|
#! Display the message in an HTML page with an OK button.
|
|
|
|
|
[
|
|
|
|
|
"Press OK to Continue" [
|
|
|
|
|
swap paragraph
|
|
|
|
|
<a =href a> "OK" write </a>
|
|
|
|
|
] simple-page
|
|
|
|
|
] show 2drop ;
|
2005-02-14 17:19:09 -05:00
|
|
|
|
|
|
|
|
: vertical-layout ( list -- )
|
2006-04-27 21:36:29 -04:00
|
|
|
#! Given a list of HTML components, arrange them vertically.
|
|
|
|
|
<table>
|
2005-02-14 17:19:09 -05:00
|
|
|
[ <tr> <td> call </td> </tr> ] each
|
2006-04-27 21:36:29 -04:00
|
|
|
</table> ;
|
2005-02-14 17:19:09 -05:00
|
|
|
|
|
|
|
|
: horizontal-layout ( list -- )
|
2006-04-27 21:36:29 -04:00
|
|
|
#! Given a list of HTML components, arrange them horizontally.
|
|
|
|
|
<table>
|
|
|
|
|
<tr "top" =valign tr> [ <td> call </td> ] each </tr>
|
|
|
|
|
</table> ;
|
2005-02-14 17:19:09 -05:00
|
|
|
|
|
|
|
|
: button ( label -- )
|
2006-04-27 21:36:29 -04:00
|
|
|
#! Output an HTML submit button with the given label.
|
|
|
|
|
<input "submit" =type =value input/> ;
|