resp.ezdoc 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. ::: Sending a response
  2. The Req object also allows you to send a response.
  3. You can only send one response. Any other attempt will
  4. trigger a crash. The response may be sent in one go or
  5. with its body streamed by chunks of arbitrary size.
  6. You can also set headers or the response body in advance
  7. and Cowboy will use them when you finally do reply.
  8. :: Reply
  9. You can send a reply with no particular headers or body.
  10. Cowboy will make sure to send the mandatory headers with
  11. the response.
  12. ``` erlang
  13. Req2 = cowboy_req:reply(200, Req).
  14. ```
  15. You can define headers to be sent with the response. Note
  16. that header names must be lowercase. Again, Cowboy will
  17. make sure to send the mandatory headers with the response.
  18. ``` erlang
  19. Req2 = cowboy_req:reply(303, [
  20. {<<"location">>, <<"http://ninenines.eu">>}
  21. ], Req).
  22. ```
  23. You can override headers that Cowboy would send otherwise.
  24. Any header set by the user will be used over the ones set
  25. by Cowboy. For example, you can advertise yourself as a
  26. different server.
  27. ``` erlang
  28. Req2 = cowboy_req:reply(200, [
  29. {<<"server">>, <<"yaws">>}
  30. ], Req).
  31. ```
  32. We also saw earlier how to force close the connection by
  33. overriding the connection header.
  34. Finally, you can also send a body with the response. Cowboy
  35. will automatically set the content-length header if you do.
  36. We recommend that you set the content-type header so the
  37. client may know how to read the body.
  38. ``` erlang
  39. Req2 = cowboy_req:reply(200, [
  40. {<<"content-type">>, <<"text/plain">>}
  41. ], "Hello world!", Req).
  42. ```
  43. Here is the same example but sending HTML this time.
  44. ``` erlang
  45. Req2 = cowboy_req:reply(200, [
  46. {<<"content-type">>, <<"text/html">>}
  47. ], "<html><head>Hello world!</head><body><p>Hats off!</p></body></html>", Req).
  48. ```
  49. Note that the reply is sent immediately.
  50. :: Chunked reply
  51. You can also stream the response body. First, you need to
  52. initiate the reply by sending the response status code.
  53. Then you can send the body in chunks of arbitrary size.
  54. ``` erlang
  55. Req2 = cowboy_req:chunked_reply(200, Req),
  56. cowboy_req:chunk("Hello...", Req2),
  57. cowboy_req:chunk("chunked...", Req2),
  58. cowboy_req:chunk("world!!", Req2).
  59. ```
  60. You should make sure to match on `ok` as an error may be
  61. returned.
  62. While it is possible to send a chunked response without
  63. a content-type header, it is still recommended. You can
  64. set this header or any other just like for normal replies.
  65. ``` erlang
  66. Req2 = cowboy_req:chunked_reply(200, [
  67. {<<"content-type">>, <<"text/html">>}
  68. ], Req),
  69. cowboy_req:chunk("<html><head>Hello world!</head>", Req2),
  70. cowboy_req:chunk("<body><p>Hats off!</p></body></html>", Req2).
  71. ```
  72. Note that the reply and each chunk following it are sent
  73. immediately.
  74. :: Preset response headers
  75. You can define response headers in advance. They will be
  76. merged into the headers given in the reply call. Headers
  77. in the reply call override preset response headers which
  78. override the default Cowboy headers.
  79. ``` erlang
  80. Req2 = cowboy_req:set_resp_header(<<"allow">>, "GET", Req).
  81. ```
  82. You can check if a response header has already been set.
  83. This will only check the response headers that you set,
  84. and not the ones Cowboy will add when actually sending
  85. the reply.
  86. ``` erlang
  87. cowboy_req:has_resp_header(<<"allow">>, Req).
  88. ```
  89. It will return `true` if the header is defined, and `false`
  90. otherwise.
  91. Finally, you can also delete a preset response header if
  92. needed. If you do, it will not be sent.
  93. ``` erlang
  94. Req2 = cowboy_req:delete_resp_header(<<"allow">>, Req).
  95. ```
  96. :: Preset response body
  97. You can set the response body in advance. Note that this
  98. body will be ignored if you then choose to send a chunked
  99. reply, or if you send a reply with an explicit body.
  100. ``` erlang
  101. Req2 = cowboy_req:set_resp_body("Hello world!", Req).
  102. ```
  103. You can also set a fun that will be called when it is time
  104. to send the body. There are three different ways of doing
  105. that.
  106. If you know the length of the body that needs to be sent,
  107. you should specify it, as it will help clients determine
  108. the remaining download time and allow them to inform the
  109. user.
  110. ``` erlang
  111. F = fun (Socket, Transport) ->
  112. Transport:send(Socket, "Hello world!")
  113. end,
  114. Req2 = cowboy_req:set_resp_body_fun(12, F, Req).
  115. ```
  116. If you do not know the length of the body, you should use
  117. a chunked response body fun instead.
  118. ``` erlang
  119. F = fun (SendChunk) ->
  120. Body = lists:duplicate(random:uniform(1024, $a)),
  121. SendChunk(Body)
  122. end,
  123. Req2 = cowboy_req:set_resp_body_fun(chunked, F, Req).
  124. ```
  125. Finally, you can also send data on the socket directly,
  126. without knowing the length in advance. Cowboy may be
  127. forced to close the connection at the end of the response
  128. though depending on the protocol capabilities.
  129. ``` erlang
  130. F = fun (Socket, Transport) ->
  131. Body = lists:duplicate(random:uniform(1024, $a)),
  132. Transport:send(Socket, Body)
  133. end,
  134. Req2 = cowboy_req:set_resp_body_fun(F, Req).
  135. ```
  136. :: Sending files
  137. You can send files directly from disk without having to
  138. read them. Cowboy will use the `sendfile` syscall when
  139. possible, which means that the file is sent to the socket
  140. directly from the kernel, which is a lot more performant
  141. than doing it from userland.
  142. Again, it is recommended to set the size of the file if it
  143. can be known in advance.
  144. ``` erlang
  145. F = fun (Socket, Transport) ->
  146. Transport:sendfile(Socket, "priv/styles.css")
  147. end,
  148. Req2 = cowboy_req:set_resp_body_fun(FileSize, F, Req).
  149. ```
  150. Please see the Ranch guide for more information about
  151. sending files.