| 
									
										
										
										
											2019-04-19 15:38:03 +09:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-05 14:48:35 -07:00
										 |  |  | require "utils/curl" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-18 15:11:11 -08:00
										 |  |  | RSpec.describe "Utils::Curl" do | 
					
						
							| 
									
										
										
										
											2023-09-04 22:17:57 -04:00
										 |  |  |   include Utils::Curl | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-08 23:14:46 +00:00
										 |  |  |   let(:details) do | 
					
						
							| 
									
										
										
										
											2022-05-02 15:56:39 -04:00
										 |  |  |     details = { | 
					
						
							|  |  |  |       normal:     {}, | 
					
						
							|  |  |  |       cloudflare: {}, | 
					
						
							|  |  |  |       incapsula:  {}, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     details[:normal][:no_cookie] = { | 
					
						
							|  |  |  |       url:            "https://www.example.com/", | 
					
						
							|  |  |  |       final_url:      nil, | 
					
						
							| 
									
										
										
										
											2022-05-25 13:31:54 -04:00
										 |  |  |       status_code:    "403", | 
					
						
							| 
									
										
										
										
											2022-05-02 15:56:39 -04:00
										 |  |  |       headers:        { | 
					
						
							|  |  |  |         "age"            => "123456", | 
					
						
							|  |  |  |         "cache-control"  => "max-age=604800", | 
					
						
							|  |  |  |         "content-type"   => "text/html; charset=UTF-8", | 
					
						
							|  |  |  |         "date"           => "Wed, 1 Jan 2020 01:23:45 GMT", | 
					
						
							|  |  |  |         "etag"           => "\"3147526947+ident\"", | 
					
						
							|  |  |  |         "expires"        => "Wed, 31 Jan 2020 01:23:45 GMT", | 
					
						
							|  |  |  |         "last-modified"  => "Wed, 1 Jan 2020 00:00:00 GMT", | 
					
						
							|  |  |  |         "server"         => "ECS (dcb/7EA2)", | 
					
						
							|  |  |  |         "vary"           => "Accept-Encoding", | 
					
						
							|  |  |  |         "x-cache"        => "HIT", | 
					
						
							|  |  |  |         "content-length" => "3", | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       etag:           "3147526947+ident", | 
					
						
							|  |  |  |       content_length: "3", | 
					
						
							|  |  |  |       file:           "...", | 
					
						
							|  |  |  |       file_hash:      nil, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-13 15:36:34 -04:00
										 |  |  |     details[:normal][:ok] = details[:normal][:no_cookie].deep_dup | 
					
						
							| 
									
										
										
										
											2022-05-25 13:31:54 -04:00
										 |  |  |     details[:normal][:ok][:status_code] = "200" | 
					
						
							| 
									
										
										
										
											2022-05-02 15:56:39 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-13 15:36:34 -04:00
										 |  |  |     details[:normal][:single_cookie] = details[:normal][:no_cookie].deep_dup | 
					
						
							| 
									
										
										
										
											2022-05-02 15:56:39 -04:00
										 |  |  |     details[:normal][:single_cookie][:headers]["set-cookie"] = "a_cookie=for_testing" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-13 15:36:34 -04:00
										 |  |  |     details[:normal][:multiple_cookies] = details[:normal][:no_cookie].deep_dup | 
					
						
							| 
									
										
										
										
											2022-05-02 15:56:39 -04:00
										 |  |  |     details[:normal][:multiple_cookies][:headers]["set-cookie"] = [ | 
					
						
							|  |  |  |       "first_cookie=for_testing", | 
					
						
							|  |  |  |       "last_cookie=also_for_testing", | 
					
						
							|  |  |  |     ] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-13 15:36:34 -04:00
										 |  |  |     details[:normal][:blank_headers] = details[:normal][:no_cookie].deep_dup | 
					
						
							| 
									
										
										
										
											2022-05-02 15:56:39 -04:00
										 |  |  |     details[:normal][:blank_headers][:headers] = {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     details[:cloudflare][:single_cookie] = { | 
					
						
							|  |  |  |       url:            "https://www.example.com/", | 
					
						
							|  |  |  |       final_url:      nil, | 
					
						
							| 
									
										
										
										
											2022-05-25 13:31:54 -04:00
										 |  |  |       status_code:    "403", | 
					
						
							| 
									
										
										
										
											2022-05-02 15:56:39 -04:00
										 |  |  |       headers:        { | 
					
						
							|  |  |  |         "date"            => "Wed, 1 Jan 2020 01:23:45 GMT", | 
					
						
							|  |  |  |         "content-type"    => "text/plain; charset=UTF-8", | 
					
						
							|  |  |  |         "content-length"  => "16", | 
					
						
							|  |  |  |         "x-frame-options" => "SAMEORIGIN", | 
					
						
							|  |  |  |         "referrer-policy" => "same-origin", | 
					
						
							|  |  |  |         "cache-control"   => "private, max-age=0, no-store, no-cache, must-revalidate, post-check=0, pre-check=0", | 
					
						
							|  |  |  |         "expires"         => "Thu, 01 Jan 1970 00:00:01 GMT", | 
					
						
							|  |  |  |         "expect-ct"       => "max-age=604800, report-uri=\"https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct\"", | 
					
						
							| 
									
										
										
										
											2022-06-28 10:17:14 +01:00
										 |  |  |         "set-cookie"      => "__cf_bm=0123456789abcdef; path=/; expires=Wed, 31-Jan-20 01:23:45 GMT; " \ | 
					
						
							|  |  |  |                              "domain=www.example.com; HttpOnly; Secure; SameSite=None", | 
					
						
							| 
									
										
										
										
											2022-05-02 15:56:39 -04:00
										 |  |  |         "server"          => "cloudflare", | 
					
						
							|  |  |  |         "cf-ray"          => "0123456789abcdef-IAD", | 
					
						
							|  |  |  |         "alt-svc"         => "h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400", | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       etag:           nil, | 
					
						
							|  |  |  |       content_length: "16", | 
					
						
							|  |  |  |       file:           "error code: 1020", | 
					
						
							|  |  |  |       file_hash:      nil, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-13 15:36:34 -04:00
										 |  |  |     details[:cloudflare][:multiple_cookies] = details[:cloudflare][:single_cookie].deep_dup | 
					
						
							| 
									
										
										
										
											2022-05-02 15:56:39 -04:00
										 |  |  |     details[:cloudflare][:multiple_cookies][:headers]["set-cookie"] = [ | 
					
						
							|  |  |  |       "first_cookie=for_testing", | 
					
						
							| 
									
										
										
										
											2022-06-28 10:17:14 +01:00
										 |  |  |       "__cf_bm=abcdef0123456789; path=/; expires=Thu, 28-Apr-22 18:38:40 GMT; domain=www.example.com; HttpOnly; " \ | 
					
						
							|  |  |  |       "Secure; SameSite=None", | 
					
						
							| 
									
										
										
										
											2022-05-02 15:56:39 -04:00
										 |  |  |       "last_cookie=also_for_testing", | 
					
						
							|  |  |  |     ] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-13 15:36:34 -04:00
										 |  |  |     details[:cloudflare][:no_server] = details[:cloudflare][:single_cookie].deep_dup | 
					
						
							| 
									
										
										
										
											2022-05-02 15:56:39 -04:00
										 |  |  |     details[:cloudflare][:no_server][:headers].delete("server") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-13 15:36:34 -04:00
										 |  |  |     details[:cloudflare][:wrong_server] = details[:cloudflare][:single_cookie].deep_dup | 
					
						
							| 
									
										
										
										
											2022-05-02 15:56:39 -04:00
										 |  |  |     details[:cloudflare][:wrong_server][:headers]["server"] = "nginx 1.2.3" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # TODO: Make the Incapsula test data more realistic once we can find an | 
					
						
							|  |  |  |     # example website to reference. | 
					
						
							| 
									
										
										
										
											2024-07-13 15:36:34 -04:00
										 |  |  |     details[:incapsula][:single_cookie_visid_incap] = details[:normal][:no_cookie].deep_dup | 
					
						
							| 
									
										
										
										
											2022-05-02 15:56:39 -04:00
										 |  |  |     details[:incapsula][:single_cookie_visid_incap][:headers]["set-cookie"] = "visid_incap_something=something" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-13 15:36:34 -04:00
										 |  |  |     details[:incapsula][:single_cookie_incap_ses] = details[:normal][:no_cookie].deep_dup | 
					
						
							| 
									
										
										
										
											2022-05-02 15:56:39 -04:00
										 |  |  |     details[:incapsula][:single_cookie_incap_ses][:headers]["set-cookie"] = "incap_ses_something=something" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-13 15:36:34 -04:00
										 |  |  |     details[:incapsula][:multiple_cookies_visid_incap] = details[:normal][:no_cookie].deep_dup | 
					
						
							| 
									
										
										
										
											2022-05-02 15:56:39 -04:00
										 |  |  |     details[:incapsula][:multiple_cookies_visid_incap][:headers]["set-cookie"] = [ | 
					
						
							|  |  |  |       "first_cookie=for_testing", | 
					
						
							|  |  |  |       "visid_incap_something=something", | 
					
						
							|  |  |  |       "last_cookie=also_for_testing", | 
					
						
							|  |  |  |     ] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-13 15:36:34 -04:00
										 |  |  |     details[:incapsula][:multiple_cookies_incap_ses] = details[:normal][:no_cookie].deep_dup | 
					
						
							| 
									
										
										
										
											2022-05-02 15:56:39 -04:00
										 |  |  |     details[:incapsula][:multiple_cookies_incap_ses][:headers]["set-cookie"] = [ | 
					
						
							|  |  |  |       "first_cookie=for_testing", | 
					
						
							|  |  |  |       "incap_ses_something=something", | 
					
						
							|  |  |  |       "last_cookie=also_for_testing", | 
					
						
							|  |  |  |     ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     details | 
					
						
							| 
									
										
										
										
											2023-03-08 23:14:46 +00:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2022-05-02 15:56:39 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-08 23:14:46 +00:00
										 |  |  |   let(:location_urls) do | 
					
						
							| 
									
										
										
										
											2021-04-26 10:13:12 -04:00
										 |  |  |     %w[
 | 
					
						
							|  |  |  |       https://example.com/example/ | 
					
						
							|  |  |  |       https://example.com/example1/ | 
					
						
							|  |  |  |       https://example.com/example2/ | 
					
						
							|  |  |  |     ] | 
					
						
							| 
									
										
										
										
											2023-03-08 23:14:46 +00:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2021-04-26 10:13:12 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-08 23:14:46 +00:00
										 |  |  |   let(:response_hash) do | 
					
						
							| 
									
										
										
										
											2021-04-26 10:13:12 -04:00
										 |  |  |     response_hash = {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response_hash[:ok] = { | 
					
						
							|  |  |  |       status_code: "200", | 
					
						
							|  |  |  |       status_text: "OK", | 
					
						
							|  |  |  |       headers:     { | 
					
						
							|  |  |  |         "cache-control"  => "max-age=604800", | 
					
						
							|  |  |  |         "content-type"   => "text/html; charset=UTF-8", | 
					
						
							|  |  |  |         "date"           => "Wed, 1 Jan 2020 01:23:45 GMT", | 
					
						
							|  |  |  |         "expires"        => "Wed, 31 Jan 2020 01:23:45 GMT", | 
					
						
							|  |  |  |         "last-modified"  => "Thu, 1 Jan 2019 01:23:45 GMT", | 
					
						
							|  |  |  |         "content-length" => "123", | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-11 10:14:40 -05:00
										 |  |  |     response_hash[:ok_no_status_text] = response_hash[:ok].deep_dup | 
					
						
							|  |  |  |     response_hash[:ok_no_status_text].delete(:status_text) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response_hash[:ok_blank_header_value] = response_hash[:ok].deep_dup | 
					
						
							|  |  |  |     response_hash[:ok_blank_header_value][:headers]["range"] = "" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-26 10:13:12 -04:00
										 |  |  |     response_hash[:redirection] = { | 
					
						
							|  |  |  |       status_code: "301", | 
					
						
							|  |  |  |       status_text: "Moved Permanently", | 
					
						
							|  |  |  |       headers:     { | 
					
						
							|  |  |  |         "cache-control"  => "max-age=604800", | 
					
						
							|  |  |  |         "content-type"   => "text/html; charset=UTF-8", | 
					
						
							|  |  |  |         "date"           => "Wed, 1 Jan 2020 01:23:45 GMT", | 
					
						
							|  |  |  |         "expires"        => "Wed, 31 Jan 2020 01:23:45 GMT", | 
					
						
							|  |  |  |         "last-modified"  => "Thu, 1 Jan 2019 01:23:45 GMT", | 
					
						
							|  |  |  |         "content-length" => "123", | 
					
						
							|  |  |  |         "location"       => location_urls[0], | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response_hash[:redirection1] = { | 
					
						
							|  |  |  |       status_code: "301", | 
					
						
							|  |  |  |       status_text: "Moved Permanently", | 
					
						
							|  |  |  |       headers:     { | 
					
						
							|  |  |  |         "cache-control"  => "max-age=604800", | 
					
						
							|  |  |  |         "content-type"   => "text/html; charset=UTF-8", | 
					
						
							|  |  |  |         "date"           => "Wed, 1 Jan 2020 01:23:45 GMT", | 
					
						
							|  |  |  |         "expires"        => "Wed, 31 Jan 2020 01:23:45 GMT", | 
					
						
							|  |  |  |         "last-modified"  => "Thu, 1 Jan 2019 01:23:45 GMT", | 
					
						
							|  |  |  |         "content-length" => "123", | 
					
						
							|  |  |  |         "location"       => location_urls[1], | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response_hash[:redirection2] = { | 
					
						
							|  |  |  |       status_code: "301", | 
					
						
							|  |  |  |       status_text: "Moved Permanently", | 
					
						
							|  |  |  |       headers:     { | 
					
						
							|  |  |  |         "cache-control"  => "max-age=604800", | 
					
						
							|  |  |  |         "content-type"   => "text/html; charset=UTF-8", | 
					
						
							|  |  |  |         "date"           => "Wed, 1 Jan 2020 01:23:45 GMT", | 
					
						
							|  |  |  |         "expires"        => "Wed, 31 Jan 2020 01:23:45 GMT", | 
					
						
							|  |  |  |         "last-modified"  => "Thu, 1 Jan 2019 01:23:45 GMT", | 
					
						
							|  |  |  |         "content-length" => "123", | 
					
						
							|  |  |  |         "location"       => location_urls[2], | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response_hash[:redirection_no_scheme] = { | 
					
						
							|  |  |  |       status_code: "301", | 
					
						
							|  |  |  |       status_text: "Moved Permanently", | 
					
						
							|  |  |  |       headers:     { | 
					
						
							|  |  |  |         "cache-control"  => "max-age=604800", | 
					
						
							|  |  |  |         "content-type"   => "text/html; charset=UTF-8", | 
					
						
							|  |  |  |         "date"           => "Wed, 1 Jan 2020 01:23:45 GMT", | 
					
						
							|  |  |  |         "expires"        => "Wed, 31 Jan 2020 01:23:45 GMT", | 
					
						
							|  |  |  |         "last-modified"  => "Thu, 1 Jan 2019 01:23:45 GMT", | 
					
						
							|  |  |  |         "content-length" => "123", | 
					
						
							|  |  |  |         "location"       => "//www.example.com/example/", | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response_hash[:redirection_root_relative] = { | 
					
						
							|  |  |  |       status_code: "301", | 
					
						
							|  |  |  |       status_text: "Moved Permanently", | 
					
						
							|  |  |  |       headers:     { | 
					
						
							|  |  |  |         "cache-control"  => "max-age=604800", | 
					
						
							|  |  |  |         "content-type"   => "text/html; charset=UTF-8", | 
					
						
							|  |  |  |         "date"           => "Wed, 1 Jan 2020 01:23:45 GMT", | 
					
						
							|  |  |  |         "expires"        => "Wed, 31 Jan 2020 01:23:45 GMT", | 
					
						
							|  |  |  |         "last-modified"  => "Thu, 1 Jan 2019 01:23:45 GMT", | 
					
						
							|  |  |  |         "content-length" => "123", | 
					
						
							|  |  |  |         "location"       => "/example/", | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response_hash[:redirection_parent_relative] = { | 
					
						
							|  |  |  |       status_code: "301", | 
					
						
							|  |  |  |       status_text: "Moved Permanently", | 
					
						
							|  |  |  |       headers:     { | 
					
						
							|  |  |  |         "cache-control"  => "max-age=604800", | 
					
						
							|  |  |  |         "content-type"   => "text/html; charset=UTF-8", | 
					
						
							|  |  |  |         "date"           => "Wed, 1 Jan 2020 01:23:45 GMT", | 
					
						
							|  |  |  |         "expires"        => "Wed, 31 Jan 2020 01:23:45 GMT", | 
					
						
							|  |  |  |         "last-modified"  => "Thu, 1 Jan 2019 01:23:45 GMT", | 
					
						
							|  |  |  |         "content-length" => "123", | 
					
						
							|  |  |  |         "location"       => "./example/", | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-02 15:31:30 -04:00
										 |  |  |     response_hash[:duplicate_header] = { | 
					
						
							|  |  |  |       status_code: "200", | 
					
						
							|  |  |  |       status_text: "OK", | 
					
						
							|  |  |  |       headers:     { | 
					
						
							|  |  |  |         "cache-control"  => "max-age=604800", | 
					
						
							|  |  |  |         "content-type"   => "text/html; charset=UTF-8", | 
					
						
							|  |  |  |         "date"           => "Wed, 1 Jan 2020 01:23:45 GMT", | 
					
						
							|  |  |  |         "expires"        => "Wed, 31 Jan 2020 01:23:45 GMT", | 
					
						
							|  |  |  |         "last-modified"  => "Thu, 1 Jan 2019 01:23:45 GMT", | 
					
						
							|  |  |  |         "content-length" => "123", | 
					
						
							|  |  |  |         "set-cookie"     => [ | 
					
						
							|  |  |  |           "example1=first", | 
					
						
							|  |  |  |           "example2=second; Expires Wed, 31 Jan 2020 01:23:45 GMT", | 
					
						
							|  |  |  |           "example3=third", | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-26 10:13:12 -04:00
										 |  |  |     response_hash | 
					
						
							| 
									
										
										
										
											2023-03-08 23:14:46 +00:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2021-04-26 10:13:12 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-08 23:14:46 +00:00
										 |  |  |   let(:response_text) do | 
					
						
							| 
									
										
										
										
											2021-04-26 10:13:12 -04:00
										 |  |  |     response_text = {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response_text[:ok] = <<~EOS | 
					
						
							|  |  |  |       HTTP/1.1 #{response_hash[:ok][:status_code]} #{response_hash[:ok][:status_text]}\r | 
					
						
							|  |  |  |       Cache-Control: #{response_hash[:ok][:headers]["cache-control"]}\r | 
					
						
							|  |  |  |       Content-Type: #{response_hash[:ok][:headers]["content-type"]}\r | 
					
						
							|  |  |  |       Date: #{response_hash[:ok][:headers]["date"]}\r | 
					
						
							|  |  |  |       Expires: #{response_hash[:ok][:headers]["expires"]}\r | 
					
						
							|  |  |  |       Last-Modified: #{response_hash[:ok][:headers]["last-modified"]}\r | 
					
						
							|  |  |  |       Content-Length: #{response_hash[:ok][:headers]["content-length"]}\r | 
					
						
							|  |  |  |       \r | 
					
						
							|  |  |  |     EOS | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-11 10:14:40 -05:00
										 |  |  |     response_text[:ok_no_status_text] = response_text[:ok].sub(" #{response_hash[:ok][:status_text]}", "") | 
					
						
							|  |  |  |     response_text[:ok_blank_header_name] = response_text[:ok].sub( | 
					
						
							|  |  |  |       "#{response_hash[:ok][:headers]["date"]}\r\n", | 
					
						
							|  |  |  |       "#{response_hash[:ok][:headers]["date"]}\r\n: Test\r\n", | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     response_text[:ok_blank_header_value] = response_text[:ok].sub( | 
					
						
							|  |  |  |       "#{response_hash[:ok][:headers]["date"]}\r\n", | 
					
						
							|  |  |  |       "#{response_hash[:ok][:headers]["date"]}\r\nRange:\r\n", | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-26 10:13:12 -04:00
										 |  |  |     response_text[:redirection] = response_text[:ok].sub( | 
					
						
							|  |  |  |       "HTTP/1.1 #{response_hash[:ok][:status_code]} #{response_hash[:ok][:status_text]}\r", | 
					
						
							|  |  |  |       "HTTP/1.1 #{response_hash[:redirection][:status_code]} #{response_hash[:redirection][:status_text]}\r\n" \ | 
					
						
							|  |  |  |       "Location: #{response_hash[:redirection][:headers]["location"]}\r", | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response_text[:redirection_to_ok] = "#{response_text[:redirection]}#{response_text[:ok]}" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response_text[:redirections_to_ok] = <<~EOS | 
					
						
							|  |  |  |       #{response_text[:redirection].sub(location_urls[0], location_urls[2])} | 
					
						
							|  |  |  |       #{response_text[:redirection].sub(location_urls[0], location_urls[1])} | 
					
						
							|  |  |  |       #{response_text[:redirection]} | 
					
						
							|  |  |  |       #{response_text[:ok]} | 
					
						
							|  |  |  |     EOS | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-02 15:31:30 -04:00
										 |  |  |     response_text[:duplicate_header] = response_text[:ok].sub( | 
					
						
							|  |  |  |       /\r\n\Z/, | 
					
						
							|  |  |  |       "Set-Cookie: #{response_hash[:duplicate_header][:headers]["set-cookie"][0]}\r\n" \ | 
					
						
							|  |  |  |       "Set-Cookie: #{response_hash[:duplicate_header][:headers]["set-cookie"][1]}\r\n" \ | 
					
						
							|  |  |  |       "Set-Cookie: #{response_hash[:duplicate_header][:headers]["set-cookie"][2]}\r\n\r\n", | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-26 10:13:12 -04:00
										 |  |  |     response_text | 
					
						
							| 
									
										
										
										
											2023-03-08 23:14:46 +00:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2021-04-26 10:13:12 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-08 23:14:46 +00:00
										 |  |  |   let(:body) do | 
					
						
							| 
									
										
										
										
											2021-04-26 10:13:12 -04:00
										 |  |  |     body = {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     body[:default] = <<~EOS | 
					
						
							|  |  |  |       <!DOCTYPE html> | 
					
						
							|  |  |  |       <html> | 
					
						
							|  |  |  |         <head> | 
					
						
							|  |  |  |           <meta charset="utf-8"> | 
					
						
							|  |  |  |           <title>Example</title>
 | 
					
						
							|  |  |  |         </head>
 | 
					
						
							|  |  |  |         <body> | 
					
						
							|  |  |  |           <h1>Example</h1>
 | 
					
						
							|  |  |  |           <p>Hello, world!</p>
 | 
					
						
							|  |  |  |         </body>
 | 
					
						
							|  |  |  |       </html>
 | 
					
						
							|  |  |  |     EOS | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     body[:with_carriage_returns] = body[:default].sub("<html>\n", "<html>\r\n\r\n") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     body[:with_http_status_line] = body[:default].sub("<html>", "HTTP/1.1 200\r\n<html>") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     body | 
					
						
							| 
									
										
										
										
											2023-03-08 23:14:46 +00:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2021-04-26 10:13:12 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-11 10:14:40 -05:00
										 |  |  |   describe "::curl_executable" do | 
					
						
							|  |  |  |     it "returns `HOMEBREW_BREWED_CURL_PATH` when `use_homebrew_curl` is `true`" do | 
					
						
							|  |  |  |       expect(curl_executable(use_homebrew_curl: true)).to eq(HOMEBREW_BREWED_CURL_PATH) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "returns curl shim path when `use_homebrew_curl` is `false` or omitted" do | 
					
						
							|  |  |  |       curl_shim_path = HOMEBREW_SHIMS_PATH/"shared/curl" | 
					
						
							|  |  |  |       expect(curl_executable(use_homebrew_curl: false)).to eq(curl_shim_path) | 
					
						
							|  |  |  |       expect(curl_executable).to eq(curl_shim_path) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe "::curl_path" do | 
					
						
							|  |  |  |     it "returns a curl path string" do | 
					
						
							|  |  |  |       expect(curl_path).to match(%r{[^/]+(?:/[^/]+)*}) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe "::curl_args" do | 
					
						
							|  |  |  |     include Context | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-06 18:53:20 -04:00
										 |  |  |     let(:args) { ["foo"] } | 
					
						
							| 
									
										
										
										
											2020-12-19 18:02:39 -05:00
										 |  |  |     let(:user_agent_string) { "Lorem ipsum dolor sit amet" } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-06 18:53:20 -04:00
										 |  |  |     it "returns `--disable` as the first argument when HOMEBREW_CURLRC is not set" do | 
					
						
							| 
									
										
										
										
											2020-03-28 19:38:39 +00:00
										 |  |  |       # --disable must be the first argument according to "man curl" | 
					
						
							| 
									
										
										
										
											2020-12-19 18:02:39 -05:00
										 |  |  |       expect(curl_args(*args).first).to eq("--disable") | 
					
						
							| 
									
										
										
										
											2018-04-05 14:48:35 -07:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2018-04-08 16:07:21 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-15 11:29:02 +01:00
										 |  |  |     it "doesn't return `--disable` as the first argument when HOMEBREW_CURLRC is set but not a path" do | 
					
						
							| 
									
										
										
										
											2018-04-09 15:43:03 -07:00
										 |  |  |       ENV["HOMEBREW_CURLRC"] = "1" | 
					
						
							| 
									
										
										
										
											2020-12-19 18:02:39 -05:00
										 |  |  |       expect(curl_args(*args).first).not_to eq("--disable") | 
					
						
							| 
									
										
										
										
											2018-04-08 16:07:21 -07:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2019-05-17 10:14:54 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-15 11:29:02 +01:00
										 |  |  |     it "doesn't return `--config` when HOMEBREW_CURLRC is unset" do | 
					
						
							|  |  |  |       expect(curl_args(*args)).not_to include(a_string_starting_with("--config")) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "returns `--config` when HOMEBREW_CURLRC is a valid path" do | 
					
						
							|  |  |  |       Tempfile.create do |tmpfile| | 
					
						
							|  |  |  |         path = tmpfile.path | 
					
						
							|  |  |  |         ENV["HOMEBREW_CURLRC"] = path | 
					
						
							|  |  |  |         # We still expect --disable | 
					
						
							|  |  |  |         expect(curl_args(*args).first).to eq("--disable") | 
					
						
							|  |  |  |         expect(curl_args(*args).join(" ")).to include("--config #{path}") | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     ensure | 
					
						
							|  |  |  |       ENV["HOMEBREW_CURLRC"] = nil | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-06 18:53:20 -04:00
										 |  |  |     it "uses `--connect-timeout` when `:connect_timeout` is Numeric" do | 
					
						
							|  |  |  |       expect(curl_args(*args, connect_timeout: 123).join(" ")).to include("--connect-timeout 123") | 
					
						
							|  |  |  |       expect(curl_args(*args, connect_timeout: 123.4).join(" ")).to include("--connect-timeout 123.4") | 
					
						
							|  |  |  |       expect(curl_args(*args, connect_timeout: 123.4567).join(" ")).to include("--connect-timeout 123.457") | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "errors when `:connect_timeout` is not Numeric" do | 
					
						
							|  |  |  |       expect { curl_args(*args, connect_timeout: "test") }.to raise_error(TypeError) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "uses `--max-time` when `:max_time` is Numeric" do | 
					
						
							|  |  |  |       expect(curl_args(*args, max_time: 123).join(" ")).to include("--max-time 123") | 
					
						
							|  |  |  |       expect(curl_args(*args, max_time: 123.4).join(" ")).to include("--max-time 123.4") | 
					
						
							|  |  |  |       expect(curl_args(*args, max_time: 123.4567).join(" ")).to include("--max-time 123.457") | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "errors when `:max_time` is not Numeric" do | 
					
						
							|  |  |  |       expect { curl_args(*args, max_time: "test") }.to raise_error(TypeError) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-20 18:14:51 +01:00
										 |  |  |     it "uses `--retry 3` when HOMEBREW_CURL_RETRIES is unset" do | 
					
						
							| 
									
										
										
										
											2020-12-19 18:02:39 -05:00
										 |  |  |       expect(curl_args(*args).join(" ")).to include("--retry 3") | 
					
						
							| 
									
										
										
										
											2019-05-17 10:14:54 +01:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2020-03-20 18:14:51 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     it "uses the given value for `--retry` when HOMEBREW_CURL_RETRIES is set" do | 
					
						
							|  |  |  |       ENV["HOMEBREW_CURL_RETRIES"] = "10" | 
					
						
							| 
									
										
										
										
											2020-12-19 18:02:39 -05:00
										 |  |  |       expect(curl_args(*args).join(" ")).to include("--retry 10") | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-06 18:53:20 -04:00
										 |  |  |     it "uses `--retry` when `:retries` is a positive Integer" do | 
					
						
							|  |  |  |       expect(curl_args(*args, retries: 5).join(" ")).to include("--retry 5") | 
					
						
							| 
									
										
										
										
											2020-12-19 18:02:39 -05:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-06 18:53:20 -04:00
										 |  |  |     it "doesn't use `--retry` when `:retries` is nil or a non-positive Integer" do | 
					
						
							|  |  |  |       expect(curl_args(*args, retries: nil).join(" ")).not_to include("--retry") | 
					
						
							|  |  |  |       expect(curl_args(*args, retries: 0).join(" ")).not_to include("--retry") | 
					
						
							|  |  |  |       expect(curl_args(*args, retries: -1).join(" ")).not_to include("--retry") | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "errors when `:retries` is not Numeric" do | 
					
						
							|  |  |  |       expect { curl_args(*args, retries: "test") }.to raise_error(TypeError) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "uses `--retry-max-time` when `:retry_max_time` is Numeric" do | 
					
						
							|  |  |  |       expect(curl_args(*args, retry_max_time: 123).join(" ")).to include("--retry-max-time 123") | 
					
						
							|  |  |  |       expect(curl_args(*args, retry_max_time: 123.4).join(" ")).to include("--retry-max-time 123") | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "errors when `:retry_max_time` is not Numeric" do | 
					
						
							|  |  |  |       expect { curl_args(*args, retry_max_time: "test") }.to raise_error(TypeError) | 
					
						
							| 
									
										
										
										
											2020-12-19 18:02:39 -05:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-11 10:14:40 -05:00
										 |  |  |     it "uses `--show-error` when :show_error is `true`" do | 
					
						
							|  |  |  |       expect(curl_args(*args, show_error: true)).to include("--show-error") | 
					
						
							|  |  |  |       expect(curl_args(*args, show_error: false)).not_to include("--show-error") | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-16 00:31:47 +00:00
										 |  |  |     it "uses `--referer` when :referer is present" do | 
					
						
							|  |  |  |       expect(curl_args(*args, referer: "https://brew.sh").join(" ")).to include("--referer https://brew.sh") | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "doesn't use `--referer` when :referer is nil" do | 
					
						
							|  |  |  |       expect(curl_args(*args, referer: nil).join(" ")).not_to include("--referer") | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-19 18:02:39 -05:00
										 |  |  |     it "uses HOMEBREW_USER_AGENT_FAKE_SAFARI when `:user_agent` is `:browser` or `:fake`" do | 
					
						
							|  |  |  |       expect(curl_args(*args, user_agent: :browser).join(" ")) | 
					
						
							|  |  |  |         .to include("--user-agent #{HOMEBREW_USER_AGENT_FAKE_SAFARI}") | 
					
						
							|  |  |  |       expect(curl_args(*args, user_agent: :fake).join(" ")) | 
					
						
							|  |  |  |         .to include("--user-agent #{HOMEBREW_USER_AGENT_FAKE_SAFARI}") | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "uses HOMEBREW_USER_AGENT_CURL when `:user_agent` is `:default` or omitted" do | 
					
						
							|  |  |  |       expect(curl_args(*args, user_agent: :default).join(" ")).to include("--user-agent #{HOMEBREW_USER_AGENT_CURL}") | 
					
						
							|  |  |  |       expect(curl_args(*args, user_agent: nil).join(" ")).to include("--user-agent #{HOMEBREW_USER_AGENT_CURL}") | 
					
						
							|  |  |  |       expect(curl_args(*args).join(" ")).to include("--user-agent #{HOMEBREW_USER_AGENT_CURL}") | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "uses provided user agent string when `:user_agent` is a `String`" do | 
					
						
							|  |  |  |       expect(curl_args(*args, user_agent: user_agent_string).join(" ")) | 
					
						
							|  |  |  |         .to include("--user-agent #{user_agent_string}") | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-06 18:53:20 -04:00
										 |  |  |     it "errors when `:user_agent` is not a String or supported Symbol" do | 
					
						
							|  |  |  |       expect { curl_args(*args, user_agent: :an_unsupported_symbol) } | 
					
						
							|  |  |  |         .to raise_error(TypeError, ":user_agent must be :browser/:fake, :default, or a String") | 
					
						
							|  |  |  |       expect { curl_args(*args, user_agent: 123) }.to raise_error(TypeError) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-19 18:02:39 -05:00
										 |  |  |     it "uses `--fail` unless `:show_output` is `true`" do | 
					
						
							|  |  |  |       expect(curl_args(*args, show_output: false).join(" ")).to include("--fail") | 
					
						
							|  |  |  |       expect(curl_args(*args, show_output: nil).join(" ")).to include("--fail") | 
					
						
							|  |  |  |       expect(curl_args(*args).join(" ")).to include("--fail") | 
					
						
							|  |  |  |       expect(curl_args(*args, show_output: true).join(" ")).not_to include("--fail") | 
					
						
							| 
									
										
										
										
											2020-03-20 18:14:51 +01:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2025-01-11 10:14:40 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     it "uses `--progress-bar` outside of a `--verbose` context" do | 
					
						
							|  |  |  |       expect(curl_args(*args).join(" ")).to include("--progress-bar") | 
					
						
							|  |  |  |       with_context verbose: true do | 
					
						
							|  |  |  |         expect(curl_args(*args).join(" ")).not_to include("--progress-bar") | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     context "when `EnvConfig.curl_verbose?` is `true`" do | 
					
						
							|  |  |  |       before do | 
					
						
							|  |  |  |         allow(Homebrew::EnvConfig).to receive(:curl_verbose?).and_return(true) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it "uses `--verbose`" do | 
					
						
							|  |  |  |         expect(curl_args(*args).join(" ")).to include("--verbose") | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     context "when `EnvConfig.curl_verbose?` is `false`" do | 
					
						
							|  |  |  |       before do | 
					
						
							|  |  |  |         allow(Homebrew::EnvConfig).to receive(:curl_verbose?).and_return(false) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it "doesn't use `--verbose`" do | 
					
						
							|  |  |  |         expect(curl_args(*args).join(" ")).not_to include("--verbose") | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     context "when `$stdout.tty?` is `false`" do | 
					
						
							|  |  |  |       before do | 
					
						
							|  |  |  |         allow($stdout).to receive(:tty?).and_return(false) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it "uses `--silent`" do | 
					
						
							|  |  |  |         expect(curl_args(*args).join(" ")).to include("--silent") | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     context "when `$stdout.tty?` is `true`" do | 
					
						
							|  |  |  |       before do | 
					
						
							|  |  |  |         allow($stdout).to receive(:tty?).and_return(true) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it "doesn't use `--silent` outside of a `--quiet` context" do | 
					
						
							|  |  |  |         with_context quiet: false do | 
					
						
							|  |  |  |           expect(curl_args(*args).join(" ")).not_to include("--silent") | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with_context quiet: true do | 
					
						
							|  |  |  |           expect(curl_args(*args).join(" ")).to include("--silent") | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2018-04-05 14:48:35 -07:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2021-04-26 10:13:12 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-11 10:14:40 -05:00
										 |  |  |   describe "::url_protected_by_cloudflare?" do | 
					
						
							| 
									
										
										
										
											2022-05-02 15:56:39 -04:00
										 |  |  |     it "returns `true` when a URL is protected by Cloudflare" do | 
					
						
							|  |  |  |       expect(url_protected_by_cloudflare?(details[:cloudflare][:single_cookie])).to be(true) | 
					
						
							|  |  |  |       expect(url_protected_by_cloudflare?(details[:cloudflare][:multiple_cookies])).to be(true) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "returns `false` when a URL is not protected by Cloudflare" do | 
					
						
							|  |  |  |       expect(url_protected_by_cloudflare?(details[:cloudflare][:no_server])).to be(false) | 
					
						
							|  |  |  |       expect(url_protected_by_cloudflare?(details[:cloudflare][:wrong_server])).to be(false) | 
					
						
							|  |  |  |       expect(url_protected_by_cloudflare?(details[:normal][:no_cookie])).to be(false) | 
					
						
							|  |  |  |       expect(url_protected_by_cloudflare?(details[:normal][:ok])).to be(false) | 
					
						
							|  |  |  |       expect(url_protected_by_cloudflare?(details[:normal][:single_cookie])).to be(false) | 
					
						
							|  |  |  |       expect(url_protected_by_cloudflare?(details[:normal][:multiple_cookies])).to be(false) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "returns `false` when response headers are blank" do | 
					
						
							|  |  |  |       expect(url_protected_by_cloudflare?(details[:normal][:blank_headers])).to be(false) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-11 10:14:40 -05:00
										 |  |  |   describe "::url_protected_by_incapsula?" do | 
					
						
							| 
									
										
										
										
											2022-05-02 15:56:39 -04:00
										 |  |  |     it "returns `true` when a URL is protected by Cloudflare" do | 
					
						
							|  |  |  |       expect(url_protected_by_incapsula?(details[:incapsula][:single_cookie_visid_incap])).to be(true) | 
					
						
							|  |  |  |       expect(url_protected_by_incapsula?(details[:incapsula][:single_cookie_incap_ses])).to be(true) | 
					
						
							|  |  |  |       expect(url_protected_by_incapsula?(details[:incapsula][:multiple_cookies_visid_incap])).to be(true) | 
					
						
							|  |  |  |       expect(url_protected_by_incapsula?(details[:incapsula][:multiple_cookies_incap_ses])).to be(true) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "returns `false` when a URL is not protected by Incapsula" do | 
					
						
							|  |  |  |       expect(url_protected_by_incapsula?(details[:normal][:no_cookie])).to be(false) | 
					
						
							|  |  |  |       expect(url_protected_by_incapsula?(details[:normal][:ok])).to be(false) | 
					
						
							|  |  |  |       expect(url_protected_by_incapsula?(details[:normal][:single_cookie])).to be(false) | 
					
						
							|  |  |  |       expect(url_protected_by_incapsula?(details[:normal][:multiple_cookies])).to be(false) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "returns `false` when response headers are blank" do | 
					
						
							|  |  |  |       expect(url_protected_by_incapsula?(details[:normal][:blank_headers])).to be(false) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-11 10:14:40 -05:00
										 |  |  |   describe "::curl_version" do | 
					
						
							|  |  |  |     it "returns a curl version string" do | 
					
						
							|  |  |  |       expect(curl_version).to match(/^v?(\d+(?:\.\d+)+)$/) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe "::curl_supports_fail_with_body?" do | 
					
						
							|  |  |  |     it "returns `true` if curl version is 7.76.0 or higher" do | 
					
						
							|  |  |  |       allow_any_instance_of(Utils::Curl).to receive(:curl_version).and_return(Version.new("7.76.0")) | 
					
						
							|  |  |  |       expect(curl_supports_fail_with_body?).to be(true) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       allow_any_instance_of(Utils::Curl).to receive(:curl_version).and_return(Version.new("7.76.1")) | 
					
						
							|  |  |  |       expect(curl_supports_fail_with_body?).to be(true) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "returns `false` if curl version is lower than 7.76.0" do | 
					
						
							|  |  |  |       allow_any_instance_of(Utils::Curl).to receive(:curl_version).and_return(Version.new("7.75.0")) | 
					
						
							|  |  |  |       expect(curl_supports_fail_with_body?).to be(false) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe "::curl_supports_tls13?" do | 
					
						
							|  |  |  |     it "returns `true` if curl command is successful" do | 
					
						
							|  |  |  |       allow_any_instance_of(Kernel).to receive(:quiet_system).and_return(true) | 
					
						
							|  |  |  |       expect(curl_supports_tls13?).to be(true) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "returns `false` if curl command is not successful" do | 
					
						
							|  |  |  |       allow_any_instance_of(Kernel).to receive(:quiet_system).and_return(false) | 
					
						
							|  |  |  |       expect(curl_supports_tls13?).to be(false) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe "::http_status_ok?" do | 
					
						
							|  |  |  |     it "returns `true` when `status` is 1xx or 2xx" do | 
					
						
							|  |  |  |       expect(http_status_ok?("200")).to be(true) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "returns `false` when `status` is not 1xx or 2xx" do | 
					
						
							|  |  |  |       expect(http_status_ok?("301")).to be(false) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "returns `false` when `status` is `nil`" do | 
					
						
							|  |  |  |       expect(http_status_ok?(nil)).to be(false) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe "::parse_curl_output" do | 
					
						
							| 
									
										
										
										
											2021-04-26 10:13:12 -04:00
										 |  |  |     it "returns a correct hash when curl output contains response(s) and body" do | 
					
						
							|  |  |  |       expect(parse_curl_output("#{response_text[:ok]}#{body[:default]}")) | 
					
						
							|  |  |  |         .to eq({ responses: [response_hash[:ok]], body: body[:default] }) | 
					
						
							|  |  |  |       expect(parse_curl_output("#{response_text[:ok]}#{body[:with_carriage_returns]}")) | 
					
						
							|  |  |  |         .to eq({ responses: [response_hash[:ok]], body: body[:with_carriage_returns] }) | 
					
						
							|  |  |  |       expect(parse_curl_output("#{response_text[:ok]}#{body[:with_http_status_line]}")) | 
					
						
							|  |  |  |         .to eq({ responses: [response_hash[:ok]], body: body[:with_http_status_line] }) | 
					
						
							|  |  |  |       expect(parse_curl_output("#{response_text[:redirection_to_ok]}#{body[:default]}")) | 
					
						
							|  |  |  |         .to eq({ responses: [response_hash[:redirection], response_hash[:ok]], body: body[:default] }) | 
					
						
							|  |  |  |       expect(parse_curl_output("#{response_text[:redirections_to_ok]}#{body[:default]}")) | 
					
						
							|  |  |  |         .to eq({ | 
					
						
							|  |  |  |           responses: [ | 
					
						
							|  |  |  |             response_hash[:redirection2], | 
					
						
							|  |  |  |             response_hash[:redirection1], | 
					
						
							|  |  |  |             response_hash[:redirection], | 
					
						
							|  |  |  |             response_hash[:ok], | 
					
						
							|  |  |  |           ], | 
					
						
							|  |  |  |           body:      body[:default], | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "returns a correct hash when curl output contains HTTP response text and no body" do | 
					
						
							|  |  |  |       expect(parse_curl_output(response_text[:ok])).to eq({ responses: [response_hash[:ok]], body: "" }) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "returns a correct hash when curl output contains body and no HTTP response text" do | 
					
						
							|  |  |  |       expect(parse_curl_output(body[:default])).to eq({ responses: [], body: body[:default] }) | 
					
						
							|  |  |  |       expect(parse_curl_output(body[:with_carriage_returns])) | 
					
						
							|  |  |  |         .to eq({ responses: [], body: body[:with_carriage_returns] }) | 
					
						
							|  |  |  |       expect(parse_curl_output(body[:with_http_status_line])) | 
					
						
							|  |  |  |         .to eq({ responses: [], body: body[:with_http_status_line] }) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "returns correct hash when curl output is blank" do | 
					
						
							|  |  |  |       expect(parse_curl_output("")).to eq({ responses: [], body: "" }) | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2025-01-11 10:14:40 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     it "errors if response count exceeds `max_iterations`" do | 
					
						
							|  |  |  |       expect do | 
					
						
							|  |  |  |         parse_curl_output(response_text[:redirections_to_ok], max_iterations: 1) | 
					
						
							|  |  |  |       end.to raise_error("Too many redirects (max = 1)") | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2021-04-26 10:13:12 -04:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-11 10:14:40 -05:00
										 |  |  |   describe "::parse_curl_response" do | 
					
						
							| 
									
										
										
										
											2021-04-26 10:13:12 -04:00
										 |  |  |     it "returns a correct hash when given HTTP response text" do | 
					
						
							|  |  |  |       expect(parse_curl_response(response_text[:ok])).to eq(response_hash[:ok]) | 
					
						
							| 
									
										
										
										
											2025-01-11 10:14:40 -05:00
										 |  |  |       expect(parse_curl_response(response_text[:ok_no_status_text])).to eq(response_hash[:ok_no_status_text]) | 
					
						
							|  |  |  |       expect(parse_curl_response(response_text[:ok_blank_header_value])).to eq(response_hash[:ok_blank_header_value]) | 
					
						
							| 
									
										
										
										
											2021-04-26 10:13:12 -04:00
										 |  |  |       expect(parse_curl_response(response_text[:redirection])).to eq(response_hash[:redirection]) | 
					
						
							| 
									
										
										
										
											2022-05-02 15:31:30 -04:00
										 |  |  |       expect(parse_curl_response(response_text[:duplicate_header])).to eq(response_hash[:duplicate_header]) | 
					
						
							| 
									
										
										
										
											2021-04-26 10:13:12 -04:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-11 10:14:40 -05:00
										 |  |  |     it "skips over response header lines with blank header name" do | 
					
						
							|  |  |  |       expect(parse_curl_response(response_text[:ok_blank_header_name])).to eq(response_hash[:ok]) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-26 10:13:12 -04:00
										 |  |  |     it "returns an empty hash when given an empty string" do | 
					
						
							|  |  |  |       expect(parse_curl_response("")).to eq({}) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-11 10:14:40 -05:00
										 |  |  |   describe "::curl_response_last_location" do | 
					
						
							| 
									
										
										
										
											2021-04-26 10:13:12 -04:00
										 |  |  |     it "returns the last location header when given an array of HTTP response hashes" do | 
					
						
							|  |  |  |       expect(curl_response_last_location([ | 
					
						
							|  |  |  |         response_hash[:redirection], | 
					
						
							|  |  |  |         response_hash[:ok], | 
					
						
							|  |  |  |       ])).to eq(response_hash[:redirection][:headers]["location"]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(curl_response_last_location([ | 
					
						
							|  |  |  |         response_hash[:redirection2], | 
					
						
							|  |  |  |         response_hash[:redirection1], | 
					
						
							|  |  |  |         response_hash[:redirection], | 
					
						
							|  |  |  |         response_hash[:ok], | 
					
						
							|  |  |  |       ])).to eq(response_hash[:redirection][:headers]["location"]) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "returns the location as given, by default or when absolutize is false" do | 
					
						
							|  |  |  |       expect(curl_response_last_location([ | 
					
						
							|  |  |  |         response_hash[:redirection_no_scheme], | 
					
						
							|  |  |  |         response_hash[:ok], | 
					
						
							|  |  |  |       ])).to eq(response_hash[:redirection_no_scheme][:headers]["location"]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(curl_response_last_location([ | 
					
						
							|  |  |  |         response_hash[:redirection_root_relative], | 
					
						
							|  |  |  |         response_hash[:ok], | 
					
						
							|  |  |  |       ])).to eq(response_hash[:redirection_root_relative][:headers]["location"]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(curl_response_last_location([ | 
					
						
							|  |  |  |         response_hash[:redirection_parent_relative], | 
					
						
							|  |  |  |         response_hash[:ok], | 
					
						
							|  |  |  |       ])).to eq(response_hash[:redirection_parent_relative][:headers]["location"]) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "returns an absolute URL when absolutize is true and a base URL is provided" do | 
					
						
							|  |  |  |       expect( | 
					
						
							|  |  |  |         curl_response_last_location( | 
					
						
							|  |  |  |           [response_hash[:redirection_no_scheme], response_hash[:ok]], | 
					
						
							|  |  |  |           absolutize: true, | 
					
						
							|  |  |  |           base_url:   "https://brew.sh/test", | 
					
						
							|  |  |  |         ), | 
					
						
							|  |  |  |       ).to eq("https:#{response_hash[:redirection_no_scheme][:headers]["location"]}") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect( | 
					
						
							|  |  |  |         curl_response_last_location( | 
					
						
							|  |  |  |           [response_hash[:redirection_root_relative], response_hash[:ok]], | 
					
						
							|  |  |  |           absolutize: true, | 
					
						
							|  |  |  |           base_url:   "https://brew.sh/test", | 
					
						
							|  |  |  |         ), | 
					
						
							|  |  |  |       ).to eq("https://brew.sh#{response_hash[:redirection_root_relative][:headers]["location"]}") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect( | 
					
						
							|  |  |  |         curl_response_last_location( | 
					
						
							|  |  |  |           [response_hash[:redirection_parent_relative], response_hash[:ok]], | 
					
						
							|  |  |  |           absolutize: true, | 
					
						
							|  |  |  |           base_url:   "https://brew.sh/test1/test2", | 
					
						
							|  |  |  |         ), | 
					
						
							|  |  |  |       ).to eq(response_hash[:redirection_parent_relative][:headers]["location"].sub(/^\./, "https://brew.sh/test1")) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-11 10:14:40 -05:00
										 |  |  |     it "skips response hashes without a `:headers` value" do | 
					
						
							|  |  |  |       expect(curl_response_last_location([ | 
					
						
							|  |  |  |         response_hash[:redirection], | 
					
						
							|  |  |  |         { status_code: "404", status_text: "Not Found" }, | 
					
						
							|  |  |  |         response_hash[:ok], | 
					
						
							|  |  |  |       ])).to eq(response_hash[:redirection][:headers]["location"]) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-26 10:13:12 -04:00
										 |  |  |     it "returns nil when the response hash doesn't contain a location header" do | 
					
						
							|  |  |  |       expect(curl_response_last_location([response_hash[:ok]])).to be_nil | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2022-11-25 12:09:59 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-11 10:14:40 -05:00
										 |  |  |   describe "::curl_response_follow_redirections" do | 
					
						
							| 
									
										
										
										
											2022-11-25 12:09:59 +11:00
										 |  |  |     it "returns the original URL when there are no location headers" do | 
					
						
							|  |  |  |       expect( | 
					
						
							|  |  |  |         curl_response_follow_redirections( | 
					
						
							|  |  |  |           [response_hash[:ok]], | 
					
						
							|  |  |  |           "https://brew.sh/test1/test2", | 
					
						
							|  |  |  |         ), | 
					
						
							|  |  |  |       ).to eq("https://brew.sh/test1/test2") | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "returns the URL relative to base when locations are relative" do | 
					
						
							|  |  |  |       expect( | 
					
						
							|  |  |  |         curl_response_follow_redirections( | 
					
						
							|  |  |  |           [response_hash[:redirection_root_relative], response_hash[:ok]], | 
					
						
							|  |  |  |           "https://brew.sh/test1/test2", | 
					
						
							|  |  |  |         ), | 
					
						
							|  |  |  |       ).to eq("https://brew.sh/example/") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect( | 
					
						
							|  |  |  |         curl_response_follow_redirections( | 
					
						
							|  |  |  |           [response_hash[:redirection_parent_relative], response_hash[:ok]], | 
					
						
							|  |  |  |           "https://brew.sh/test1/test2", | 
					
						
							|  |  |  |         ), | 
					
						
							|  |  |  |       ).to eq("https://brew.sh/test1/example/") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect( | 
					
						
							|  |  |  |         curl_response_follow_redirections( | 
					
						
							|  |  |  |           [ | 
					
						
							|  |  |  |             response_hash[:redirection_parent_relative], | 
					
						
							|  |  |  |             response_hash[:redirection_parent_relative], | 
					
						
							|  |  |  |             response_hash[:ok], | 
					
						
							|  |  |  |           ], | 
					
						
							|  |  |  |           "https://brew.sh/test1/test2", | 
					
						
							|  |  |  |         ), | 
					
						
							|  |  |  |       ).to eq("https://brew.sh/test1/example/example/") | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "returns new base when there are absolute location(s)" do | 
					
						
							|  |  |  |       expect( | 
					
						
							|  |  |  |         curl_response_follow_redirections( | 
					
						
							|  |  |  |           [response_hash[:redirection], response_hash[:ok]], | 
					
						
							|  |  |  |           "https://brew.sh/test1/test2", | 
					
						
							|  |  |  |         ), | 
					
						
							|  |  |  |       ).to eq(location_urls[0]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect( | 
					
						
							|  |  |  |         curl_response_follow_redirections( | 
					
						
							|  |  |  |           [response_hash[:redirection], response_hash[:redirection_parent_relative], response_hash[:ok]], | 
					
						
							|  |  |  |           "https://brew.sh/test1/test2", | 
					
						
							|  |  |  |         ), | 
					
						
							|  |  |  |       ).to eq("#{location_urls[0]}example/") | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2025-01-11 10:14:40 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     it "skips response hashes without a `:headers` value" do | 
					
						
							|  |  |  |       expect( | 
					
						
							|  |  |  |         curl_response_follow_redirections( | 
					
						
							|  |  |  |           [ | 
					
						
							|  |  |  |             response_hash[:redirection_root_relative], | 
					
						
							|  |  |  |             { status_code: "404", status_text: "Not Found" }, | 
					
						
							|  |  |  |             response_hash[:ok], | 
					
						
							|  |  |  |           ], | 
					
						
							|  |  |  |           "https://brew.sh/test1/test2", | 
					
						
							|  |  |  |         ), | 
					
						
							|  |  |  |       ).to eq("https://brew.sh/example/") | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2022-11-25 12:09:59 +11:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2018-04-05 14:48:35 -07:00
										 |  |  | end |