使用Racket servlets提供静态文件服务

4

我正在学习使用Racket进行服务器开发,但是在尝试使用静态资源时遇到了困难。根据这个答案,我成功地包含了一个静态样式表:

#lang racket

(require web-server/servlet
         web-server/servlet-env
         web-server/configuration/responders)

(define (home req)
  (response/xexpr
   '(html
     (head (link ([rel "stylesheet"] [type "text/css"] [href "/style.css"])))
     (body
      (span ([class "emph"]) "Hello, world!")))))

(define-values (dispatch input-url)
  (dispatch-rules
   [("home") home]
   [("style.css") (λ (_) (file-response 200 #"OK" "style.css"))]))

(serve/servlet dispatch
               #:servlet-regexp #rx""
               #:servlet-path "/home"
               #:server-root-path (current-directory))

然而,我仍然不确定如何在一般情况下完成这个任务,即提供#:extra-files-paths中的所有文件而不为它们每个文件创建一个调度规则。我尝试了Jay的建议,并通过将htdocs和extra-files-paths部分向上移动(我可能不应该在这里复制整个内容),改变了serve/servlet的调度器顺序,并且破坏了解析MIME类型的能力。总体而言,这是一团糟。
因此,以下任何问题都与我的问题相关/相关(从较少到更一般):
  1. 是否有更好的方法使用serve/servlet级别的工具来包含静态文件?
  2. 是否有人可以具体概述我如何重新排列serve/servlet中的组件而不会破坏事物?
  3. 是否有比文档更好的地方可以学习如何使用Racket中的低级服务器工具?(我在这个特定领域还很新,因此“了解更多关于服务器”的回答可能是有效的)
1个回答

1
我认为问题出在 #:servlet-regexp 上,它被设置为空正则表达式,这意味着它将匹配任何内容。一个简单的解决方案是限制这个正则表达式只匹配非静态资源;然后,所有其他请求都应该从 #:extra-files-paths 中提供服务。
也许你有某些原因需要拦截所有请求并在代码中处理它们?不确定。

一个合适的正则表达式是什么样子的?#rx".*\.rkt" 看起来语法有误。报错信息为:read: unknown escape sequence \. in string - Zelphir Kaltstahl
1
是的,这是经典的双重转义问题;Racket(以及大多数其他语言)将反斜杠解释为转义字符。由于您实际上想要在正则表达式中使用反斜杠,因此您需要将其编写为#rx".*\.rkt"。也就是说...需要双倍的反斜杠。让我们看看这个字符串是否能够通过堆栈溢出处理。 - John Clements

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接