Friday, August 14, 2009

Redirect Support

Perhaps we would want to control redirects from within the scripts - ideally something like below should work:

(redirect! url)

To enable such handling is straight forward:
(define (redirect! url 
#:status (status 'temporary-redirect)
#:headers (headers '()))
(define (header-helper h)
(cond ((header? h) h)
((pair? h) (make-header (string->bytes/utf-8 (car h))
(string->bytes/utf-8 (cdr h))))
((cookie? h)
(cookie->header h))))
(redirect-to (if (url? url) (url->string url) url)
(case status
((found) permanently)
((see-other) see-other)
((temporary-redirect) temporarily))
#:headers (map header-helper headers)))

The wrapper over redirect-to simplifies type conversion between url and string, and pairs of string to header, as well as cookie to header, so you can do the following:

(redirect! '/another/path' #:headers `(("test" . "me") ,(cookie-ref! "session")))

As redirect-to only returns a response/full struct, we need to raise the struct so we can escape the calling stack if the script is being included. And let's catch the object at the request handling:

(define (handle-request server request)
(parameterize (($pathinfo ($pathinfo))
($server server)
($request request))
(parameterize (($cookies (init-cookies!)))
(eval-script-if-changed! (shp-handler-required server))
(with-handlers ((response/basic?
(lambda (r) r)))
(make-response (include! (request-uri request)
#:topfilter (shp-handler-topfilter server)
#:partial? #t))))))

Now we can do a redirect from within the scripts! ;)

No comments:

Post a Comment