[racket] Help needed in writing Macro to transform (lambda (req) ....) to be used in web-server/servlet using auth cookies

From: Jay McCarthy (jay.mccarthy at gmail.com)
Date: Sat Jun 25 22:56:05 EDT 2011

2011/6/25 J G Cho <gcho at fundingmatters.com>:
> Yikes. I did read those documents before sometime ago when I started
> to learn about Racket. Without much comprehension! I really hoped to
> stay with WebApps part and stay oblivious to the internals of the
> Server. No such luck if I really want to take advantage of all the
> neat things it can do.
>
> Per your reply with links, I read them again trying to make sense of
> your sequencing dispatchers code. I think I can sorta get a feel for
> sequence:make and lift:make etc but ...
>
> Right now, I feel very comfortable 'hugging the shore' writing my
> little servlets. Stringing together my own custom dispatchers feel
> like taking a new sail boat out to uncharted big ocean.
>
> You see, I am still banging my head making my way around the documents
> on Racket HTTP Server, which is not the easiest to digest.
>
> First, the first sentence I read is  "Web Server is just a
> configuration of a dispatching server." My reaction is, 'Huh? I've
> never heard such statement over the years doing web apps starting with
> Perl CGI, PHP, JSP, RoR, GAE to mention a few. The statement might be
> true but it's not helping me find my way around. Sounds more like zen
> koan or something experts utter that completely makes no sense to a
> beginner.'

That section then explains what a dispatching server is.

>
> Second, I am trying out the file server example (from 3. Launching Servers).
>
> I made a file file-server.rkt by copying the code:
>
> #lang racket
>
> (require web-server/webserver

You meant (require web-server/web-server) as it says at the top of
that page. It's very easy to make typos on this sort of thing. :(

Jay

>         web-server/dispatchers/filesystem-map)
>
> (define (start-file-server base)
>   (serve
>      #:dispatch
>      (files:make
>         #:url->path (make->url->path base)
>         #:path->mime-type (lambda (path) #"application/octet-stream"))
>         #:indices (list "index.html")
>      #:port 8080))
>
> (start-file-server  (current-directory))
>
>
> I am invoking it with
>
> path to /Racket5.1/bin/racket -t file-server.rkt
>
> (the way I start my servlets from command line when not using DrRacket).
>
> I am greeted with:
>
> default-load-handler: cannot open input file: "path
> to/Racket5.1/collects/web-server/webserver.rkt" (No such file or
> directory; errno=2)
>
> Either the example is wrong or the author has left out a small detail
> obvious to him but not so to this beginner.
>
> It's going to take a bit of blood/sweat/tears/scars...
>
> But on the other hand, the design seems very promising/exciting if I
> can get past the initial learning pains. Taking the auth checking code
> out of the procedures is such a huge gain!
>
> Thank you.
>
>
> On Sat, Jun 25, 2011 at 1:10 PM, Jay McCarthy <jay.mccarthy at gmail.com> wrote:
>> The Web server is set up as a pipeline of "dispatchers", which are
>> functions that accept the TCP connection and the HTTP request and
>> either write a response or refuse to handle the request. This chapter
>> of the documentation:
>>
>> http://docs.racket-lang.org/web-server-internal/dispatchers.html
>>
>> discusses all the dispatchers that make up the standard server. They
>> can be combined very easily to customize the server to do exactly what
>> you want.
>>
>> Launching a server with your custom dispatcher is as easy as using
>> serve/servlet or web-server/insta:
>>
>> http://docs.racket-lang.org/web-server-internal/web-server.html
>>
>> Jay
>>
>> 2011/6/25 J G Cho <gcho at fundingmatters.com>:
>>> Seems like an elegant approach but....  "dispatcher outside the
>>> servlet" goes over my head like an UFO over a crop duster.
>>>
>>> I guess I will have to dig deeper into how the server is put together.
>>>
>>> On Sat, Jun 25, 2011 at 1:23 AM, Jay McCarthy <jay.mccarthy at gmail.com> wrote:
>>>> I find it more convenient to setup a dispatcher outside the servlet
>>>> that checks for the authenticator, that way once it has passed that
>>>> part of the dispatch chain, security can be relied upon. Something
>>>> like...
>>>>
>>>> (serve/launch/wait
>>>>  (sequence:make
>>>>  (lift:make (lambda (req) (if (or (unsecured-url? req)
>>>> (authenticated? req)) (next-dispatcher) (display-error/login-page))))
>>>>  (dispatch/servlet ...)))
>>>>
>>>> Then the servlet code can basically ignore the authenticator.
>>>>
>>>> Jay
>>>>
>>>> 2011/6/24 J G Cho <gcho at fundingmatters.com>:
>>>>> Hello again,
>>>>>
>>>>> I am guessing my problem calls for macro (which is "beyond my pay
>>>>> scale") and I am hoping this is the right place.
>>>>>
>>>>> Anyway, after reading this
>>>>> http://docs.racket-lang.org/web-server/faq.html#(part._.What_special_considerations_are_there_for_security_with_the_.Web_.Server_)
>>>>>
>>>>> I am led to believe that I will be writing lots of code like this:
>>>>>
>>>>> (define (some-sensitive-content req)
>>>>>
>>>>>   (if (user-is-legit req) ;check auth cookie
>>>>>      (...what have you ...)
>>>>>      (do-login-and-then-maybe-handle req)))
>>>>>
>>>>> So here is my first attemp at macro which sorta works:
>>>>>
>>>>> (define-syntax (guarded-handler stx)
>>>>>  (syntax-case stx ()
>>>>>    [(_ name body)
>>>>>     #'(begin (define (name req)
>>>>>                (if (user-is-legit req)
>>>>>                    body
>>>>>                    (ask-login req))))]))
>>>>>
>>>>> (guarded-handler gated-content
>>>>>                 (response/xexpr
>>>>>                  `(html (head (title "Gated Content"))
>>>>>                         (body (p "Shhhhhhh")
>>>>>                               (p
>>>>>                                (a ([href "/logout "])
>>>>>                                   "Done"))))))
>>>>>
>>>>> What I would really like, however, is
>>>>>
>>>>> (guard (lambda (req) ...)) to transformed to:
>>>>>
>>>>> (lambda (req)
>>>>>   (if (user-is-legit req)
>>>>>      (...what have you ...)
>>>>>      (do-login-and-then-maybe-handle  req)))
>>>>>
>>>>> such that I can use it like:
>>>>>
>>>>> (define (count-dot-com i)
>>>>>  (count-dot-com
>>>>>  (send/suspend/dispatch
>>>>>   (λ (embed/url)
>>>>>     (response/xexpr
>>>>>      `(html
>>>>>        (head (title "Count!"))
>>>>>        (body (h2 (a ([href ,(embed/url
>>>>>                              (guard (λ (req)
>>>>>                                (sub1 i))))])
>>>>>                     "-"))
>>>>> ...
>>>>>
>>>>> (define (count-dot-com i)
>>>>>  (send/suspend/dispatch
>>>>>   (λ (embed/url)
>>>>>     (response/xexpr
>>>>>      `(html
>>>>>        (head (title "Count!"))
>>>>>        (body (h2 (a ([href ,(embed/url
>>>>>
>>>>>                              (guard (λ (req)
>>>>>                                (count-dot-com (sub1 i))))])
>>>>>                     "-")
>>>>> ...
>>>>>
>>>>> in addition to the first case like this:
>>>>>
>>>>> (define gated-content
>>>>>  (guard (lambda (req) ...))
>>>>>
>>>>> Seems simple enough but my naive macros (not shown here to protect my
>>>>> fragile ego) are failing.
>>>>> Any help/suggestion is greatly appreciated.
>>>>>
>>>>> jGc
>>>>>
>>>>> _________________________________________________
>>>>>  For list-related administrative tasks:
>>>>>  http://lists.racket-lang.org/listinfo/users
>>>>
>>>>
>>>>
>>>> --
>>>> Jay McCarthy <jay at cs.byu.edu>
>>>> Assistant Professor / Brigham Young University
>>>> http://faculty.cs.byu.edu/~jay
>>>>
>>>> "The glory of God is Intelligence" - D&C 93
>>>>
>>>
>>
>>
>>
>> --
>> Jay McCarthy <jay at cs.byu.edu>
>> Assistant Professor / Brigham Young University
>> http://faculty.cs.byu.edu/~jay
>>
>> "The glory of God is Intelligence" - D&C 93
>>
>



-- 
Jay McCarthy <jay at cs.byu.edu>
Assistant Professor / Brigham Young University
http://faculty.cs.byu.edu/~jay

"The glory of God is Intelligence" - D&C 93



Posted on the users mailing list.