rfc7231_SUITE.erl 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508
  1. %% Copyright (c) 2017, Loïc Hoguin <essen@ninenines.eu>
  2. %%
  3. %% Permission to use, copy, modify, and/or distribute this software for any
  4. %% purpose with or without fee is hereby granted, provided that the above
  5. %% copyright notice and this permission notice appear in all copies.
  6. %%
  7. %% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  8. %% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  9. %% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  10. %% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  11. %% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  12. %% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  13. %% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  14. -module(rfc7231_SUITE).
  15. -compile(export_all).
  16. -compile(nowarn_export_all).
  17. -import(ct_helper, [config/2]).
  18. -import(ct_helper, [doc/1]).
  19. -import(cowboy_test, [gun_open/1]).
  20. all() ->
  21. cowboy_test:common_all().
  22. groups() ->
  23. cowboy_test:common_groups(ct_helper:all(?MODULE)).
  24. init_per_group(Name, Config) ->
  25. cowboy_test:init_common_groups(Name, Config, ?MODULE).
  26. end_per_group(Name, _) ->
  27. cowboy:stop_listener(Name).
  28. init_dispatch(_) ->
  29. cowboy_router:compile([{"[...]", [
  30. {"*", asterisk_h, []},
  31. {"/", hello_h, []},
  32. {"/echo/:key", echo_h, []},
  33. {"/resp/:key[/:arg]", resp_h, []}
  34. ]}]).
  35. %% @todo The documentation should list what methods, headers and status codes
  36. %% are handled automatically so users can know what befalls to them to implement.
  37. %% Methods.
  38. method_get(Config) ->
  39. doc("The GET method is accepted. (RFC7231 4.3.1)"),
  40. ConnPid = gun_open(Config),
  41. Ref = gun:get(ConnPid, "/", [
  42. {<<"accept-encoding">>, <<"gzip">>}
  43. ]),
  44. {response, nofin, 200, _} = gun:await(ConnPid, Ref),
  45. {ok, <<"Hello world!">>} = gun:await_body(ConnPid, Ref),
  46. ok.
  47. method_head(Config) ->
  48. doc("The HEAD method is accepted. (RFC7231 4.3.2)"),
  49. ConnPid = gun_open(Config),
  50. Ref = gun:head(ConnPid, "/", [
  51. {<<"accept-encoding">>, <<"gzip">>}
  52. ]),
  53. {response, fin, 200, _} = gun:await(ConnPid, Ref),
  54. ok.
  55. method_head_same_resp_headers_as_get(Config) ->
  56. doc("Responses to HEAD should return the same headers as GET. (RFC7231 4.3.2)"),
  57. ConnPid = gun_open(Config),
  58. Ref1 = gun:get(ConnPid, "/", [
  59. {<<"accept-encoding">>, <<"gzip">>}
  60. ]),
  61. {response, nofin, 200, Headers1} = gun:await(ConnPid, Ref1),
  62. {ok, <<"Hello world!">>} = gun:await_body(ConnPid, Ref1),
  63. Ref2 = gun:head(ConnPid, "/", [
  64. {<<"accept-encoding">>, <<"gzip">>}
  65. ]),
  66. {response, fin, 200, Headers2} = gun:await(ConnPid, Ref2),
  67. %% We remove the date header since the date might have changed between requests.
  68. Headers = lists:keydelete(<<"date">>, 1, Headers1),
  69. Headers = lists:keydelete(<<"date">>, 1, Headers2),
  70. ok.
  71. method_head_same_resp_headers_as_get_stream_reply(Config) ->
  72. doc("Responses to HEAD should return the same headers as GET. (RFC7231 4.3.2)"),
  73. ConnPid = gun_open(Config),
  74. Ref1 = gun:get(ConnPid, "/resp/stream_reply2/200", [
  75. {<<"accept-encoding">>, <<"gzip">>}
  76. ]),
  77. {response, nofin, 200, Headers1} = gun:await(ConnPid, Ref1),
  78. {ok, _} = gun:await_body(ConnPid, Ref1),
  79. Ref2 = gun:head(ConnPid, "/resp/stream_reply2/200", [
  80. {<<"accept-encoding">>, <<"gzip">>}
  81. ]),
  82. {response, fin, 200, Headers2} = gun:await(ConnPid, Ref2),
  83. %% We remove the date header since the date might have changed between requests.
  84. Headers = lists:keydelete(<<"date">>, 1, Headers1),
  85. Headers = lists:keydelete(<<"date">>, 1, Headers2),
  86. ok.
  87. method_post(Config) ->
  88. doc("The POST method is accepted. (RFC7231 4.3.3)"),
  89. ConnPid = gun_open(Config),
  90. Ref = gun:post(ConnPid, "/echo/read_body", [
  91. {<<"accept-encoding">>, <<"gzip">>},
  92. {<<"content-type">>, <<"application/x-www-form-urlencoded">>}
  93. ], <<"hello=world">>),
  94. {response, nofin, 200, _} = gun:await(ConnPid, Ref),
  95. {ok, <<"hello=world">>} = gun:await_body(ConnPid, Ref),
  96. ok.
  97. method_put(Config) ->
  98. doc("The PUT method is accepted. (RFC7231 4.3.4)"),
  99. ConnPid = gun_open(Config),
  100. Ref = gun:put(ConnPid, "/echo/read_body", [
  101. {<<"accept-encoding">>, <<"gzip">>},
  102. {<<"content-type">>, <<"application/x-www-form-urlencoded">>}
  103. ], <<"hello=world">>),
  104. {response, nofin, 200, _} = gun:await(ConnPid, Ref),
  105. {ok, <<"hello=world">>} = gun:await_body(ConnPid, Ref),
  106. ok.
  107. method_delete(Config) ->
  108. doc("The DELETE method is accepted. (RFC7231 4.3.5)"),
  109. ConnPid = gun_open(Config),
  110. Ref = gun:delete(ConnPid, "/echo/method", [
  111. {<<"accept-encoding">>, <<"gzip">>}
  112. ]),
  113. {response, nofin, 200, _} = gun:await(ConnPid, Ref),
  114. {ok, <<"DELETE">>} = gun:await_body(ConnPid, Ref),
  115. ok.
  116. method_connect(Config) ->
  117. doc("The CONNECT method is currently not implemented. (RFC7231 4.3.6)"),
  118. ConnPid = gun_open(Config),
  119. Ref = gun:request(ConnPid, <<"CONNECT">>, "localhost:8080", [
  120. {<<"accept-encoding">>, <<"gzip">>}
  121. ]),
  122. {response, fin, 501, _} = gun:await(ConnPid, Ref),
  123. ok.
  124. method_options(Config) ->
  125. doc("The OPTIONS method is accepted. (RFC7231 4.3.7)"),
  126. ConnPid = gun_open(Config),
  127. Ref = gun:options(ConnPid, "/echo/method", [
  128. {<<"accept-encoding">>, <<"gzip">>}
  129. ]),
  130. {response, nofin, 200, _} = gun:await(ConnPid, Ref),
  131. {ok, <<"OPTIONS">>} = gun:await_body(ConnPid, Ref),
  132. ok.
  133. method_options_asterisk(Config) ->
  134. doc("The OPTIONS method is accepted with an asterisk. (RFC7231 4.3.7)"),
  135. ConnPid = gun_open(Config),
  136. Ref = gun:options(ConnPid, "*", [
  137. {<<"accept-encoding">>, <<"gzip">>},
  138. {<<"x-echo">>, <<"method">>}
  139. ]),
  140. {response, nofin, 200, _} = gun:await(ConnPid, Ref),
  141. {ok, <<"OPTIONS">>} = gun:await_body(ConnPid, Ref),
  142. ok.
  143. method_options_content_length_0(Config) ->
  144. doc("The OPTIONS method must set the content-length header "
  145. "to 0 when no body is returned. (RFC7231 4.3.7)"),
  146. ConnPid = gun_open(Config),
  147. Ref = gun:options(ConnPid, "*", [
  148. {<<"accept-encoding">>, <<"gzip">>}
  149. ]),
  150. {response, fin, 200, Headers} = gun:await(ConnPid, Ref),
  151. {_, <<"0">>} = lists:keyfind(<<"content-length">>, 1, Headers),
  152. ok.
  153. method_trace(Config) ->
  154. doc("The TRACE method is currently not implemented. (RFC7231 4.3.8)"),
  155. ConnPid = gun_open(Config),
  156. Ref = gun:request(ConnPid, <<"TRACE">>, "/", [
  157. {<<"accept-encoding">>, <<"gzip">>}
  158. ]),
  159. {response, fin, 501, _} = gun:await(ConnPid, Ref),
  160. ok.
  161. %% Request headers.
  162. %% @todo
  163. %% Status codes.
  164. status_code_100(Config) ->
  165. doc("The 100 Continue status code can be sent. (RFC7231 6.2.1)"),
  166. ConnPid = gun_open(Config),
  167. Ref = gun:get(ConnPid, "/resp/inform2/100", [
  168. {<<"accept-encoding">>, <<"gzip">>}
  169. ]),
  170. {inform, 100, []} = gun:await(ConnPid, Ref),
  171. ok.
  172. %http10_status_code_100(Config) ->
  173. status_code_101(Config) ->
  174. doc("The 101 Switching Protocols status code can be sent. (RFC7231 6.2.2)"),
  175. ConnPid = gun_open(Config),
  176. Ref = gun:get(ConnPid, "/resp/inform2/101", [
  177. {<<"accept-encoding">>, <<"gzip">>}
  178. ]),
  179. {inform, 101, []} = gun:await(ConnPid, Ref),
  180. ok.
  181. %http10_status_code_100(Config) ->
  182. status_code_200(Config) ->
  183. doc("The 200 OK status code can be sent. (RFC7231 6.3.1)"),
  184. ConnPid = gun_open(Config),
  185. Ref = gun:get(ConnPid, "/resp/reply2/200", [
  186. {<<"accept-encoding">>, <<"gzip">>}
  187. ]),
  188. {response, _, 200, _} = gun:await(ConnPid, Ref),
  189. ok.
  190. status_code_201(Config) ->
  191. doc("The 201 Created status code can be sent. (RFC7231 6.3.2)"),
  192. ConnPid = gun_open(Config),
  193. Ref = gun:get(ConnPid, "/resp/reply2/201", [
  194. {<<"accept-encoding">>, <<"gzip">>}
  195. ]),
  196. {response, _, 201, _} = gun:await(ConnPid, Ref),
  197. ok.
  198. status_code_202(Config) ->
  199. doc("The 202 Accepted status code can be sent. (RFC7231 6.3.3)"),
  200. ConnPid = gun_open(Config),
  201. Ref = gun:get(ConnPid, "/resp/reply2/202", [
  202. {<<"accept-encoding">>, <<"gzip">>}
  203. ]),
  204. {response, _, 202, _} = gun:await(ConnPid, Ref),
  205. ok.
  206. status_code_203(Config) ->
  207. doc("The 203 Non-Authoritative Information status code can be sent. (RFC7231 6.3.4)"),
  208. ConnPid = gun_open(Config),
  209. Ref = gun:get(ConnPid, "/resp/reply2/203", [
  210. {<<"accept-encoding">>, <<"gzip">>}
  211. ]),
  212. {response, _, 203, _} = gun:await(ConnPid, Ref),
  213. ok.
  214. status_code_204(Config) ->
  215. doc("The 204 No Content status code can be sent. (RFC7231 6.3.5)"),
  216. ConnPid = gun_open(Config),
  217. Ref = gun:get(ConnPid, "/resp/reply2/204", [
  218. {<<"accept-encoding">>, <<"gzip">>}
  219. ]),
  220. {response, _, 204, _} = gun:await(ConnPid, Ref),
  221. ok.
  222. status_code_205(Config) ->
  223. doc("The 205 Reset Content status code can be sent. (RFC7231 6.3.6)"),
  224. ConnPid = gun_open(Config),
  225. Ref = gun:get(ConnPid, "/resp/reply2/205", [
  226. {<<"accept-encoding">>, <<"gzip">>}
  227. ]),
  228. {response, _, 205, _} = gun:await(ConnPid, Ref),
  229. ok.
  230. status_code_300(Config) ->
  231. doc("The 300 Multiple Choices status code can be sent. (RFC7231 6.4.1)"),
  232. ConnPid = gun_open(Config),
  233. Ref = gun:get(ConnPid, "/resp/reply2/300", [
  234. {<<"accept-encoding">>, <<"gzip">>}
  235. ]),
  236. {response, _, 300, _} = gun:await(ConnPid, Ref),
  237. ok.
  238. status_code_301(Config) ->
  239. doc("The 301 Moved Permanently status code can be sent. (RFC7231 6.4.2)"),
  240. ConnPid = gun_open(Config),
  241. Ref = gun:get(ConnPid, "/resp/reply2/301", [
  242. {<<"accept-encoding">>, <<"gzip">>}
  243. ]),
  244. {response, _, 301, _} = gun:await(ConnPid, Ref),
  245. ok.
  246. status_code_302(Config) ->
  247. doc("The 302 Found status code can be sent. (RFC7231 6.4.3)"),
  248. ConnPid = gun_open(Config),
  249. Ref = gun:get(ConnPid, "/resp/reply2/302", [
  250. {<<"accept-encoding">>, <<"gzip">>}
  251. ]),
  252. {response, _, 302, _} = gun:await(ConnPid, Ref),
  253. ok.
  254. status_code_303(Config) ->
  255. doc("The 303 See Other status code can be sent. (RFC7231 6.4.4)"),
  256. ConnPid = gun_open(Config),
  257. Ref = gun:get(ConnPid, "/resp/reply2/303", [
  258. {<<"accept-encoding">>, <<"gzip">>}
  259. ]),
  260. {response, _, 303, _} = gun:await(ConnPid, Ref),
  261. ok.
  262. status_code_305(Config) ->
  263. doc("The 305 Use Proxy status code can be sent. (RFC7231 6.4.5)"),
  264. ConnPid = gun_open(Config),
  265. Ref = gun:get(ConnPid, "/resp/reply2/305", [
  266. {<<"accept-encoding">>, <<"gzip">>}
  267. ]),
  268. {response, _, 305, _} = gun:await(ConnPid, Ref),
  269. ok.
  270. %% The status code 306 is no longer used. (RFC7231 6.4.6)
  271. status_code_307(Config) ->
  272. doc("The 307 Temporary Redirect status code can be sent. (RFC7231 6.4.7)"),
  273. ConnPid = gun_open(Config),
  274. Ref = gun:get(ConnPid, "/resp/reply2/307", [
  275. {<<"accept-encoding">>, <<"gzip">>}
  276. ]),
  277. {response, _, 307, _} = gun:await(ConnPid, Ref),
  278. ok.
  279. status_code_400(Config) ->
  280. doc("The 400 Bad Request status code can be sent. (RFC7231 6.5.1)"),
  281. ConnPid = gun_open(Config),
  282. Ref = gun:get(ConnPid, "/resp/reply2/400", [
  283. {<<"accept-encoding">>, <<"gzip">>}
  284. ]),
  285. {response, _, 400, _} = gun:await(ConnPid, Ref),
  286. ok.
  287. status_code_402(Config) ->
  288. doc("The 402 Payment Required status code can be sent. (RFC7231 6.5.2)"),
  289. ConnPid = gun_open(Config),
  290. Ref = gun:get(ConnPid, "/resp/reply2/402", [
  291. {<<"accept-encoding">>, <<"gzip">>}
  292. ]),
  293. {response, _, 402, _} = gun:await(ConnPid, Ref),
  294. ok.
  295. status_code_403(Config) ->
  296. doc("The 403 Forbidden status code can be sent. (RFC7231 6.5.3)"),
  297. ConnPid = gun_open(Config),
  298. Ref = gun:get(ConnPid, "/resp/reply2/403", [
  299. {<<"accept-encoding">>, <<"gzip">>}
  300. ]),
  301. {response, _, 403, _} = gun:await(ConnPid, Ref),
  302. ok.
  303. status_code_404(Config) ->
  304. doc("The 404 Not Found status code can be sent. (RFC7231 6.5.4)"),
  305. ConnPid = gun_open(Config),
  306. Ref = gun:get(ConnPid, "/resp/reply2/404", [
  307. {<<"accept-encoding">>, <<"gzip">>}
  308. ]),
  309. {response, _, 404, _} = gun:await(ConnPid, Ref),
  310. ok.
  311. status_code_405(Config) ->
  312. doc("The 405 Method Not Allowed status code can be sent. (RFC7231 6.5.5)"),
  313. ConnPid = gun_open(Config),
  314. Ref = gun:get(ConnPid, "/resp/reply2/405", [
  315. {<<"accept-encoding">>, <<"gzip">>}
  316. ]),
  317. {response, _, 405, _} = gun:await(ConnPid, Ref),
  318. ok.
  319. status_code_406(Config) ->
  320. doc("The 406 Not Acceptable status code can be sent. (RFC7231 6.5.6)"),
  321. ConnPid = gun_open(Config),
  322. Ref = gun:get(ConnPid, "/resp/reply2/406", [
  323. {<<"accept-encoding">>, <<"gzip">>}
  324. ]),
  325. {response, _, 406, _} = gun:await(ConnPid, Ref),
  326. ok.
  327. status_code_408(Config) ->
  328. doc("The 408 Request Timeout status code can be sent. (RFC7231 6.5.7)"),
  329. ConnPid = gun_open(Config),
  330. Ref = gun:get(ConnPid, "/resp/reply2/408", [
  331. {<<"accept-encoding">>, <<"gzip">>}
  332. ]),
  333. {response, _, 408, _} = gun:await(ConnPid, Ref),
  334. ok.
  335. status_code_409(Config) ->
  336. doc("The 409 Conflict status code can be sent. (RFC7231 6.5.8)"),
  337. ConnPid = gun_open(Config),
  338. Ref = gun:get(ConnPid, "/resp/reply2/409", [
  339. {<<"accept-encoding">>, <<"gzip">>}
  340. ]),
  341. {response, _, 409, _} = gun:await(ConnPid, Ref),
  342. ok.
  343. status_code_410(Config) ->
  344. doc("The 410 Gone status code can be sent. (RFC7231 6.5.9)"),
  345. ConnPid = gun_open(Config),
  346. Ref = gun:get(ConnPid, "/resp/reply2/410", [
  347. {<<"accept-encoding">>, <<"gzip">>}
  348. ]),
  349. {response, _, 410, _} = gun:await(ConnPid, Ref),
  350. ok.
  351. status_code_411(Config) ->
  352. doc("The 411 Length Required status code can be sent. (RFC7231 6.5.10)"),
  353. ConnPid = gun_open(Config),
  354. Ref = gun:get(ConnPid, "/resp/reply2/411", [
  355. {<<"accept-encoding">>, <<"gzip">>}
  356. ]),
  357. {response, _, 411, _} = gun:await(ConnPid, Ref),
  358. ok.
  359. status_code_413(Config) ->
  360. doc("The 413 Payload Too Large status code can be sent. (RFC7231 6.5.11)"),
  361. ConnPid = gun_open(Config),
  362. Ref = gun:get(ConnPid, "/resp/reply2/413", [
  363. {<<"accept-encoding">>, <<"gzip">>}
  364. ]),
  365. {response, _, 413, _} = gun:await(ConnPid, Ref),
  366. ok.
  367. status_code_414(Config) ->
  368. doc("The 414 URI Too Long status code can be sent. (RFC7231 6.5.12)"),
  369. ConnPid = gun_open(Config),
  370. Ref = gun:get(ConnPid, "/resp/reply2/414", [
  371. {<<"accept-encoding">>, <<"gzip">>}
  372. ]),
  373. {response, _, 414, _} = gun:await(ConnPid, Ref),
  374. ok.
  375. status_code_415(Config) ->
  376. doc("The 415 Unsupported Media Type status code can be sent. (RFC7231 6.5.13)"),
  377. ConnPid = gun_open(Config),
  378. Ref = gun:get(ConnPid, "/resp/reply2/415", [
  379. {<<"accept-encoding">>, <<"gzip">>}
  380. ]),
  381. {response, _, 415, _} = gun:await(ConnPid, Ref),
  382. ok.
  383. status_code_417(Config) ->
  384. doc("The 417 Expectation Failed status code can be sent. (RFC7231 6.5.14)"),
  385. ConnPid = gun_open(Config),
  386. Ref = gun:get(ConnPid, "/resp/reply2/417", [
  387. {<<"accept-encoding">>, <<"gzip">>}
  388. ]),
  389. {response, _, 417, _} = gun:await(ConnPid, Ref),
  390. ok.
  391. status_code_426(Config) ->
  392. doc("The 426 Upgrade Required status code can be sent. (RFC7231 6.5.15)"),
  393. ConnPid = gun_open(Config),
  394. Ref = gun:get(ConnPid, "/resp/reply2/426", [
  395. {<<"accept-encoding">>, <<"gzip">>}
  396. ]),
  397. {response, _, 426, _} = gun:await(ConnPid, Ref),
  398. ok.
  399. status_code_500(Config) ->
  400. doc("The 500 Internal Server Error status code can be sent. (RFC7231 6.6.1)"),
  401. ConnPid = gun_open(Config),
  402. Ref = gun:get(ConnPid, "/resp/reply2/500", [
  403. {<<"accept-encoding">>, <<"gzip">>}
  404. ]),
  405. {response, _, 500, _} = gun:await(ConnPid, Ref),
  406. ok.
  407. status_code_501(Config) ->
  408. doc("The 501 Not Implemented status code can be sent. (RFC7231 6.6.2)"),
  409. ConnPid = gun_open(Config),
  410. Ref = gun:get(ConnPid, "/resp/reply2/501", [
  411. {<<"accept-encoding">>, <<"gzip">>}
  412. ]),
  413. {response, _, 501, _} = gun:await(ConnPid, Ref),
  414. ok.
  415. status_code_502(Config) ->
  416. doc("The 502 Bad Gateway status code can be sent. (RFC7231 6.6.3)"),
  417. ConnPid = gun_open(Config),
  418. Ref = gun:get(ConnPid, "/resp/reply2/502", [
  419. {<<"accept-encoding">>, <<"gzip">>}
  420. ]),
  421. {response, _, 502, _} = gun:await(ConnPid, Ref),
  422. ok.
  423. status_code_503(Config) ->
  424. doc("The 503 Service Unavailable status code can be sent. (RFC7231 6.6.4)"),
  425. ConnPid = gun_open(Config),
  426. Ref = gun:get(ConnPid, "/resp/reply2/503", [
  427. {<<"accept-encoding">>, <<"gzip">>}
  428. ]),
  429. {response, _, 503, _} = gun:await(ConnPid, Ref),
  430. ok.
  431. status_code_504(Config) ->
  432. doc("The 504 Gateway Timeout status code can be sent. (RFC7231 6.6.5)"),
  433. ConnPid = gun_open(Config),
  434. Ref = gun:get(ConnPid, "/resp/reply2/504", [
  435. {<<"accept-encoding">>, <<"gzip">>}
  436. ]),
  437. {response, _, 504, _} = gun:await(ConnPid, Ref),
  438. ok.
  439. status_code_505(Config) ->
  440. doc("The 505 HTTP Version Not Supported status code can be sent. (RFC7231 6.6.6)"),
  441. ConnPid = gun_open(Config),
  442. Ref = gun:get(ConnPid, "/resp/reply2/505", [
  443. {<<"accept-encoding">>, <<"gzip">>}
  444. ]),
  445. {response, _, 505, _} = gun:await(ConnPid, Ref),
  446. ok.