@@ -1026,6 +1026,101 @@ defmodule Req.StepsTest do
10261026 end
10271027 end
10281028
1029+ describe "escape_url" do
1030+ test "can be disabled" do
1031+ resp =
1032+ Req . get! (
1033+ escape_url: false ,
1034+ plug: & Plug.Conn . send_resp ( & 1 , 200 , Plug.Conn . request_url ( & 1 ) ) ,
1035+ url: "http://lüthje.com/with space"
1036+ )
1037+
1038+ assert resp . body == "http://lüthje.com/with space"
1039+ end
1040+
1041+ test "escapes host" do
1042+ resp =
1043+ Req . get! (
1044+ plug: & Plug.Conn . send_resp ( & 1 , 200 , Plug.Conn . request_url ( & 1 ) ) ,
1045+ url: "http://lüthje.com/"
1046+ )
1047+
1048+ assert resp . body == "http://xn--lthje-kva.com/"
1049+ end
1050+
1051+ test "escapes percent encoded host" do
1052+ resp =
1053+ Req . get! (
1054+ plug: & Plug.Conn . send_resp ( & 1 , 200 , Plug.Conn . request_url ( & 1 ) ) ,
1055+ url:
1056+ "http://www.%E3%81%BB%E3%82%93%E3%81%A8%E3%81%86%E3%81%AB%E3%81%AA%E3%81%8C%E3%81%84%E3%82%8F%E3%81%91%E3%81%AE%E3%82%8F%E3%81%8B%E3%82%89%E3%81%AA%E3%81%84%E3%81%A9%E3%82%81%E3%81%84%E3%82%93%E3%82%81%E3%81%84%E3%81%AE%E3%82%89%E3%81%B9%E3%82%8B%E3%81%BE%E3%81%A0%E3%81%AA%E3%81%8C%E3%81%8F%E3%81%97%E3%81%AA%E3%81%84%E3%81%A8%E3%81%9F%E3%82%8A%E3%81%AA%E3%81%84.w3.mag.keio.ac.jp/"
1057+ )
1058+
1059+ assert resp . body ==
1060+ "http://www.xn--n8jaaaaai5bhf7as8fsfk3jnknefdde3fg11amb5gzdb4wi9bya3kc6lra.w3.mag.keio.ac.jp/"
1061+ end
1062+
1063+ test "escapes percent encoded unix socket" do
1064+ resp =
1065+ Req . get! (
1066+ plug:
1067+ & Plug.Conn . send_resp (
1068+ & 1 ,
1069+ 200 ,
1070+ [ to_string ( & 1 . scheme ) , "://" , & 1 . host , & 1 . request_path , "?" , & 1 . query_string ]
1071+ ) ,
1072+ url: "http+unix://user@%2Fvar%2Frun%2Ftest.sock/path?key=value"
1073+ )
1074+
1075+ assert resp . body == "http+unix:///var/run/test.sock/path?key=value"
1076+ end
1077+
1078+ test "raises on non-IP host that decodes to an IP" do
1079+ assert_raise ArgumentError , ~r/ invalid URL host: "%31%32%37%2E%30%2E%30%2E%31"/ , fn ->
1080+ Req . get! (
1081+ plug: & Plug.Conn . send_resp ( & 1 , 200 , Plug.Conn . request_url ( & 1 ) ) ,
1082+ url: "http://%31%32%37%2E%30%2E%30%2E%31/"
1083+ )
1084+ end
1085+ end
1086+
1087+ test "escapes path" do
1088+ % { req: req , url: url } = serve ( & Plug.Conn . send_resp ( & 1 , 200 , Plug.Conn . request_url ( & 1 ) ) )
1089+ resp = Req . get! ( req , url: "#{ url } /with space" )
1090+ assert resp . body == "#{ url } /with%20space"
1091+ end
1092+
1093+ test "escapes unescaped path with %" do
1094+ % { req: req , url: url } = serve ( & Plug.Conn . send_resp ( & 1 , 200 , Plug.Conn . request_url ( & 1 ) ) )
1095+ resp = Req . get! ( req , url: "#{ url } /with%2percent" )
1096+ assert resp . body == "#{ url } /with%252percent"
1097+ end
1098+
1099+ test "keeps escaped path untouched" do
1100+ % { req: req , url: url } = serve ( & Plug.Conn . send_resp ( & 1 , 200 , Plug.Conn . request_url ( & 1 ) ) )
1101+ resp = Req . get! ( req , url: "#{ url } /with%20space" )
1102+ assert resp . body == "#{ url } /with%20space"
1103+ end
1104+
1105+ test "escapes query" do
1106+ % { req: req , url: url } = serve ( & Plug.Conn . send_resp ( & 1 , 200 , Plug.Conn . request_url ( & 1 ) ) )
1107+ resp = Req . get! ( req , url: "#{ url } /?with space" )
1108+ assert resp . body == "#{ url } /?with%20space"
1109+ end
1110+
1111+ test "escapes unescaped query with %" do
1112+ % { req: req , url: url } = serve ( & Plug.Conn . send_resp ( & 1 , 200 , Plug.Conn . request_url ( & 1 ) ) )
1113+ resp = Req . get! ( req , url: "#{ url } /?with%2percent" )
1114+ assert resp . body == "#{ url } /?with%252percent"
1115+ end
1116+
1117+ test "keeps escaped query untouched" do
1118+ % { req: req , url: url } = serve ( & Plug.Conn . send_resp ( & 1 , 200 , Plug.Conn . request_url ( & 1 ) ) )
1119+ resp = Req . get! ( req , url: "#{ url } /?with%20space" )
1120+ assert resp . body == "#{ url } /?with%20space"
1121+ end
1122+ end
1123+
10291124 ## Response steps
10301125
10311126 describe "decompress_body" do
@@ -1733,6 +1828,32 @@ defmodule Req.StepsTest do
17331828 end
17341829 end
17351830
1831+ @ tag :capture_log
1832+ test "escapes location" do
1833+ % { req: req , url: url } =
1834+ serve ( fn
1835+ conn when conn . request_path == "/redirect" ->
1836+ location =
1837+ case conn . query_string do
1838+ "" -> "/oh hai?param=with spaces"
1839+ string -> "/oh hai?" <> string
1840+ end
1841+
1842+ redirect ( conn , 302 , location )
1843+
1844+ conn ->
1845+ Plug.Conn . send_resp ( conn , 200 , Plug.Conn . request_url ( conn ) )
1846+ end )
1847+
1848+ response = Req . get! ( req , url: "#{ url } /redirect" )
1849+ assert response . status == 200
1850+ assert response . body == "#{ url } /oh%20hai?param=with%20spaces"
1851+
1852+ response = Req . get! ( req , url: "#{ url } /redirect?a=already%20encoded" )
1853+ assert response . status == 200
1854+ assert response . body == "#{ url } /oh%20hai?a=already%20encoded"
1855+ end
1856+
17361857 test "without location" do
17371858 % { req: req , url: url } =
17381859 serve ( fn conn ->
0 commit comments