Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding {:as :stream} support #3

Open
olivergeorge opened this issue Jan 5, 2014 · 3 comments
Open

Adding {:as :stream} support #3

olivergeorge opened this issue Jan 5, 2014 · 3 comments

Comments

@olivergeorge
Copy link

How about something like this to provide support for the {:as ...} feature.

Most of the functionality would be handled by clojure.java.io but we have to fight it a bit because the default :body type of String should be treated as content not a file descriptor.

The protocols might not be the best approach. They do allow flexibility and avoid having to hard code (cond (nil? x) ... (string? ...) :default ...) statements.

(defprotocol IAsByteArray
  "Used to coerce :body of response to byte-array"
  (as-byte-array [this]))

(extend-protocol IAsByteArray
  nil
  (as-byte-array [_] (byte-array 0))
  String
  (as-byte-array [s] (.getBytes s "utf8"))
  Object
  (as-byte-array [x] (as-byte-array (input-stream x)))
  java.io.InputStream
  (as-byte-array [is] (with-open [os (java.io.ByteArrayOutputStream.)]
                        (copy is os)
                        (.toByteArray os))))


(defprotocol IAsStream
  "Used to coerce :body of response to stream"
  (as-stream [this]))

(extend-protocol IAsStream
  nil
  (as-stream [_] (as-stream (byte-array 0)))
  String
  (as-stream [s] (as-stream (.getBytes s "utf8")))
  Object
  (as-stream [x] (clojure.java.io/input-stream x)))


(defprotocol IAsText
  "Used to coerce :body of response to text"
  (as-text [this]))

(extend-protocol IAsText
  nil
  (as-text [_] "")
  String
  (as-text [s] s)
  Object
  (as-text [x] (slurp x)))


(defn assoc-body-as
  "Coerce :body based on request :as.  Supports :stream :text and :byte-array.
  :body can be any sane type supported by clojure.java.io with the exception
  that we treat strings as content instead of file descriptors. "
  [resp opts]
  (merge resp (if-let [as-fun (case (:as opts)
                                :stream as-stream
                                :text as-text
                                :byte-array as-byte-array)]
                {:body (as-fun (:body resp))})))

(defn response-map
  "Build the response data based on the request data and the spec used in
  `with-fake-http`.

  This function merges in some defaults."
  [opts res-spec]
  (-> (merge
       {:opts opts
        :status 200
        :headers {:content-type "text/html"
                  :server "org.httpkit.fake"}
        :body ""}
       (cond
        (string? res-spec) {:body res-spec}
        (number? res-spec) {:status res-spec}
        :else res-spec))
      (assoc-body-as opts)))
@olivergeorge
Copy link
Author

Happy to help out with some test cases too. Bit of a can of worms really - there are quite a lot of cases to consider.

@d11wtq
Copy link
Owner

d11wtq commented Jan 9, 2014

Hey, sorry for the slow response. Started a new job on Monday and haven't had a lot of free time. I agree with what you're proposing, although I'd have to play around to see what feels like a good solution. Realistically I probably won't get the time to work on this for a few weeks due to weekend commitments, but if you sent a pull request, I'd be happy to review it and go from there.

@olivergeorge
Copy link
Author

Hello

My turn to apologise for slow response. Very happy to do that but I am
quite busy myself right now. I'll see how I go - let's keep in touch. If
you beat me to it I'm very happy to help in anyway.

cheers, Oliver

On 9 January 2014 23:15, d11wtq [email protected] wrote:

Hey, sorry for the slow response. Started a new job on Monday and haven't
had a lot of free time. I agree with what you're proposing, although I'd
have to play around to see what feels like a good solution. Realistically I
probably won't get the time to work on this for a few weeks due to weekend
commitments, but if you sent a pull request, I'd be happy to review it and
go from there.


Reply to this email directly or view it on GitHubhttps://github.com//issues/3#issuecomment-31925352
.

@icambron icambron mentioned this issue Nov 20, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants