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

From: J G Cho (gcho at fundingmatters.com)
Date: Sat Jun 25 23:25:16 EDT 2011

That was completely self-inflicted typo, which makes learning new
stuff that much more difficult. Thanks for catching it.

Got past that error and then ran into a few more. So it now reads:

#lang racket

(require web-server/web-server
         web-server/dispatchers/filesystem-map)
(require (prefix-in files: web-server/dispatchers/dispatch-files))

(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))

Now I am getting

#<procedure:...-server-unit.rkt:46:2>

(from both DrRacket and command-line) instead of a running file server.

Just for the hell of it, I changed (start-file-server (current-directory)) to
start-file-server
 and ran the code and got
#<procedure:start-file-server>
as I expected. Not that this helps me at all.

((start-file-server (current-directory))) just returns.

Is there something else I can/should try?

On Sat, Jun 25, 2011 at 10:56 PM, Jay McCarthy <jay.mccarthy at gmail.com> wrote:
> 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.