This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-05-01
Channels
- # beginners (121)
- # boot (12)
- # cider (14)
- # clara (19)
- # cljsjs (1)
- # clojure (124)
- # clojure-italy (4)
- # clojure-nl (2)
- # clojure-russia (47)
- # clojure-spec (20)
- # clojure-uk (7)
- # clojurescript (102)
- # cursive (16)
- # datomic (10)
- # emacs (2)
- # events (2)
- # immutant (3)
- # luminus (5)
- # lumo (33)
- # off-topic (2)
- # om (5)
- # onyx (22)
- # parinfer (1)
- # pedestal (32)
- # protorepl (1)
- # re-frame (6)
- # reagent (2)
- # ring-swagger (2)
- # rum (1)
- # spacemacs (8)
- # specter (17)
- # yada (1)
How do I disable secure-headers
middleware? this does not seem to do it:
(def service {:env prod :io.pedestal.http/secure=-headers nil ::http/routes routes ::http/type :jetty ::http/port 8080}
:io.pedestal.http/secure=-headers
-> :io.pedestal.http/secure-headers
?
@danielcompton Yup, I'm a genius
I either have a typo that I can't see, or I misunderstand how Pedestal interceptors work.
I have an interceptor that modifies Vase query results to return them as a cvs string, rather than as a data structure.
It gets back to my client as the raw string, rather than as the transit that the client expects.
It looks like the problem is that modifying the context's :result in an interceptor somehow interrupts the interceptor chain, causing remaining interceptors not to run.
In this code, including the update-in
(rather than merely returning context
) causes trace-context
not to trigger, and returns the raw string generated by my csv
function.
What am I doing wrong? If it's a typo, I sure can't see it. If it is not legal to modify :response, then how do I generate results?
;;; From .edn file
"/csv-history" {:get [<#C49BSM9B3|vase>/query {:name :receipts-server.v1/csv-history-get
:query [:find [(pull ?e [*]) ...]
:where [?e :purchase/uid]]
:to :receipts/raw-history}
receipts-server.interceptors/generate-csv
receipts-server.interceptors/trace-context]}
;;; From .clj file
(def generate-csv
(i/interceptor
{:name ::generate-csv
:enter (fn [context]
(log/info :msg (str "**** 2 enter = " (:receipts/raw-history context)))
(log/info :msg (str "2 CONTEXT: " context))
(update-in context [:response] assoc
:body (csv (:receipts/raw-history context))
:headers {}
:status 200))
:leave (fn [context]
(log/info :msg (str "GEN-CSV LEAVE: " (:response context)))
context)}))
(def trace-context
(i/interceptor
{:name ::trace-context
:enter (fn [context]
(log/info :msg (str "TRACE ENTER: " (:response context)))
context)
:leave (fn [context]
(log/info :msg (str "TRACE LEAVE: " (:response context)))
context)}))
Thanks, I'll try that right now. But (despite having read that doc a few times) I don't see that requirement. (The only hint I see is the last line of the doc "Because a handler takes one kind of thing (request) and returns a different kind of thing (response), it can only be used in the last position of a stack.")
What is the underlying logic that prevents assigning :response
in the :enter
?
I don’t know that logic exactly but I’m guessing that :response
acts like a result in a web stack
Actually that makes sense - you should assoc :response
inside the last interceptor of your stack (it’s :leave
function) and only update it inside other interceptors
And here it is in the code (`terminator-injector`) https://github.com/pedestal/pedestal/blob/master/service/src/io/pedestal/http/impl/servlet_interceptor.clj#L364-L377
I'm not familiar with how a result acts in a web stack, but I guess that some mechanism looks for the existence of :response
and aborts calling the :leave
queue if a response already exists?
In any event, you are obviously correct. That change solved half my problem.
As expected, I now see calls to generate-csv/enter, trace-context/enter, trace-context/leave, and generate-csv/leave. All good so far.
But, my client is still receiving the text/plain
result, rather than the correct transit results.
My guess is that I'm putting the wrong thing in response.
Maybe I'm not supposed to supply the headers and status? Or maybe just give the body without any map wrapping it?
Ugh, I think I found what's going on... https://github.com/pedestal/pedestal/blob/master/service/src/io/pedestal/http.clj#L150 Looks like the body is only converted to Transit if it is a collection, not a string! Why?
So, questions for the gurus: - Why does Pedestal not allow a bare string to be passed back via transit? - Should Interceptors be better documented, explaining how and when to return a response? Where? In the Vase docs, or Pedestal, or both?
Is that true of Transit too? I've seen that the transit library will happily take a bare string.
There is even an example of this in readme of the transit library https://github.com/cognitect/transit-clj
Ah, but this is transit+json, so I guess it uses json as bearer and needs to be valid json too?
@deg the transit interceptor checks with (coll? body)
so that's the problem. Though, it seems the updated JSON RFC also does allow single strings now.
It was easier just to wrap my result in a map, than to change the Content-Type. The latter would have meant playing with cljs-ajax to figure out what make it happy. Its handling of random content-types is somewhat, umm, random.
And the re-frame stuff is nice enough, that I'm generally happy to put up with its opinionation. (if that's a word 🙂 )
Yeah not sure I'd wanna lock myself into using a http-fx library. What about retries, offline queuing etc?
Dunno yet. I'm still writing toy code, mostly for the sake of exploring Vase + Pedestal + re-frame + ...