/unmaintained/cont-responder/callbacks.factor

http://github.com/abeaumont/factor · Factor · 122 lines · 93 code · 26 blank · 3 comment · 5 complexity · efc520392bf500d284bb58d5b9694b8f MD5 · raw file

  1. ! Copyright (C) 2004 Chris Double.
  2. ! Copyright (C) 2006, 2008 Slava Pestov.
  3. ! See http://factorcode.org/license.txt for BSD license.
  4. USING: http http.server io kernel math namespaces
  5. continuations calendar sequences assocs hashtables
  6. accessors arrays alarms quotations combinators fry
  7. http.server.redirection furnace assocs.lib urls ;
  8. IN: furnace.callbacks
  9. SYMBOL: responder
  10. TUPLE: callback-responder responder callbacks ;
  11. : <callback-responder> ( responder -- responder' )
  12. H{ } clone callback-responder boa ;
  13. TUPLE: callback cont quot expires alarm responder ;
  14. : timeout 20 minutes ;
  15. : timeout-callback ( callback -- )
  16. [ alarm>> cancel-alarm ]
  17. [ dup responder>> callbacks>> delete-at ]
  18. bi ;
  19. : touch-callback ( callback -- )
  20. dup expires>> [
  21. dup alarm>> [ cancel-alarm ] when*
  22. dup '[ , timeout-callback ] timeout later >>alarm
  23. ] when drop ;
  24. : <callback> ( cont quot expires? -- callback )
  25. f callback-responder get callback boa
  26. dup touch-callback ;
  27. : invoke-callback ( callback -- response )
  28. [ touch-callback ]
  29. [ quot>> request get exit-continuation get 3array ]
  30. [ cont>> continue-with ]
  31. tri ;
  32. : register-callback ( cont quot expires? -- id )
  33. <callback> callback-responder get callbacks>> set-at-unique ;
  34. : forward-to-url ( url -- * )
  35. #! When executed inside a 'show' call, this will force a
  36. #! HTTP 302 to occur to instruct the browser to forward to
  37. #! the request URL.
  38. <temporary-redirect> exit-with ;
  39. : cont-id "factorcontid" ;
  40. : forward-to-id ( id -- * )
  41. #! When executed inside a 'show' call, this will force a
  42. #! HTTP 302 to occur to instruct the browser to forward to
  43. #! the request URL.
  44. <url>
  45. swap cont-id set-query-param forward-to-url ;
  46. : restore-request ( pair -- )
  47. first3 exit-continuation set request set call ;
  48. SYMBOL: post-refresh-get?
  49. : redirect-to-here ( -- )
  50. #! Force a redirect to the client browser so that the browser
  51. #! goes to the current point in the code. This forces an URL
  52. #! change on the browser so that refreshing that URL will
  53. #! immediately run from this code point. This prevents the
  54. #! "this request will issue a POST" warning from the browser
  55. #! and prevents re-running the previous POST logic. This is
  56. #! known as the 'post-refresh-get' pattern.
  57. post-refresh-get? get [
  58. [
  59. [ ] t register-callback forward-to-id
  60. ] callcc1 restore-request
  61. ] [
  62. post-refresh-get? on
  63. ] if ;
  64. SYMBOL: current-show
  65. : store-current-show ( -- )
  66. #! Store the current continuation in the variable 'current-show'
  67. #! so it can be returned to later by 'quot-id'. Note that it
  68. #! recalls itself when the continuation is called to ensure that
  69. #! it resets its value back to the most recent show call.
  70. [ current-show set f ] callcc1
  71. [ restore-request store-current-show ] when* ;
  72. : show-final ( quot -- * )
  73. [ redirect-to-here store-current-show ] dip
  74. call exit-with ; inline
  75. : resuming-callback ( responder request -- id )
  76. url>> cont-id query-param swap callbacks>> at ;
  77. M: callback-responder call-responder* ( path responder -- response )
  78. '[
  79. , ,
  80. [ callback-responder set ]
  81. [ request get resuming-callback ] bi
  82. [
  83. invoke-callback
  84. ] [
  85. callback-responder get responder>> call-responder
  86. ] ?if
  87. ] with-exit-continuation ;
  88. : show-page ( quot -- )
  89. [ redirect-to-here store-current-show ] dip
  90. [
  91. [ ] t register-callback swap call exit-with
  92. ] callcc1 restore-request ; inline
  93. : quot-id ( quot -- id )
  94. current-show get swap t register-callback ;
  95. : quot-url ( quot -- url )
  96. quot-id f swap cont-id associate derive-url ;