【问题标题】:Clojure Pedestal root serving as application/octet-streamClojure Pedestal 根用作应用程序/八位字节流
【发布时间】:2017-04-02 13:41:57
【问题描述】:

我正在尝试在Pedestal 0.5.1 中托管静态资产和服务。我正在使用::file-path 指向一个目录来托管文件。如果我直接导​​航到文件http://localhost:8888/index.html,这很好用,但是如果我转到站点的根目录http://localhost:8888,它会将文件作为application/octet-stream 而不是text/html。我调整了Hello World Sample,它具有相同的行为。

src/hello_world/server.clj

(ns hello-world.server
  (:require [io.pedestal.http :as http]
            [io.pedestal.http.route :as route])
  (:gen-class))

(def routes
  (route/expand-routes [[]]))

(def service
  {:env                 :prod
   ::http/join? false
   ::http/routes routes
   ::http/file-path "/tmp/www"       
   ::http/type          :jetty
   ::http/allowed-origins {:creds true :allowed-origins (constantly true)}       
   ::http/port          8888})

(defonce runnable-service (http/create-server service))

(defn -main
  "The entry-point for 'lein run'"
  [& args]
  (println "\nCreating your server...")
  (http/start runnable-service))

开始lein run

$ curl -i localhost:8888
HTTP/1.1 200 OK
Date: Fri, 18 Nov 2016 16:02:56 GMT
Last-Modified: Fri, 18 Nov 2016 15:10:22 GMT
Content-Type: application/octet-stream
Content-Length: 12
Server: Jetty(9.3.8.v20160314)

hello world

$ curl -i localhost:8888/index.html
HTTP/1.1 200 OK
Date: Fri, 18 Nov 2016 16:03:02 GMT
Last-Modified: Fri, 18 Nov 2016 15:10:22 GMT
Content-Type: text/html
Content-Length: 12
Server: Jetty(9.3.8.v20160314)

hello world

有没有办法修复“/”路由以提供正确的内容类型?

【问题讨论】:

    标签: clojure pedestal


    【解决方案1】:

    要为用作目录索引的文件获取正确的内容类型, 将拦截器io.pedestal.http.ring-middlewares/file-info 添加到 您的基座配置。

    这要求您使用覆盖默认拦截器链 你自己的,所以你必须包括所有的默认拦截器 您的应用所需要的。

    例如,您的服务可能如下所示:

    (ns hello-world.service
      (:require
       [io.pedestal.http :as http]
       [io.pedestal.http.ring-middlewares :as middlewares]
       [io.pedestal.http.route :as route]
       [io.pedestal.http.route.definition :refer [defroutes]]))
    
    (defroutes routes
      [[]])
    
    (def service
      {::http/type :jetty
       ::http/port 8080
       ::http/interceptors [http/log-request
                            http/not-found
                            middlewares/session
                            route/query-params
                            (middlewares/file-info)  ; HERE
                            (middlewares/file "/tmp/www")
                            ;; ... insert other interceptors ...
                            (route/router #(deref #'routes) :map-tree)]})
    

    对于您可能想要包含的其他默认拦截器的示例, 见default-interceptors

    说明

    这在实践中可能不会经常出现,因为许多网络 应用程序使用处理函数来生成主页 返回静态文件。

    对于替代解决方案,您可以为 / 编写路由处理程序 使用适当的返回 index.html 内容的路由 内容类型。

    Pedestal 的默认拦截器堆栈包括 io.pedestal.http.ring-middlewares/fileio.pedestal.http.ring-middlewares/content-type

    这些拦截器只是包装了 Ring 中间件函数 file-requestcontent-type-response

    file-request 返回一个 java.io.File 对象作为 HTTP 响应。

    content-type-response 检查请求 URI 以确定 Content-Type 标头的值。由于 URI 只是 / 它 默认为application/octet-stream

    相比之下ring.middleware.file-info(已弃用)检查 响应中实际 File 对象的路径。 见file-info-response

    io.pedestal.http.ring-middlewares/file-info 是拦截器 包装 ring.middleware.file-info/file-info-response

    【讨论】:

    • 最简单的改变可能是让“/”响应重定向到“index.html”。
    猜你喜欢
    • 2011-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-15
    • 2017-10-21
    • 1970-01-01
    • 2022-10-11
    相关资源
    最近更新 更多