[plt-scheme] Persisting multiple values with web-server

From: Don Felgar (dfelgar at rainier-infosys.com)
Date: Sun Jun 8 18:43:16 EDT 2003

How can I get the attached toy servlet to work correctly?  In its
current form the eyes and hair variables will be clobbered by a
concurrent client.  Solving this problem means forgetting the hair
value when setting the eyes value or vice versa.  The user should be
able to set none, one, or both variables, so it is not appropriate to
prompt for each value with successive pages.  I've tried passing
hidden inputs to work around the forgetting problem, but in my real
application this is unworkable.  It is necessary in my application to
set the values corresponding to hair and eyes in separate pages.

The only sure solution I can think of is to create a hash table and
store values in it on a per-client basis.  Then I am back to using
cookies, which defeats the purpose of web-server.

Wrapping the unit/sig and it's surrounding let in a lambda doesn't
solve the client interaction problems.


(require (lib "unitsig.ss")
         (lib "servlet-sig.ss" "web-server")
         (lib "servlet-helpers.ss" "web-server"))

(let ((eyes #f)
      (hair #f))
  (unit/sig () (import servlet^)

    (define (handle-request request)
      (lambda (k-url)
        (let* ((bindings (request-bindings request))
               (action (if (exists-binding? 'action bindings)
                           (extract-binding/single 'action bindings)

          (if (exists-binding? 'eyes bindings)
              (set! eyes (extract-binding/single 'eyes bindings)))
          (if (exists-binding? 'hair bindings)
              (set! hair (extract-binding/single 'hair bindings)))

           ((string=? action "Set Eye Color")
            `(html (body (form ((method "get") (action ,k-url))
                               (p "Eye color:"
                                  (input ((type "text")
                                          (name "eyes"))))
                               (input ((type "submit")))))))
           ((string=? action "Set Hair Color")
            `(html (body (form ((method "get") (action ,k-url))
                               (p "Hair color:"
                                  (input ((type "text")
                                          (name "hair"))))
                               (input ((type "submit")))))))
           (else (main-page k-url))))))

    (define (main-page k-url)
      `(html (body
              (form ((method "get") (action ,k-url))
                    (p "Eyes: " ,(if eyes eyes
                                     '(input ((type "submit")
                                              (name "action")
                                              (value "Set Eye Color")))))
                    (p "Hair: " ,(if hair hair
                                     '(input ((type "submit")
                                              (name "action")
                                              (value "Set Hair Color")))))))))
    (let loop ((request
                (send/suspend (handle-request initial-request))))
      (loop (send/suspend (handle-request request))))))

Posted on the users mailing list.