We illustrate how continuations are essential to web programming and how applications on top of web servers are much harder to write due to the stateless nature of HTTP. Continuations turn web programs as easy to write as desktop applications.
59 lines
1.9 KiB
Racket
59 lines
1.9 KiB
Racket
#lang racket/base
|
|
|
|
(require web-server/servlet
|
|
web-server/servlet-env
|
|
web-server/http/redirect
|
|
xml)
|
|
|
|
(define (the-sum-application request)
|
|
(define m (get-number "First"))
|
|
(define n (get-number "Second"))
|
|
(response/xexpr
|
|
(make-page-showing-the-sum-of m n)))
|
|
(define (get-number label [error #f])
|
|
(define (html-page-asking-number url)
|
|
(response/xexpr (make-page (form-ask-number label url error))))
|
|
(define response (send/suspend html-page-asking-number))
|
|
(define n (extract-number 'number response))
|
|
(if (number? n)
|
|
n
|
|
(get-number label "Omg, you don't know how to write a number?")))
|
|
(define (make-page-showing-the-sum-of m n)
|
|
(make-page
|
|
`((p ,(format "~a + ~a = ~a" m n (+ (inexact->exact m) (inexact->exact n))))
|
|
(p ,@(button-to "/" "Do it again!")))))
|
|
(define (make-page content)
|
|
(define title "The sum application")
|
|
`(html
|
|
(head (title ,title))
|
|
(body (h1 ,title)
|
|
,@content)))
|
|
(define (form-ask-number label action [error #f])
|
|
`((form ([action ,action] [method "get"])
|
|
,label ":" (br)
|
|
(input ([type "text"] [name "number"] [value ""]))
|
|
,@(if error `((br) (font ((color "#ff0000")) ,error) (br)) '())
|
|
(input ([type "submit"] [value "Go!"])))))
|
|
(define (button-to url text)
|
|
`((form ([action ,url] [method "get"])
|
|
(input ([type "submit"] [value ,text])))))
|
|
|
|
(define (main)
|
|
(define port 1025)
|
|
(displayln (format "Serving on localhost:~a" port))
|
|
(serve/servlet the-sum-application
|
|
#:port port
|
|
#:listen-ip #f
|
|
#:command-line? #t
|
|
#:servlet-path ""
|
|
#:servlet-regexp #rx""))
|
|
|
|
(module+ main
|
|
(main))
|
|
|
|
(define (extract-number id response)
|
|
(string->number
|
|
(bytes->string/utf-8
|
|
(binding:form-value
|
|
(bindings-assq (string->bytes/utf-8 (symbol->string id))
|
|
(request-bindings/raw response))))))
|