Send image as a response

1,483 views
Skip to first unread message

Arnaud Benard

unread,
Jan 25, 2015, 5:32:04 PM1/25/15
to phoeni...@googlegroups.com
Hi,
I am trying to build a image converter webservice. I send an image through a POST request and then convert it with Mogrify (https://github.com/route/mogrify). I want to send the converted image as a response.
I tried converting the image to binary and putting appropriate headers but it doesn't seem to work.

Any hint on how to do this?


Thank you very much. :)
Arnaud

Chris McCord

unread,
Jan 25, 2015, 9:20:35 PM1/25/15
to phoeni...@googlegroups.com
What you have seems like it should work. What errors do you get? Have you tried setting the Content-Disposition header? i.e.:

`|> put_resp_header(“content-disposition”, "attachment; filename=“foobar.jpeg”)`


Chris

--
You received this message because you are subscribed to the Google Groups "phoenix-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to phoenix-talk...@googlegroups.com.
To post to this group, send email to phoeni...@googlegroups.com.
Visit this group at http://groups.google.com/group/phoenix-talk.
To view this discussion on the web visit https://groups.google.com/d/msgid/phoenix-talk/57403c59-d631-4a53-9a49-623b99b8d1fb%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Arnaud Benard

unread,
Jan 26, 2015, 2:24:25 PM1/26/15
to phoeni...@googlegroups.com
I get the following error. Putting the content-disposition header raises the same one.

19:23:16.197 [error] #PID<0.334.0> running Sharpie.Endpoint terminated
Server: localhost:4000 (http)
Request: POST /api/images
** (exit) an exception was raised:
    ** (FunctionClauseError) no function clause matching in Plug.Conn.resp/3
        (plug) lib/plug/conn.ex:358: Plug.Conn.resp(%Plug.Conn{adapter: {Plug.Adapters.Cowboy.Conn, :...}, assigns: %{}, before_send: [#Function<1.122333005/1 in Plug.Logger.call/2>], cookies: %Plug.Conn.Unfetched{aspect: :cookies}, halted: false, host: "localhost", method: "POST", owner: #PID<0.334.0>, params: %{"img" => %Plug.Upload{content_type: "image/jpeg", filename: "288c71bbc50eb6a4f784f291c1e02692.jpg", path: "/var/folders/z9/mbk_9k2d36qg5r2dxvf32www0000gn/T//plug-1422/multipart-300195-841075"}}, path_info: ["api", "images"], peer: {{127, 0, 0, 1}, 50771}, port: 4000, private: %{phoenix_action: :convert, phoenix_controller: Sharpie.ImageController, phoenix_endpoint: Sharpie.Endpoint, phoenix_layout: {Sharpie.LayoutView, :application}, phoenix_pipelines: [], phoenix_route: #Function<1.14025333/1 in Sharpie.Router.match/4>, phoenix_router: Sharpie.Router, phoenix_view: Sharpie.ImageView, plug_session_fetch: #Function<1.121476067/1 in Plug.Session.fetch_session/1>}, query_string: "", remote_ip: {127, 0, 0, 1}, req_cookies: %Plug.Conn.Unfetched{aspect: :cookies}, req_headers: [{"host", "localhost:4000"}, {"connection", "keep-alive"}, {"content-length", "79089"}, {"cache-control", "no-cache"}, {"origin", "chrome-extension://fdmmgilgnpjigdojojpjoooidkmcomcm"}, {"user-agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.91 Safari/537.36"}, {"content-type", "multipart/form-data; boundary=----WebKitFormBoundaryJxdFw5gqFsJ8bJ6i"}, {"accept", "*/*"}, {"dnt", "1"}, {"accept-encoding", "gzip, deflate"}, {"accept-language", "en-US,en;q=0.8,fr;q=0.6"}, {"cookie", "connect.sid=s%3A3z-R1IgqvHF80f4BofsL2Oms.Lf8a5pD%2FR%2BUsl4JqVDGltL%2FzLpb2IS7hmdbWYf3ElgI"}], resp_body: nil, resp_cookies: %{}, resp_headers: [{"cache-control", "max-age=0, private, must-revalidate"}, {"x-request-id", "YmLY7DzYhzm+xyJgYxGT"}, {"content-type", "image/jpeg; charset=utf-8"}, {"content-disposition", "attachment; filename=foobar.jpeg"}], scheme: :http, script_name: [], secret_key_base: "fIiAF9t/pWlTgHPX4+WAp5bxp1EnwkSbAMBFxezV+Rij3y9xFT/dnVVnTXfSgbZE", state: :unset, status: nil}, 200, #PID<0.338.0>)
        (plug) lib/plug/conn.ex:348: Plug.Conn.send_resp/3
        (sharpie) web/controllers/image_controller.ex:1: Sharpie.ImageController.phoenix_controller_pipeline/2
        (sharpie) lib/phoenix/router.ex:2: Sharpie.Router.call/2
        (plug) lib/plug/debugger.ex:104: Plug.Debugger.wrap/3
        (phoenix) lib/phoenix/endpoint/error_handler.ex:43: Phoenix.Endpoint.ErrorHandler.wrap/3
        (sharpie) lib/sharpie/endpoint.ex:1: Sharpie.Endpoint.phoenix_endpoint_pipeline/2
        (plug) lib/plug/debugger.ex:104: Plug.Debugger.wrap/3

Chris McCord

unread,
Jan 26, 2015, 2:43:39 PM1/26/15
to phoeni...@googlegroups.com
I just re-read the code, and since you have the path in `converted_image.path`, you should be able to just call `send_file/2` and let the plug adapter take care of everything for you.


Arnaud Benard

unread,
Jan 26, 2015, 5:28:25 PM1/26/15
to phoeni...@googlegroups.com
Cool. Thank you. 

I have just tried it and I get this type of result. 
���� JFIF ��C


My code is now (I get the same result without the headers):
  def convert(conn, _params) do
    img
= _params["img"]
    converted_image
= open(img.path) |> resize("100x100")
    conn
   
|> put_resp_content_type("image/jpeg")
   
|> put_resp_header("content-disposition", "attachment; filename=elixir.jpg")
   
|> send_file(200, converted_image.path)
 
end


My response has the right headers. 
  1. cache-control:
    max-age=0, private, must-revalidate
  2. connection:
    keep-alive
  3. content-disposition:
    attachment; filename=elixir.jpg
  4. content-length:
    5796
  5. content-type:
    image/jpeg; charset=utf-8
  6. date:
    Mon, 26 Jan 2015 22:19:46 GMT
  7. server:
    Cowboy
  8. x-request-id:
    5VogGkEp/KfBtTPjZ7KZ
I am testing this with Postman on Chrome.

Reply all
Reply to author
Forward
0 new messages