Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does ring's resource-response respond with application/octet-stream content type?

I am trying to figure out why Ring's resource-response is choosing to respond with an application/octet-stream content type. I recently updated some sample code, that I've been learning from, so that it uses the newer ring-defaults. Prior to using ring-defaults, this code responded with the html content type. Why is this now choosing octet-stream?

(ns replays.handler
  (:require [compojure.core :refer [GET defroutes]]
            [compojure.route :as route]
            [ring.util.response :refer [response resource-response]]
            [ring.middleware.json :as middleware]
            [ring.middleware.defaults :refer [wrap-defaults api-defaults]]))

(defroutes app-routes
  (GET  "/" [] (resource-response "index.html" {:root "public"}))
  (GET  "/widgets" [] (response [{:name "Widget 1"} {:name "Widget 2"}]))
  (route/resources "/public")
  (route/not-found "not found"))

(def app
  (-> app-routes
      (middleware/wrap-json-body)
      (middleware/wrap-json-response)
      (wrap-defaults api-defaults)))

And, for version numbers, here's the project file ...

(defproject replays "0.1.0-SNAPSHOT"

  :url "http://example.com/FIXME"
  :description "FIXME: write description"

  :plugins [[lein-pdo "0.1.1"]
            [lein-ring "0.9.3"]
            [lein-cljsbuild "1.0.5"]]

  :dependencies [[org.clojure/clojure "1.6.0"]
                 [org.clojure/core.async "0.1.346.0-17112a-alpha"]
                 [org.clojure/clojurescript "0.0-3126"]
                 [org.omcljs/om "0.8.8"]
                 [ring/ring-core "1.3.2"]
                 [ring/ring-json "0.3.1"]
                 [ring/ring-defaults "0.1.4"]
                 [compojure "1.3.2"]
                 [cljs-http "0.1.29"]]

  :source-paths ["src/clj"]

  :ring {:handler replays.handler/app}

  :cljsbuild {:builds [{:id "dev"
                        :source-paths ["src/cljs"]
                        :compiler {:output-to "resources/public/js/app.js"
                                   :output-dir "resources/public/js/out"
                                   :optimizations :none
                                   :source-map true}}]}

  :aliases {"up" ["pdo" "cljsbuild" "auto" "dev," "ring" "server-headless"]}

  :profiles {:dev {:dependencies [[javax.servlet/servlet-api "2.5"]
                                  [ring-mock "0.1.5"]]}})
like image 371
Ryan Avatar asked Mar 30 '15 02:03

Ryan


1 Answers

This is happening because api-defaults (actually it's ring.middleware.content-type) tries to guess your content-type based on the data you passed to it. It uses file extensions to do that and since you are using resource-response, there is no extension. So by default ring.middleware.content-type uses application/octet-stream.

The solution is to provide your content-type to the response like below:

(ns app.routes
  (:require [compojure.core :refer [defroutes GET]]
            [ring.util.response :as resp]))

(defroutes appRoutes
  ;; ...
  ;; your routes
  ;; ...
  (GET "/"
       resp/content-type (resp/resource-response "index.html" {:root "public"}) "text/html"))
like image 195
fasfsfgs Avatar answered Oct 13 '22 08:10

fasfsfgs