[racket] Servlet static file paths, I just don't get it

From: David Vanderson (david.vanderson at gmail.com)
Date: Mon Sep 30 21:28:17 EDT 2013

Erich,

In addition to Jay's options, I think one way to do what you want is to 
remove the "else" clause from dispatch-rules and instead pass your 
"respond-unknown" function to the serve/servlet 
#:file-not-found-responder keyword:

#lang racket
(require web-server/servlet-env
          web-server/servlet)

(define (lottery-app req)
   (response/xexpr '(html
      (head (title "Lottery App"))
      (body
       (img ([src "images/Sloth.png"]))
       (h1 "Under construction")))))

(define (respond-unknown req)
   (response/xexpr '(html
      (head (title "Unknown Response"))
      (body
       (img ([src "images/Sloth.png"]))
       (h1 "Unknown Response")))))

(define-values (dispatch input-url)
   (dispatch-rules
    (("lottery") lottery-app)))

(serve/servlet dispatch ; answers requests
                #:servlet-path "/lottery" ; is the default URL
                #:extra-files-paths (list (build-path 
(current-directory) "htdocs"))
                #:port 8080 ; is the port
                #:servlet-regexp #rx""
                #:file-not-found-responder respond-unknown)


Does this make sense?

Thanks,
Dave


On 09/29/2013 03:50 PM, Erich Rast wrote:
> Thanks a lot! That's what I was suspecting already.
>
> But I still wonder how to do achieve what I want. how do I make
> "http://my-server.com/lottery" respond to my lottery servlet, but every
> other request to respond with respond-unknown *and also* show an
> image file within respond-unknown? Is there no way to load a static
> file (e.g. by relative path) within such a "catch all" handler?
>
> I'm using a dispatcher because I want to later add lots of experimental
> servlets, all of which should have easy urls (my-server/lottery,
> my-server/test, etc.). Everything else should be handled by
> respond-unknown. Do I have to use a static web page instead of
> respond-unknown?
>
> Best,
>
> Erich
>
> On Sat, 28 Sep 2013 21:57:21 -0600
> Jay McCarthy <jay.mccarthy at gmail.com> wrote:
>
>> Hi Erich,
>>
>> You have programmed your servlet to respond to all requests, including
>> requests to URLs like "http://your-server.com/images/Sloth.png". If
>> you go to that URL, you'll see that it shows you the result of
>> respond-unknown.
>>
>> On Sat, Sep 28, 2013 at 4:05 PM, Erich Rast <erich at snafu.de> wrote:
>>> This is driving me nuts, I just cannot find the place where my
>>> servlet gets static files from. I run the following "server.scm" in
>>> a directory in which there is also "htdocs/images/Sloth.png" but no
>>> matter what combination of img src file paths and extra-file-paths
>>> I try, respond-unknown does not want to display the Sloth.png when
>>> I click run:
>>>
>>> #lang racket
>>> (require web-server/web-server
>>>           web-server/dispatch
>>>            web-server/servlet-env
>>>            web-server/servlet)
>>> (require "lottery/darkstar-lottery.scm")
>>>
>>> (define (respond-unknown req)
>>>    (response/xexpr '(html
>>>       (head (title "The 3-Toed Sloth"))
>>>       (body
>>>        (img ([src "images/Sloth.png"]))
>>>        (h1 "Under construction")))))
>>>
>>> (define-values (dispatch input-url)
>>>    (dispatch-rules
>>>     (("lottery") lottery-app)
>>>     (else respond-unknown)))
>> You did it right here when you said that if you go to anything other
>> than "/lottery" then you should run 'respond-unknown'
>>
>> If you look at section 5.1 of the documentation (the first section on
>> dispatch-rules) that has this paragraph:
>>
>> "When you use web-server/dispatch with serve/servlet, you almost
>> always want to use the #:servlet-regexp argument with the value "" to
>> capture all top-level requests. However, make sure you don’t include
>> an else in your rules if you are also serving static files, or else
>> the filesystem server will never see the requests."
>>
>> The problem mentioned is exactly what you did.
>>
>> Jay
>>
>>> (serve/servlet dispatch ; answers requests
>>>                 #:servlet-path "" ; is the default URL
>>>                 #:extra-files-paths (list (build-path
>>>                 (current-directory) "htdocs"))
>>>                 #:port 8080 ; is the port
>>>                 #:servlet-regexp #rx"")
>>>
>>> How do I make the servlet serve the file "htdocs/images/Sloth.png"
>>> relative to the servlet source directory and how do I address it in
>>> the "img" tag? I tried absolute paths, too, but no luck.
>>>
>>> Best,
>>>
>>> Erich
>>>
>>> P.S. For completeness, the content of
>>> lottery/darkstar-lottery.scm:
>>>
>>> #lang racket
>>> (require web-server/servlet
>>>           web-server/servlet-env)
>>> (provide lottery-app)
>>>
>>> (define (draw n total)
>>>    (sort
>>>     (take
>>>      (shuffle (for/list ((i (in-range total)))
>>>                 (add1 i)))
>>>      n)
>>>     <))
>>>
>>> (define (stringify numbers)
>>>    (string-append
>>>     (apply string-append
>>>            (for/list ([n (in-list (reverse (cdr (reverse
>>> numbers))))]) (format "~a, " n)))
>>>     (format "~a" (car (reverse numbers)))))
>>>
>>> (define (euromillions)
>>>    (define (draw-5-of-50)
>>>      (draw 5 50))
>>>    (define (draw-2-of-11)
>>>      (draw 2 11))
>>>    (format "The next lottery result is ~a with additional numbers
>>> ~a." (stringify (draw-5-of-50))
>>>            (stringify (draw-2-of-11))))
>>>
>>> (define (lottery-app req)
>>>    (response/xexpr
>>>     `(html (head (title "Euromillions"))
>>>            (body (p ,(euromillions))))))
>>>
>>> ;(serve/servlet lottery-app
>>> ;               #:servlet-path "/lottery"
>>> ;               #:port 8080
>>> ;               #:command-line #t)
>>> ____________________
>>>    Racket Users list:
>>>    http://lists.racket-lang.org/users
>>
>>
>
> ____________________
>    Racket Users list:
>    http://lists.racket-lang.org/users


Posted on the users mailing list.