From 0e01d960e8c9f5bf87455d2abebdcb65e607ee22 Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Tue, 1 Nov 2022 16:45:26 -0300 Subject: [PATCH 01/78] Accept regexp values for ignore-files via CLI --- lib/html_proofer/configuration.rb | 12 +++++++++++- lib/html_proofer/runner.rb | 10 ++++++++-- spec/html-proofer/command_spec.rb | 8 +++++++- spec/spec_helper.rb | 5 +++++ 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/lib/html_proofer/configuration.rb b/lib/html_proofer/configuration.rb index 62f00d6e..f5a4edfc 100644 --- a/lib/html_proofer/configuration.rb +++ b/lib/html_proofer/configuration.rb @@ -134,7 +134,17 @@ def parse_cli_options(args) section(opts, "Ignore Configuration") do set_option(opts, "--ignore-files [FILE1,FILE2,...]") do |long_opt_symbol, list| - @options[long_opt_symbol] = list.nil? ? [] : list.split(",") + @options[long_opt_symbol] = if list.nil? + [] + else + list.split(",").map.each do |l| + if l.start_with?("/") && l.end_with?("/") + Regexp.new(l[1...-1]) + else + l + end + end + end end set_option(opts, "--[no-]ignore-empty-alt") do |long_opt_symbol, arg| diff --git a/lib/html_proofer/runner.rb b/lib/html_proofer/runner.rb index 47e2510c..ba6719a8 100644 --- a/lib/html_proofer/runner.rb +++ b/lib/html_proofer/runner.rb @@ -166,8 +166,14 @@ def files def ignore_file?(file) @options[:ignore_files].each do |pattern| - return true if pattern.is_a?(String) && pattern == file - return true if pattern.is_a?(Regexp) && pattern =~ file + if pattern.is_a?(String) && pattern == file + @logger.log(:debug, "Ignoring #{file} because it matches #{pattern}") + return true + end + next unless pattern.is_a?(Regexp) && pattern.match(file) + + @logger.log(:debug, "Ignoring #{file} because it matches regexp #{pattern}") + return true end false diff --git a/spec/html-proofer/command_spec.rb b/spec/html-proofer/command_spec.rb index a490fa53..bc298c5e 100644 --- a/spec/html-proofer/command_spec.rb +++ b/spec/html-proofer/command_spec.rb @@ -134,12 +134,18 @@ expect(output).to(match("failure")) end - it "works with ignore-files" do + it "works with ignore-files (string)" do external = File.join(FIXTURES_DIR, "links", "broken_hash_internal.html") output = make_bin("--ignore-files #{external} #{external}") expect(output).to(match("successfully")) end + it "works with ignore-files (regexp)" do + external = File.join(FIXTURES_DIR, "links", "broken_hash_internal.html") + output = make_bin("--ignore-files /_hash_/ #{external}") + expect(output).to(match("successfully")) + end + it "works with ignore-missing-alt" do broken = File.join(FIXTURES_DIR, "images", "missing_image_alt.html") output = make_bin("--ignore-missing-alt #{broken}") diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 9007a14c..aa8a43ff 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -70,6 +70,7 @@ def capture_proofer_http(item, type, opts = {}) end def make_bin(args) + ap("#{RbConfig.ruby} exe/htmlproofer #{args}") if debug? stdout, stderr = Open3.capture3("#{RbConfig.ruby} exe/htmlproofer #{args}") "#{stdout}\n#{stderr}".encode("UTF-8", invalid: :replace, undef: :replace) end @@ -84,6 +85,10 @@ def make_cassette_name(file, opts) filename end +def debug? + ENV.fetch("DEBUG", false) +end + def ci? ENV.fetch("CI", false) end From e52aa43f7b9fd7a2150fb0ffaee12bc2325fd8e4 Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Tue, 1 Nov 2022 16:46:14 -0300 Subject: [PATCH 02/78] lint --- lib/html_proofer/configuration.rb | 2 +- spec/html-proofer/command_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/html_proofer/configuration.rb b/lib/html_proofer/configuration.rb index f5a4edfc..ce986322 100644 --- a/lib/html_proofer/configuration.rb +++ b/lib/html_proofer/configuration.rb @@ -295,7 +295,7 @@ module ConfigurationHelp check_internal_hash: ["Checks whether internal hashes exist (even if the webpage exists) (default: `true`)."], check_sri: ["Check that `` and ` + + http_version: '2' + adapter_metadata: + effective_url: https://www.linkedin.com/company/netapp + recorded_at: Thu, 02 Mar 2023 02:12:27 GMT +- request: + method: head + uri: https://www.netapp.com/company/contact-us/ + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; HTML Proofer/5.0.4; +https://github.com/gjtorikian/html-proofer) + Accept: + - application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Expect: + - '' + response: + status: + code: 200 + message: '' + headers: + content-type: + - text/html; charset=utf-8 + server: + - Microsoft-IIS/10.0 + access-control-allow-methods: + - GET + access-control-allow-origin: + - "*" + access-control-expose-headers: + - Request-Context + x-aspnetmvc-version: + - '5.2' + x-aspnet-version: + - 4.0.30319 + request-context: + - appId=cid-v1:149249a1-9c0c-40ae-89b4-ef4e47a1cbd8 + x-powered-by: + - ASP.NET + x-akam-sw-version: + - 0.5.0 + cache-control: + - private, max-age=900 + expires: + - Thu, 02 Mar 2023 02:27:27 GMT + date: + - Thu, 02 Mar 2023 02:12:27 GMT + alt-svc: + - h3=":443"; ma=93600 + strict-transport-security: + - max-age=63072000 + content-security-policy: + - 'default-src * ''unsafe-inline''; script-src * data: ''unsafe-inline'' ''unsafe-eval''; + style-src * ''unsafe-inline''; style-src-elem * ''unsafe-inline''; style-src-attr + * ''unsafe-inline''; img-src * data: blob:; font-src * data:; frame-src * + data:; frame-ancestors *; media-src * blob:; worker-src * blob:' + referrer-policy: + - strict-origin-when-cross-origin + x-xss-protection: + - 1; mode=block + x-content-type-options: + - nosniff + x-frame-options: + - SAMEORIGIN + server-timing: + - ak_p; desc="466034_388049348_2496399312_14050_3307_41_0";dur=1 + body: + encoding: ASCII-8BIT + string: '' + http_version: '2' + adapter_metadata: + effective_url: https://www.netapp.com/company/contact-us/ + recorded_at: Thu, 02 Mar 2023 02:12:27 GMT +- request: + method: head + uri: https://www.netapp.com/company/legal/terms-of-use/ + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; HTML Proofer/5.0.4; +https://github.com/gjtorikian/html-proofer) + Accept: + - application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Expect: + - '' + response: + status: + code: 200 + message: '' + headers: + content-type: + - text/html; charset=utf-8 + server: + - Microsoft-IIS/10.0 + access-control-allow-methods: + - GET + access-control-allow-origin: + - "*" + access-control-expose-headers: + - Request-Context + x-aspnetmvc-version: + - '5.2' + x-aspnet-version: + - 4.0.30319 + request-context: + - appId=cid-v1:149249a1-9c0c-40ae-89b4-ef4e47a1cbd8 + x-powered-by: + - ASP.NET + cache-control: + - private, max-age=900 + expires: + - Thu, 02 Mar 2023 02:27:27 GMT + date: + - Thu, 02 Mar 2023 02:12:27 GMT + alt-svc: + - h3=":443"; ma=93600 + x-akam-sw-version: + - 0.5.0 + strict-transport-security: + - max-age=63072000 + content-security-policy: + - 'default-src * ''unsafe-inline''; script-src * data: ''unsafe-inline'' ''unsafe-eval''; + style-src * ''unsafe-inline''; style-src-elem * ''unsafe-inline''; style-src-attr + * ''unsafe-inline''; img-src * data: blob:; font-src * data:; frame-src * + data:; frame-ancestors *; media-src * blob:; worker-src * blob:' + referrer-policy: + - strict-origin-when-cross-origin + x-xss-protection: + - 1; mode=block + x-content-type-options: + - nosniff + x-frame-options: + - SAMEORIGIN + server-timing: + - ak_p; desc="466034_388049348_2496399368_14453_3457_37_0";dur=1 + body: + encoding: ASCII-8BIT + string: '' + http_version: '2' + adapter_metadata: + effective_url: https://www.netapp.com/company/legal/terms-of-use/ + recorded_at: Thu, 02 Mar 2023 02:12:27 GMT +- request: + method: head + uri: https://github.com/NetAppDocs/storagegrid-116/issues/new?body=Page:%20%5BConfigure%20load%20balancer%20endpoints%5D(https://docs.netapp.com/us-en/storagegrid-116/admin/configuring-load-balancer-endpoints.html)&template=public-issue-template.md + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; HTML Proofer/5.0.4; +https://github.com/gjtorikian/html-proofer) + Accept: + - application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Expect: + - '' + response: + status: + code: 200 + message: '' + headers: + server: + - GitHub.com + date: + - Thu, 02 Mar 2023 02:12:27 GMT + content-type: + - text/html; charset=utf-8 + vary: + - X-PJAX, X-PJAX-Container, Turbo-Visit, Turbo-Frame + - Accept-Encoding, Accept, X-Requested-With + cache-control: + - no-store + etag: + - W/"79c03e0832d359650290b6194a0d9122" + set-cookie: + - _device_id=7032cce46a63a4060343771e8430734a; path=/; expires=Sat, 02 Mar 2024 + 02:12:27 GMT; secure; HttpOnly; SameSite=Lax + - _octo=GH1.1.707407677.1677723147; domain=github.com; path=/; expires=Sat, + 02 Mar 2024 02:12:27 GMT; secure; SameSite=Lax + - logged_in=no; domain=github.com; path=/; expires=Sat, 02 Mar 2024 02:12:27 + GMT; secure; HttpOnly; SameSite=Lax + - _gh_sess=eNEVDP3KAgEq6zepYzo239j0%2Frm3u96hVHINkMjfdbF%2Bka%2B3o9BEbJ4Kq10SBelJzP%2Fie4XDwqtlMCUus2bdXy89pdYbu6IJXUbCbya6M%2BeCHJCaH2iHYZr3pFR4G5677oF3WE9qxJstz40saOr%2F67tvSqS39SmKcNO8ZGNa7CCbRXWSaFjQ8FSxfC3JrY3Wo7x1%2F%2FGS8jiccBbUt%2BzDzL7FHzW1nceijEDKCY9qMP7L7YcZuXWy%2F20R9qPECeFj6tygZnU%3D--IIZJgazx7vdctBwA--1HNn5iTHZhzJOlMy2%2BHldA%3D%3D; + path=/; secure; HttpOnly; SameSite=Lax + strict-transport-security: + - max-age=31536000; includeSubdomains; preload + x-frame-options: + - deny + x-content-type-options: + - nosniff + x-xss-protection: + - '0' + referrer-policy: + - origin-when-cross-origin, strict-origin-when-cross-origin + content-security-policy: + - 'default-src ''none''; base-uri ''self''; block-all-mixed-content; child-src + github.com/assets-cdn/worker/ gist.github.com/assets-cdn/worker/; connect-src + ''self'' uploads.github.com objects-origin.githubusercontent.com www.githubstatus.com + collector.github.com raw.githubusercontent.com api.github.com github-cloud.s3.amazonaws.com + github-production-repository-file-5c1aeb.s3.amazonaws.com github-production-upload-manifest-file-7fdce7.s3.amazonaws.com + github-production-user-asset-6210df.s3.amazonaws.com cdn.optimizely.com logx.optimizely.com/v1/events + *.actions.githubusercontent.com productionresultssa0.blob.core.windows.net/ + productionresultssa1.blob.core.windows.net/ productionresultssa2.blob.core.windows.net/ + productionresultssa3.blob.core.windows.net/ productionresultssa4.blob.core.windows.net/ + wss://*.actions.githubusercontent.com online.visualstudio.com/api/v1/locations + github-production-repository-image-32fea6.s3.amazonaws.com github-production-release-asset-2e65be.s3.amazonaws.com + insights.github.com wss://alive.github.com; font-src github.githubassets.com; + form-action ''self'' github.com gist.github.com objects-origin.githubusercontent.com; + frame-ancestors ''none''; frame-src viewscreen.githubusercontent.com notebooks.githubusercontent.com; + img-src ''self'' data: github.githubassets.com media.githubusercontent.com + camo.githubusercontent.com identicons.github.com avatars.githubusercontent.com + github-cloud.s3.amazonaws.com objects.githubusercontent.com objects-origin.githubusercontent.com + secured-user-images.githubusercontent.com/ private-user-images.githubusercontent.com + opengraph.githubassets.com github-production-user-asset-6210df.s3.amazonaws.com + customer-stories-feed.github.com spotlights-feed.github.com *.githubusercontent.com; + manifest-src ''self''; media-src github.com user-images.githubusercontent.com/ + secured-user-images.githubusercontent.com/ private-user-images.githubusercontent.com; + script-src github.githubassets.com; style-src ''unsafe-inline'' github.githubassets.com; + worker-src github.com/assets-cdn/worker/ gist.github.com/assets-cdn/worker/' + x-github-request-id: + - FD23:5EEF:AF9108E:104E2845:6400060B + body: + encoding: ASCII-8BIT + string: '' + http_version: '2' + adapter_metadata: + effective_url: https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2FNetAppDocs%2Fstoragegrid-116%2Fissues%2Fnew%3Fbody%3DPage%3A%2520%255BConfigure%2520load%2520balancer%2520endpoints%255D%28https%3A%2F%2Fdocs.netapp.com%2Fus-en%2Fstoragegrid-116%2Fadmin%2Fconfiguring-load-balancer-endpoints.html%29%26template%3Dpublic-issue-template.md + recorded_at: Thu, 02 Mar 2023 02:12:27 GMT +- request: + method: head + uri: https://blog.netapp.com/ + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; HTML Proofer/5.0.4; +https://github.com/gjtorikian/html-proofer) + Accept: + - application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Expect: + - '' + response: + status: + code: 200 + message: '' + headers: + content-type: + - text/html; charset=utf-8 + server: + - Microsoft-IIS/10.0 + access-control-allow-methods: + - GET + access-control-allow-origin: + - "*" + access-control-expose-headers: + - Request-Context + x-aspnetmvc-version: + - '5.2' + x-aspnet-version: + - 4.0.30319 + request-context: + - appId=cid-v1:149249a1-9c0c-40ae-89b4-ef4e47a1cbd8 + x-powered-by: + - ASP.NET + mpulse_origin_time: + - '1509' + mpulse_cdn_cache: + - MISS + x-akam-sw-version: + - 0.5.0 + cache-control: + - private, max-age=900 + expires: + - Thu, 02 Mar 2023 02:27:27 GMT + date: + - Thu, 02 Mar 2023 02:12:27 GMT + alt-svc: + - h3=":443"; ma=93600 + strict-transport-security: + - max-age=63072000 + content-security-policy: + - 'default-src * ''unsafe-inline''; script-src * data: ''unsafe-inline'' ''unsafe-eval''; + style-src * ''unsafe-inline''; style-src-elem * ''unsafe-inline''; style-src-attr + * ''unsafe-inline''; img-src * data: blob:; font-src * data:; frame-src * + data:; frame-ancestors *; media-src * blob:; worker-src * blob:' + referrer-policy: + - strict-origin-when-cross-origin + x-xss-protection: + - 1; mode=block + x-content-type-options: + - nosniff + x-frame-options: + - SAMEORIGIN + server-timing: + - ak_p; desc="466034_388049348_2496399795_8492_3362_39_0";dur=1 + body: + encoding: ASCII-8BIT + string: '' + http_version: '2' + adapter_metadata: + effective_url: https://www.netapp.com/blog/ + recorded_at: Thu, 02 Mar 2023 02:12:27 GMT +- request: + method: head + uri: https://docs.netapp.com/us-en/contribute/ + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; HTML Proofer/5.0.4; +https://github.com/gjtorikian/html-proofer) + Accept: + - application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Expect: + - '' + response: + status: + code: 200 + message: OK + headers: + Content-Type: + - text/html; charset=utf-8 + Connection: + - keep-alive + Date: + - Thu, 02 Mar 2023 02:12:27 GMT + Server: + - GitHub.com + Access-Control-Allow-Origin: + - "*" + expires: + - Wed, 01 Mar 2023 20:17:10 GMT + Cache-Control: + - max-age=600 + x-proxy-cache: + - MISS + X-GitHub-Request-Id: + - 89C4:2C1A:EFE4D7:11528A1:63FFB06E + Accept-Ranges: + - bytes + Via: + - 1.1 varnish + Age: + - '0' + X-Served-By: + - cache-pdx12328-PDX + X-Cache: + - HIT + X-Cache-Hits: + - '1' + X-Timer: + - S1677723148.579237,VS0,VE76 + Vary: + - Accept-Encoding + X-Fastly-Request-ID: + - 3a9500fea3b8c894f0915b24346080b4e3c68fe4 + body: + encoding: ASCII-8BIT + string: '' + http_version: '1.1' + adapter_metadata: + effective_url: https://docs.netapp.com/us-en/contribute/ + recorded_at: Thu, 02 Mar 2023 02:12:27 GMT +- request: + method: head + uri: https://docs.netapp.com/ja-jp/storagegrid-116/admin/configuring-load-balancer-endpoints.html + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; HTML Proofer/5.0.4; +https://github.com/gjtorikian/html-proofer) + Accept: + - application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Expect: + - '' + response: + status: + code: 200 + message: OK + headers: + Content-Type: + - text/html; charset=utf-8 + Connection: + - keep-alive + Date: + - Thu, 02 Mar 2023 02:12:27 GMT + Server: + - GitHub.com + Access-Control-Allow-Origin: + - "*" + expires: + - Thu, 02 Mar 2023 02:22:27 GMT + Cache-Control: + - max-age=600 + x-proxy-cache: + - MISS + X-GitHub-Request-Id: + - 1D6A:60E7:C38386:E0574F:6400060B + Accept-Ranges: + - bytes + Via: + - 1.1 varnish + Age: + - '0' + X-Served-By: + - cache-pdx12327-PDX + X-Cache: + - MISS + X-Cache-Hits: + - '0' + X-Timer: + - S1677723148.577021,VS0,VE99 + Vary: + - Accept-Encoding + X-Fastly-Request-ID: + - c851761c699d74b2f157d746986464cb6e2f95fe + body: + encoding: ASCII-8BIT + string: '' + http_version: '1.1' + adapter_metadata: + effective_url: https://docs.netapp.com/ja-jp/storagegrid-116/admin/configuring-load-balancer-endpoints.html + recorded_at: Thu, 02 Mar 2023 02:12:27 GMT +- request: + method: head + uri: https://docs.netapp.com/ko-kr/storagegrid-116/admin/configuring-load-balancer-endpoints.html + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; HTML Proofer/5.0.4; +https://github.com/gjtorikian/html-proofer) + Accept: + - application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Expect: + - '' + response: + status: + code: 200 + message: OK + headers: + Content-Type: + - text/html; charset=utf-8 + Connection: + - keep-alive + Date: + - Thu, 02 Mar 2023 02:12:27 GMT + Server: + - GitHub.com + Access-Control-Allow-Origin: + - "*" + expires: + - Thu, 02 Mar 2023 02:22:27 GMT + Cache-Control: + - max-age=600 + x-proxy-cache: + - MISS + X-GitHub-Request-Id: + - 0B62:5B5D:43A385:4CE5B4:6400060B + Accept-Ranges: + - bytes + Via: + - 1.1 varnish + Age: + - '0' + X-Served-By: + - cache-pdx12320-PDX + X-Cache: + - MISS + X-Cache-Hits: + - '0' + X-Timer: + - S1677723148.576720,VS0,VE98 + Vary: + - Accept-Encoding + X-Fastly-Request-ID: + - 1c7dab971bde6986ff2a098ab38e7ba20afacf2a + body: + encoding: ASCII-8BIT + string: '' + http_version: '1.1' + adapter_metadata: + effective_url: https://docs.netapp.com/ko-kr/storagegrid-116/admin/configuring-load-balancer-endpoints.html + recorded_at: Thu, 02 Mar 2023 02:12:27 GMT +- request: + method: head + uri: https://docs.netapp.com/zh-cn/storagegrid-116/admin/configuring-load-balancer-endpoints.html + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; HTML Proofer/5.0.4; +https://github.com/gjtorikian/html-proofer) + Accept: + - application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Expect: + - '' + response: + status: + code: 200 + message: OK + headers: + Content-Type: + - text/html; charset=utf-8 + Connection: + - keep-alive + Date: + - Thu, 02 Mar 2023 02:12:27 GMT + Server: + - GitHub.com + Access-Control-Allow-Origin: + - "*" + expires: + - Thu, 02 Mar 2023 02:22:27 GMT + Cache-Control: + - max-age=600 + x-proxy-cache: + - MISS + X-GitHub-Request-Id: + - 322A:60E7:C38386:E05751:6400060B + Accept-Ranges: + - bytes + Via: + - 1.1 varnish + Age: + - '0' + X-Served-By: + - cache-pdx12320-PDX + X-Cache: + - MISS + X-Cache-Hits: + - '0' + X-Timer: + - S1677723148.577784,VS0,VE80 + Vary: + - Accept-Encoding + X-Fastly-Request-ID: + - a573e8d553ac758fa654b44c28793333a17af022 + body: + encoding: ASCII-8BIT + string: '' + http_version: '1.1' + adapter_metadata: + effective_url: https://docs.netapp.com/zh-cn/storagegrid-116/admin/configuring-load-balancer-endpoints.html + recorded_at: Thu, 02 Mar 2023 02:12:27 GMT +- request: + method: head + uri: https://docs.netapp.com/zh-tw/storagegrid-116/admin/configuring-load-balancer-endpoints.html + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; HTML Proofer/5.0.4; +https://github.com/gjtorikian/html-proofer) + Accept: + - application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Expect: + - '' + response: + status: + code: 200 + message: OK + headers: + Content-Type: + - text/html; charset=utf-8 + Connection: + - keep-alive + Date: + - Thu, 02 Mar 2023 02:12:27 GMT + Server: + - GitHub.com + Access-Control-Allow-Origin: + - "*" + expires: + - Thu, 02 Mar 2023 02:22:27 GMT + Cache-Control: + - max-age=600 + x-proxy-cache: + - MISS + X-GitHub-Request-Id: + - DBF0:923D:9413F8:A87A53:6400060B + Accept-Ranges: + - bytes + Via: + - 1.1 varnish + Age: + - '0' + X-Served-By: + - cache-pdx12320-PDX + X-Cache: + - MISS + X-Cache-Hits: + - '0' + X-Timer: + - S1677723148.577160,VS0,VE91 + Vary: + - Accept-Encoding + X-Fastly-Request-ID: + - 84cba67f641b8345ca0329eb04273d19ea4ccf3c + body: + encoding: ASCII-8BIT + string: '' + http_version: '1.1' + adapter_metadata: + effective_url: https://docs.netapp.com/zh-tw/storagegrid-116/admin/configuring-load-balancer-endpoints.html + recorded_at: Thu, 02 Mar 2023 02:12:27 GMT +- request: + method: head + uri: https://docs.netapp.com/de-de/storagegrid-116/admin/configuring-load-balancer-endpoints.html + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; HTML Proofer/5.0.4; +https://github.com/gjtorikian/html-proofer) + Accept: + - application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Expect: + - '' + response: + status: + code: 200 + message: OK + headers: + Content-Type: + - text/html; charset=utf-8 + Connection: + - keep-alive + Date: + - Thu, 02 Mar 2023 02:12:27 GMT + Server: + - GitHub.com + Access-Control-Allow-Origin: + - "*" + expires: + - Thu, 02 Mar 2023 02:22:27 GMT + Cache-Control: + - max-age=600 + x-proxy-cache: + - MISS + X-GitHub-Request-Id: + - D1B6:2CDE:E097E7:101AB02:6400060B + Accept-Ranges: + - bytes + Via: + - 1.1 varnish + Age: + - '0' + X-Served-By: + - cache-pdx12327-PDX + X-Cache: + - MISS + X-Cache-Hits: + - '0' + X-Timer: + - S1677723148.586790,VS0,VE130 + Vary: + - Accept-Encoding + X-Fastly-Request-ID: + - dc795988830dd4ad4b3f47e700c7ebca8db3da67 + body: + encoding: ASCII-8BIT + string: '' + http_version: '1.1' + adapter_metadata: + effective_url: https://docs.netapp.com/de-de/storagegrid-116/admin/configuring-load-balancer-endpoints.html + recorded_at: Thu, 02 Mar 2023 02:12:27 GMT +- request: + method: head + uri: https://docs.netapp.com/es-es/storagegrid-116/admin/configuring-load-balancer-endpoints.html + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; HTML Proofer/5.0.4; +https://github.com/gjtorikian/html-proofer) + Accept: + - application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Expect: + - '' + response: + status: + code: 200 + message: OK + headers: + Content-Type: + - text/html; charset=utf-8 + Connection: + - keep-alive + Date: + - Thu, 02 Mar 2023 02:12:27 GMT + Server: + - GitHub.com + Access-Control-Allow-Origin: + - "*" + expires: + - Thu, 02 Mar 2023 02:22:27 GMT + Cache-Control: + - max-age=600 + x-proxy-cache: + - MISS + X-GitHub-Request-Id: + - DD58:9E1C:39058D:40BCD9:6400060B + Accept-Ranges: + - bytes + Via: + - 1.1 varnish + Age: + - '0' + X-Served-By: + - cache-pdx12330-PDX + X-Cache: + - MISS + X-Cache-Hits: + - '0' + X-Timer: + - S1677723148.578103,VS0,VE100 + Vary: + - Accept-Encoding + X-Fastly-Request-ID: + - 649547bf65e01de1729d68da60a1b0959ac94035 + body: + encoding: ASCII-8BIT + string: '' + http_version: '1.1' + adapter_metadata: + effective_url: https://docs.netapp.com/es-es/storagegrid-116/admin/configuring-load-balancer-endpoints.html + recorded_at: Thu, 02 Mar 2023 02:12:27 GMT +- request: + method: head + uri: https://docs.netapp.com/fr-fr/storagegrid-116/admin/configuring-load-balancer-endpoints.html + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; HTML Proofer/5.0.4; +https://github.com/gjtorikian/html-proofer) + Accept: + - application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Expect: + - '' + response: + status: + code: 200 + message: OK + headers: + Content-Type: + - text/html; charset=utf-8 + Connection: + - keep-alive + Date: + - Thu, 02 Mar 2023 02:12:27 GMT + Server: + - GitHub.com + Access-Control-Allow-Origin: + - "*" + expires: + - Thu, 02 Mar 2023 02:22:27 GMT + Cache-Control: + - max-age=600 + x-proxy-cache: + - MISS + X-GitHub-Request-Id: + - EEA2:6BC6:251F36:2A4BA4:6400060B + Accept-Ranges: + - bytes + Via: + - 1.1 varnish + Age: + - '0' + X-Served-By: + - cache-pdx12328-PDX + X-Cache: + - MISS + X-Cache-Hits: + - '0' + X-Timer: + - S1677723148.578423,VS0,VE99 + Vary: + - Accept-Encoding + X-Fastly-Request-ID: + - 4415c0e4127f64d199390982c501448cac5a5bdd + body: + encoding: ASCII-8BIT + string: '' + http_version: '1.1' + adapter_metadata: + effective_url: https://docs.netapp.com/fr-fr/storagegrid-116/admin/configuring-load-balancer-endpoints.html + recorded_at: Thu, 02 Mar 2023 02:12:27 GMT +- request: + method: head + uri: https://docs.netapp.com + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; HTML Proofer/5.0.4; +https://github.com/gjtorikian/html-proofer) + Accept: + - application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Expect: + - '' + response: + status: + code: 200 + message: '' + headers: + content-type: + - text/html; charset=utf-8 + server: + - Microsoft-IIS/10.0 + access-control-allow-methods: + - GET + access-control-allow-origin: + - "*" + access-control-expose-headers: + - Request-Context + x-aspnetmvc-version: + - '5.2' + x-aspnet-version: + - 4.0.30319 + request-context: + - appId=cid-v1:dcd7466e-24d2-4a35-b887-18422e1be81d + x-powered-by: + - ASP.NET + cache-control: + - private, max-age=900 + expires: + - Thu, 02 Mar 2023 02:27:27 GMT + date: + - Thu, 02 Mar 2023 02:12:27 GMT + alt-svc: + - h3=":443"; ma=93600 + x-akam-sw-version: + - 0.5.0 + strict-transport-security: + - max-age=63072000 + content-security-policy: + - 'default-src * ''unsafe-inline''; script-src * data: ''unsafe-inline'' ''unsafe-eval''; + style-src * ''unsafe-inline''; style-src-elem * ''unsafe-inline''; style-src-attr + * ''unsafe-inline''; img-src * data: blob:; font-src * data:; frame-src * + data:; frame-ancestors *; media-src * blob:; worker-src * blob:' + referrer-policy: + - strict-origin-when-cross-origin + x-xss-protection: + - 1; mode=block + x-content-type-options: + - nosniff + x-frame-options: + - SAMEORIGIN + server-timing: + - ak_p; desc="466034_388049348_2496400532_2412_3537_38_0";dur=1 + body: + encoding: ASCII-8BIT + string: '' + http_version: '2' + adapter_metadata: + effective_url: https://www.netapp.com/support-and-training/documentation/ + recorded_at: Thu, 02 Mar 2023 02:12:27 GMT +- request: + method: head + uri: https://www.facebook.com/NetApp + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; HTML Proofer/5.0.4; +https://github.com/gjtorikian/html-proofer) + Accept: + - application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Expect: + - '' + response: + status: + code: 200 + message: '' + headers: + vary: + - Accept-Encoding + accept-ch-lifetime: + - '4838400' + accept-ch: + - sec-ch-prefers-color-scheme + report-to: + - '{"max_age":86400,"endpoints":[{"url":"https:\/\/www.facebook.com\/browser_reporting\/?minimize=0"}],"group":"coep_report"}, + {"max_age":259200,"endpoints":[{"url":"https:\/\/www.facebook.com\/ajax\/comet_error_reports\/?device_level=unknown"}]}' + x-fb-rlafr: + - '0' + document-policy: + - force-load-at-top + cross-origin-embedder-policy-report-only: + - require-corp;report-to="coep_report" + cross-origin-opener-policy: + - same-origin-allow-popups + pragma: + - no-cache + cache-control: + - private, no-cache, no-store, must-revalidate + expires: + - Sat, 01 Jan 2000 00:00:00 GMT + x-content-type-options: + - nosniff + x-xss-protection: + - '0' + x-frame-options: + - DENY + strict-transport-security: + - max-age=15552000; preload + content-type: + - text/html; charset="utf-8" + x-fb-debug: + - WRhBBXr1CmQZfH+QRaWQoyQGqbWsOWMqG70uUE22bhRBltF2kq/J1skMfePXgTQcavJkn0NHY4LO6d01ZUkVtQ== + date: + - Thu, 02 Mar 2023 02:12:27 GMT + priority: + - u=3,i + alt-svc: + - h3=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: '' + http_version: '2' + adapter_metadata: + effective_url: https://www.facebook.com/NetApp + recorded_at: Thu, 02 Mar 2023 02:12:27 GMT +- request: + method: head + uri: https://www.youtube.com/user/NetAppTV + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; HTML Proofer/5.0.4; +https://github.com/gjtorikian/html-proofer) + Accept: + - application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Expect: + - '' + response: + status: + code: 200 + message: '' + headers: + content-type: + - text/html; charset=utf-8 + x-content-type-options: + - nosniff + cache-control: + - no-cache, no-store, max-age=0, must-revalidate + pragma: + - no-cache + expires: + - Mon, 01 Jan 1990 00:00:00 GMT + date: + - Thu, 02 Mar 2023 02:12:27 GMT + content-length: + - '961224' + strict-transport-security: + - max-age=31536000 + x-frame-options: + - SAMEORIGIN + report-to: + - '{"group":"youtube_main","max_age":2592000,"endpoints":[{"url":"https://csp.withgoogle.com/csp/report-to/youtube_main"}]}' + permissions-policy: + - ch-ua-arch=*, ch-ua-bitness=*, ch-ua-full-version=*, ch-ua-full-version-list=*, + ch-ua-model=*, ch-ua-wow64=*, ch-ua-platform=*, ch-ua-platform-version=* + cross-origin-opener-policy-report-only: + - same-origin-allow-popups; report-to="youtube_main" + p3p: + - CP="This is not a P3P policy! See http://support.google.com/accounts/answer/151657?hl=en + for more info." + server: + - ESF + x-xss-protection: + - '0' + set-cookie: + - GPS=1; Domain=.youtube.com; Expires=Thu, 02-Mar-2023 02:42:27 GMT; Path=/; + Secure; HttpOnly + - YSC=_UjrMpMt1K0; Domain=.youtube.com; Path=/; Secure; HttpOnly; SameSite=none + - VISITOR_INFO1_LIVE=C6VwWccVJRU; Domain=.youtube.com; Expires=Tue, 29-Aug-2023 + 02:12:27 GMT; Path=/; Secure; HttpOnly; SameSite=none + alt-svc: + - h3=":443"; ma=2592000,h3-29=":443"; ma=2592000 + body: + encoding: ASCII-8BIT + string: '' + http_version: '2' + adapter_metadata: + effective_url: https://www.youtube.com/user/NetAppTV + recorded_at: Thu, 02 Mar 2023 02:12:27 GMT +- request: + method: head + uri: https://docs.netapp.com/us-en/storagegrid-115/admin/configuring-load-balancer-endpoints.html + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; HTML Proofer/5.0.4; +https://github.com/gjtorikian/html-proofer) + Accept: + - application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Expect: + - '' + response: + status: + code: 200 + message: OK + headers: + Content-Type: + - text/html; charset=utf-8 + Connection: + - keep-alive + Date: + - Thu, 02 Mar 2023 02:12:27 GMT + Server: + - GitHub.com + Access-Control-Allow-Origin: + - "*" + expires: + - Thu, 02 Mar 2023 02:22:27 GMT + Cache-Control: + - max-age=600 + x-proxy-cache: + - MISS + X-GitHub-Request-Id: + - EEA8:2FCA:438171:4CAD89:6400060B + Accept-Ranges: + - bytes + Via: + - 1.1 varnish + Age: + - '0' + X-Served-By: + - cache-pdx12322-PDX + X-Cache: + - MISS + X-Cache-Hits: + - '0' + X-Timer: + - S1677723148.578159,VS0,VE100 + Vary: + - Accept-Encoding + X-Fastly-Request-ID: + - f85f757977fc46f5506fbf48e4237d98c240ad0e + body: + encoding: ASCII-8BIT + string: '' + http_version: '1.1' + adapter_metadata: + effective_url: https://docs.netapp.com/us-en/storagegrid-115/admin/configuring-load-balancer-endpoints.html + recorded_at: Thu, 02 Mar 2023 02:12:27 GMT +- request: + method: head + uri: https://www.netapp.com/support-and-training/netapp-university/ + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; HTML Proofer/5.0.4; +https://github.com/gjtorikian/html-proofer) + Accept: + - application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Expect: + - '' + response: + status: + code: 200 + message: '' + headers: + content-type: + - text/html; charset=utf-8 + server: + - Microsoft-IIS/10.0 + access-control-allow-methods: + - GET + access-control-allow-origin: + - "*" + access-control-expose-headers: + - Request-Context + x-aspnetmvc-version: + - '5.2' + x-aspnet-version: + - 4.0.30319 + request-context: + - appId=cid-v1:323f08db-f4f8-4d28-a241-224e200b593e + x-powered-by: + - ASP.NET + cache-control: + - private, max-age=900 + expires: + - Thu, 02 Mar 2023 02:27:27 GMT + date: + - Thu, 02 Mar 2023 02:12:27 GMT + alt-svc: + - h3=":443"; ma=93600 + x-akam-sw-version: + - 0.5.0 + strict-transport-security: + - max-age=63072000 + content-security-policy: + - 'default-src * ''unsafe-inline''; script-src * data: ''unsafe-inline'' ''unsafe-eval''; + style-src * ''unsafe-inline''; style-src-elem * ''unsafe-inline''; style-src-attr + * ''unsafe-inline''; img-src * data: blob:; font-src * data:; frame-src * + data:; frame-ancestors *; media-src * blob:; worker-src * blob:' + referrer-policy: + - strict-origin-when-cross-origin + x-xss-protection: + - 1; mode=block + x-content-type-options: + - nosniff + x-frame-options: + - SAMEORIGIN + server-timing: + - ak_p; desc="466034_388049348_2496400529_2630_4204_38_0";dur=1 + body: + encoding: ASCII-8BIT + string: '' + http_version: '2' + adapter_metadata: + effective_url: https://www.netapp.com/support-and-training/netapp-learning-services/ + recorded_at: Thu, 02 Mar 2023 02:12:27 GMT +- request: + method: head + uri: https://github.com/netapp-madkat + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; HTML Proofer/5.0.4; +https://github.com/gjtorikian/html-proofer) + Accept: + - application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Expect: + - '' + response: + status: + code: 200 + message: '' + headers: + server: + - GitHub.com + date: + - Thu, 02 Mar 2023 02:12:27 GMT + content-type: + - text/html; charset=utf-8 + vary: + - X-Requested-With, X-PJAX-Container, Turbo-Frame, Turbo-Visit, Accept-Encoding, + Accept, X-Requested-With + etag: + - W/"60676f6b10b27ff39e7d3627bc88ffe9" + cache-control: + - max-age=0, private, must-revalidate + strict-transport-security: + - max-age=31536000; includeSubdomains; preload + x-frame-options: + - deny + x-content-type-options: + - nosniff + x-xss-protection: + - '0' + referrer-policy: + - origin-when-cross-origin, strict-origin-when-cross-origin + content-security-policy: + - 'default-src ''none''; base-uri ''self''; block-all-mixed-content; child-src + github.com/assets-cdn/worker/ gist.github.com/assets-cdn/worker/; connect-src + ''self'' uploads.github.com objects-origin.githubusercontent.com www.githubstatus.com + collector.github.com raw.githubusercontent.com api.github.com github-cloud.s3.amazonaws.com + github-production-repository-file-5c1aeb.s3.amazonaws.com github-production-upload-manifest-file-7fdce7.s3.amazonaws.com + github-production-user-asset-6210df.s3.amazonaws.com cdn.optimizely.com logx.optimizely.com/v1/events + *.actions.githubusercontent.com productionresultssa0.blob.core.windows.net/ + productionresultssa1.blob.core.windows.net/ productionresultssa2.blob.core.windows.net/ + productionresultssa3.blob.core.windows.net/ productionresultssa4.blob.core.windows.net/ + wss://*.actions.githubusercontent.com online.visualstudio.com/api/v1/locations + github-production-repository-image-32fea6.s3.amazonaws.com github-production-release-asset-2e65be.s3.amazonaws.com + insights.github.com wss://alive.github.com; font-src github.githubassets.com; + form-action ''self'' github.com gist.github.com objects-origin.githubusercontent.com; + frame-ancestors ''none''; frame-src viewscreen.githubusercontent.com notebooks.githubusercontent.com; + img-src ''self'' data: github.githubassets.com media.githubusercontent.com + camo.githubusercontent.com identicons.github.com avatars.githubusercontent.com + github-cloud.s3.amazonaws.com objects.githubusercontent.com objects-origin.githubusercontent.com + secured-user-images.githubusercontent.com/ private-user-images.githubusercontent.com + opengraph.githubassets.com github-production-user-asset-6210df.s3.amazonaws.com + customer-stories-feed.github.com spotlights-feed.github.com *.githubusercontent.com; + manifest-src ''self''; media-src github.com user-images.githubusercontent.com/ + secured-user-images.githubusercontent.com/ private-user-images.githubusercontent.com; + script-src github.githubassets.com; style-src ''unsafe-inline'' github.githubassets.com; + worker-src github.com/assets-cdn/worker/ gist.github.com/assets-cdn/worker/' + set-cookie: + - _gh_sess=DalVv2qIaqUXBCG6YhvQqckAcSyxgCdqwgqblDpOK8ef1IeaipomqM736%2B2J8TcO4yZlRWRx%2FLBp84L6aaarNYXzgh88O3oc4X7OU8m16GzPYG8CeR%2BhMbObZGhP%2FCsZxwXNBiAic0kCsUnIHnO66atJe1oozb7GOQqYkea96vez8yR%2Frm9fBulJnJRVVg8YRw2LQZ9el33l%2B7rQP2LbbChLUUI82nk2PJw%2Bb3IdKGRHCCmbWxAroEWBqg53rXntikcTOtNHuTCuYrPAdHt5oA%3D%3D--FntlCTiF0wYDgBqX--9gyIw5iiYLuPoiiRaEP5AQ%3D%3D; + Path=/; HttpOnly; Secure; SameSite=Lax + - _octo=GH1.1.215560807.1677723147; Path=/; Domain=github.com; Expires=Sat, + 02 Mar 2024 02:12:27 GMT; Secure; SameSite=Lax + - logged_in=no; Path=/; Domain=github.com; Expires=Sat, 02 Mar 2024 02:12:27 + GMT; HttpOnly; Secure; SameSite=Lax + accept-ranges: + - bytes + x-github-request-id: + - FD25:8F41:AC206AE:1005FA9C:6400060B + body: + encoding: ASCII-8BIT + string: '' + http_version: '2' + adapter_metadata: + effective_url: https://github.com/netapp-madkat + recorded_at: Thu, 02 Mar 2023 02:12:27 GMT +- request: + method: head + uri: https://github.com/netapp-perveilerk + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; HTML Proofer/5.0.4; +https://github.com/gjtorikian/html-proofer) + Accept: + - application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Expect: + - '' + response: + status: + code: 200 + message: '' + headers: + server: + - GitHub.com + date: + - Thu, 02 Mar 2023 02:12:27 GMT + content-type: + - text/html; charset=utf-8 + vary: + - X-Requested-With, X-PJAX-Container, Turbo-Frame, Turbo-Visit, Accept-Encoding, + Accept, X-Requested-With + etag: + - W/"e0cac19bd8072d2941a3d253fc97b06d" + cache-control: + - max-age=0, private, must-revalidate + strict-transport-security: + - max-age=31536000; includeSubdomains; preload + x-frame-options: + - deny + x-content-type-options: + - nosniff + x-xss-protection: + - '0' + referrer-policy: + - origin-when-cross-origin, strict-origin-when-cross-origin + content-security-policy: + - 'default-src ''none''; base-uri ''self''; block-all-mixed-content; child-src + github.com/assets-cdn/worker/ gist.github.com/assets-cdn/worker/; connect-src + ''self'' uploads.github.com objects-origin.githubusercontent.com www.githubstatus.com + collector.github.com raw.githubusercontent.com api.github.com github-cloud.s3.amazonaws.com + github-production-repository-file-5c1aeb.s3.amazonaws.com github-production-upload-manifest-file-7fdce7.s3.amazonaws.com + github-production-user-asset-6210df.s3.amazonaws.com cdn.optimizely.com logx.optimizely.com/v1/events + *.actions.githubusercontent.com productionresultssa0.blob.core.windows.net/ + productionresultssa1.blob.core.windows.net/ productionresultssa2.blob.core.windows.net/ + productionresultssa3.blob.core.windows.net/ productionresultssa4.blob.core.windows.net/ + wss://*.actions.githubusercontent.com online.visualstudio.com/api/v1/locations + github-production-repository-image-32fea6.s3.amazonaws.com github-production-release-asset-2e65be.s3.amazonaws.com + insights.github.com wss://alive.github.com; font-src github.githubassets.com; + form-action ''self'' github.com gist.github.com objects-origin.githubusercontent.com; + frame-ancestors ''none''; frame-src viewscreen.githubusercontent.com notebooks.githubusercontent.com; + img-src ''self'' data: github.githubassets.com media.githubusercontent.com + camo.githubusercontent.com identicons.github.com avatars.githubusercontent.com + github-cloud.s3.amazonaws.com objects.githubusercontent.com objects-origin.githubusercontent.com + secured-user-images.githubusercontent.com/ private-user-images.githubusercontent.com + opengraph.githubassets.com github-production-user-asset-6210df.s3.amazonaws.com + customer-stories-feed.github.com spotlights-feed.github.com *.githubusercontent.com; + manifest-src ''self''; media-src github.com user-images.githubusercontent.com/ + secured-user-images.githubusercontent.com/ private-user-images.githubusercontent.com; + script-src github.githubassets.com; style-src ''unsafe-inline'' github.githubassets.com; + worker-src github.com/assets-cdn/worker/ gist.github.com/assets-cdn/worker/' + set-cookie: + - _gh_sess=2KChkOSiVFve5uD3S8%2FHqAnYhdcZh2%2FG%2BEXCNIwIXiZDmhke1WICp%2F3%2F8Ca2bXRr51LNz5%2BDS%2BzruAGaaoNuuFbRYuM%2BBdUwHwBVSvcN7hrVEuzQ%2FWmrAoc4kiYUDkTIzgaM3S%2FAUdntfSzoOXcRfEr2mrsSEBEhYewhQR%2BiGApHlM8WhoD2Q2qXJaCyjxKe5hY%2B8rIlZyJH96YzuREOfJSud7HrFLXTe2mDcEfivbq1HItbHf%2BBl%2BiP3EbVBW8w%2FK%2FNXqBA9mMY1fiZoKx7VQ%3D%3D--H1QKlmpL7hq7Mauf--v3cz0KkbeXEgtt16XAxDLw%3D%3D; + Path=/; HttpOnly; Secure; SameSite=Lax + - _octo=GH1.1.825622907.1677723147; Path=/; Domain=github.com; Expires=Sat, + 02 Mar 2024 02:12:27 GMT; Secure; SameSite=Lax + - logged_in=no; Path=/; Domain=github.com; Expires=Sat, 02 Mar 2024 02:12:27 + GMT; HttpOnly; Secure; SameSite=Lax + accept-ranges: + - bytes + x-github-request-id: + - FD26:5AB9:AFF1337:105127FF:6400060B + body: + encoding: ASCII-8BIT + string: '' + http_version: '2' + adapter_metadata: + effective_url: https://github.com/netapp-perveilerk + recorded_at: Thu, 02 Mar 2023 02:12:27 GMT +- request: + method: head + uri: https://github.com/NetAppDocs/storagegrid-116/blob/main/admin/configuring-load-balancer-endpoints.adoc + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; HTML Proofer/5.0.4; +https://github.com/gjtorikian/html-proofer) + Accept: + - application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Expect: + - '' + response: + status: + code: 200 + message: '' + headers: + server: + - GitHub.com + date: + - Thu, 02 Mar 2023 02:12:27 GMT + content-type: + - text/html; charset=utf-8 + vary: + - X-PJAX, X-PJAX-Container, Turbo-Visit, Turbo-Frame, Accept-Encoding, Accept, + X-Requested-With + etag: + - W/"ba096f8c3c04826245cc167afeb3b7d6" + cache-control: + - max-age=0, private, must-revalidate + strict-transport-security: + - max-age=31536000; includeSubdomains; preload + x-frame-options: + - deny + x-content-type-options: + - nosniff + x-xss-protection: + - '0' + referrer-policy: + - no-referrer-when-downgrade + content-security-policy: + - 'default-src ''none''; base-uri ''self''; block-all-mixed-content; child-src + github.com/assets-cdn/worker/ gist.github.com/assets-cdn/worker/; connect-src + ''self'' uploads.github.com objects-origin.githubusercontent.com www.githubstatus.com + collector.github.com raw.githubusercontent.com api.github.com github-cloud.s3.amazonaws.com + github-production-repository-file-5c1aeb.s3.amazonaws.com github-production-upload-manifest-file-7fdce7.s3.amazonaws.com + github-production-user-asset-6210df.s3.amazonaws.com cdn.optimizely.com logx.optimizely.com/v1/events + *.actions.githubusercontent.com productionresultssa0.blob.core.windows.net/ + productionresultssa1.blob.core.windows.net/ productionresultssa2.blob.core.windows.net/ + productionresultssa3.blob.core.windows.net/ productionresultssa4.blob.core.windows.net/ + wss://*.actions.githubusercontent.com online.visualstudio.com/api/v1/locations + github-production-repository-image-32fea6.s3.amazonaws.com github-production-release-asset-2e65be.s3.amazonaws.com + insights.github.com wss://alive.github.com; font-src github.githubassets.com; + form-action ''self'' github.com gist.github.com objects-origin.githubusercontent.com; + frame-ancestors ''none''; frame-src viewscreen.githubusercontent.com notebooks.githubusercontent.com; + img-src ''self'' data: github.githubassets.com media.githubusercontent.com + camo.githubusercontent.com identicons.github.com avatars.githubusercontent.com + github-cloud.s3.amazonaws.com objects.githubusercontent.com objects-origin.githubusercontent.com + secured-user-images.githubusercontent.com/ private-user-images.githubusercontent.com + opengraph.githubassets.com github-production-user-asset-6210df.s3.amazonaws.com + customer-stories-feed.github.com spotlights-feed.github.com *.githubusercontent.com; + manifest-src ''self''; media-src github.com user-images.githubusercontent.com/ + secured-user-images.githubusercontent.com/ private-user-images.githubusercontent.com; + script-src github.githubassets.com; style-src ''unsafe-inline'' github.githubassets.com; + worker-src github.com/assets-cdn/worker/ gist.github.com/assets-cdn/worker/' + set-cookie: + - _gh_sess=Nkp3xHI157F4N2GM%2FtpiWJ4xF4Bx4FDXfodM7MDGaoZ8uKfkvFKyjktMCSahfHv0E8wp0swivmtiCHnUAD142Rh3J%2FWMh79UVcN69%2FT8axJh00%2FXB1EbKnR5aRxDUxQR9SRLVLeSGLSvJFiWxYjs7wEUWnVQ6RPNqXJXVBbM7nL5MmNHadQRcPbyRPGcSANhU%2Fh4XCt7Bi2ptd5Bz3EOdlYGmsM2ZDHjCMJhRa5yO%2BuHH0da5VlQnNsMPzhF4UhMuL3xGP8MXCFz4rD9P0fpWQ%3D%3D--zihX8p8i2nw5oUAh--r9Mw4%2FqDGwj9DRlEKJs57g%3D%3D; + Path=/; HttpOnly; Secure; SameSite=Lax + - _octo=GH1.1.1282973806.1677723147; Path=/; Domain=github.com; Expires=Sat, + 02 Mar 2024 02:12:27 GMT; Secure; SameSite=Lax + - logged_in=no; Path=/; Domain=github.com; Expires=Sat, 02 Mar 2024 02:12:27 + GMT; HttpOnly; Secure; SameSite=Lax + accept-ranges: + - bytes + x-github-request-id: + - FD24:32BA:B82EBF9:110A395E:6400060B + body: + encoding: ASCII-8BIT + string: '' + http_version: '2' + adapter_metadata: + effective_url: https://github.com/NetAppDocs/storagegrid-116/blob/main/admin/configuring-load-balancer-endpoints.adoc + recorded_at: Thu, 02 Mar 2023 02:12:27 GMT +- request: + method: head + uri: https://www.slideshare.net/NetApp + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; HTML Proofer/5.0.4; +https://github.com/gjtorikian/html-proofer) + Accept: + - application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Expect: + - '' + response: + status: + code: 200 + message: '' + headers: + content-type: + - text/html; charset=utf-8 + server: + - nginx + x-frame-options: + - SAMEORIGIN + x-xss-protection: + - 1; mode=block + x-content-type-options: + - nosniff + - nosniff + x-download-options: + - noopen + x-permitted-cross-domain-policies: + - none + referrer-policy: + - strict-origin-when-cross-origin + x-request-uuid: + - ebd788a2e3d275b12a18f64b9d412359 + cache-control: + - private, no-store + pragma: + - no-cache + x-ss-make-cacheable: + - 'true' + x-bench-route: + - profile/index + etag: + - W/"24673b46ca35d946fe9c7d1a29d3f235" + set-cookie: + - flash=BAh7DEkiC25vdGljZQY6BkVGMEkiDHdhcm5pbmcGOwBGMEkiDG1lc3NhZ2UGOwBGMEkiDHN1Y2Nlc3MGOwBGMEkiCmVycm9yBjsARjBJIg5wZXJtYW5lbnQGOwBGMEkiEW1vZGFsX25vdGljZQY7AEYw--4d44737d8a4b0fb4535d68df321d9eff6a31ba96; + path=/ + - browser_id=7c7e7b7a-7b48-4ccc-b547-7574d445c96f; Domain=.slideshare.net; Path=/; + Expires=Tue, 29 Feb 2028 02:12:27 GMT + x-request-id: + - ebd788a2e3d275b12a18f64b9d412359 + x-runtime: + - '0.371590' + p3p: + - CP="OTI DSP COR CUR ADM DEV PSD IVD CONo OUR IND" + accept-ranges: + - bytes + date: + - Thu, 02 Mar 2023 02:12:27 GMT + via: + - 1.1 varnish + x-served-by: + - cache-ewr18123-EWR + x-cache: + - MISS + x-cache-hits: + - '0' + x-timer: + - S1677723147.450715,VS0,VE407 + strict-transport-security: + - max-age=63072000; includeSubDomains; preload + alt-svc: + - h3=":443";ma=86400,h3-29=":443";ma=86400,h3-27=":443";ma=86400 + body: + encoding: ASCII-8BIT + string: '' + http_version: '2' + adapter_metadata: + effective_url: https://www.slideshare.net/NetApp + recorded_at: Thu, 02 Mar 2023 02:12:27 GMT +- request: + method: head + uri: https://github.com/netapp-lhalbert + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; HTML Proofer/5.0.4; +https://github.com/gjtorikian/html-proofer) + Accept: + - application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Expect: + - '' + response: + status: + code: 200 + message: '' + headers: + server: + - GitHub.com + date: + - Thu, 02 Mar 2023 02:12:27 GMT + content-type: + - text/html; charset=utf-8 + vary: + - X-Requested-With, X-PJAX-Container, Turbo-Frame, Turbo-Visit, Accept-Encoding, + Accept, X-Requested-With + etag: + - W/"eab9e534ab92a9c1b8883fa9e8e0d61f" + cache-control: + - max-age=0, private, must-revalidate + strict-transport-security: + - max-age=31536000; includeSubdomains; preload + x-frame-options: + - deny + x-content-type-options: + - nosniff + x-xss-protection: + - '0' + referrer-policy: + - origin-when-cross-origin, strict-origin-when-cross-origin + content-security-policy: + - 'default-src ''none''; base-uri ''self''; block-all-mixed-content; child-src + github.com/assets-cdn/worker/ gist.github.com/assets-cdn/worker/; connect-src + ''self'' uploads.github.com objects-origin.githubusercontent.com www.githubstatus.com + collector.github.com raw.githubusercontent.com api.github.com github-cloud.s3.amazonaws.com + github-production-repository-file-5c1aeb.s3.amazonaws.com github-production-upload-manifest-file-7fdce7.s3.amazonaws.com + github-production-user-asset-6210df.s3.amazonaws.com cdn.optimizely.com logx.optimizely.com/v1/events + *.actions.githubusercontent.com productionresultssa0.blob.core.windows.net/ + productionresultssa1.blob.core.windows.net/ productionresultssa2.blob.core.windows.net/ + productionresultssa3.blob.core.windows.net/ productionresultssa4.blob.core.windows.net/ + wss://*.actions.githubusercontent.com online.visualstudio.com/api/v1/locations + github-production-repository-image-32fea6.s3.amazonaws.com github-production-release-asset-2e65be.s3.amazonaws.com + insights.github.com wss://alive.github.com; font-src github.githubassets.com; + form-action ''self'' github.com gist.github.com objects-origin.githubusercontent.com; + frame-ancestors ''none''; frame-src viewscreen.githubusercontent.com notebooks.githubusercontent.com; + img-src ''self'' data: github.githubassets.com media.githubusercontent.com + camo.githubusercontent.com identicons.github.com avatars.githubusercontent.com + github-cloud.s3.amazonaws.com objects.githubusercontent.com objects-origin.githubusercontent.com + secured-user-images.githubusercontent.com/ private-user-images.githubusercontent.com + opengraph.githubassets.com github-production-user-asset-6210df.s3.amazonaws.com + customer-stories-feed.github.com spotlights-feed.github.com *.githubusercontent.com; + manifest-src ''self''; media-src github.com user-images.githubusercontent.com/ + secured-user-images.githubusercontent.com/ private-user-images.githubusercontent.com; + script-src github.githubassets.com; style-src ''unsafe-inline'' github.githubassets.com; + worker-src github.com/assets-cdn/worker/ gist.github.com/assets-cdn/worker/' + set-cookie: + - _gh_sess=EnArlkm3%2B3TpJLiUMMf4GVaDwq7EQ5KBRQanpSivR%2Bm8QbPsG0I3n1GJb9Ngj6WpNN6xjGnt3fGC4CG%2BC4pBwh0eoK1NYCgrDHU6m5IU4wTRpkXclkkXLMRhtt8tQnlOMUP3qJVbqghrZ%2B7o2ctrAddezJJnGDg99zokhSz%2FUi65F%2FuI4KT2qNqAGiHCK7kokI1L21jzLAZcnf%2BmZ8GDFnWhz8LUUYRqu8CvCez%2BI4KCHpojNRn8btVO7SPahYXrNOR4pIX90RafsbFnx5qCQA%3D%3D--r%2B8JVp8rUWdppFiD--pFBnRltX2xUeKzwz2NTGZA%3D%3D; + Path=/; HttpOnly; Secure; SameSite=Lax + - _octo=GH1.1.1115079731.1677723147; Path=/; Domain=github.com; Expires=Sat, + 02 Mar 2024 02:12:27 GMT; Secure; SameSite=Lax + - logged_in=no; Path=/; Domain=github.com; Expires=Sat, 02 Mar 2024 02:12:27 + GMT; HttpOnly; Secure; SameSite=Lax + accept-ranges: + - bytes + x-github-request-id: + - FD27:1CCB:4322B29:657A147:6400060B + body: + encoding: ASCII-8BIT + string: '' + http_version: '2' + adapter_metadata: + effective_url: https://github.com/netapp-lhalbert + recorded_at: Thu, 02 Mar 2023 02:12:27 GMT +- request: + method: head + uri: https://docs.netapp.com/us-en/storagegrid-116/admin/configuring-load-balancer-endpoints.html + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; HTML Proofer/5.0.4; +https://github.com/gjtorikian/html-proofer) + Accept: + - application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Expect: + - '' + response: + status: + code: 200 + message: OK + headers: + Content-Type: + - text/html; charset=utf-8 + Connection: + - keep-alive + Date: + - Thu, 02 Mar 2023 02:12:27 GMT + Server: + - GitHub.com + Access-Control-Allow-Origin: + - "*" + expires: + - Thu, 02 Mar 2023 02:22:27 GMT + Cache-Control: + - max-age=600 + x-proxy-cache: + - MISS + X-GitHub-Request-Id: + - F15A:3C3C:550A5D:606569:6400060B + Accept-Ranges: + - bytes + Via: + - 1.1 varnish + Age: + - '0' + X-Served-By: + - cache-pdx12330-PDX + X-Cache: + - MISS + X-Cache-Hits: + - '0' + X-Timer: + - S1677723148.586333,VS0,VE300 + Vary: + - Accept-Encoding + X-Fastly-Request-ID: + - b81fa28cb11dc9a1159ff14b1ae387f5897ab9b9 + body: + encoding: ASCII-8BIT + string: '' + http_version: '1.1' + adapter_metadata: + effective_url: https://docs.netapp.com/us-en/storagegrid-116/admin/configuring-load-balancer-endpoints.html + recorded_at: Thu, 02 Mar 2023 02:12:27 GMT +- request: + method: head + uri: https://www.netapp.com/company/legal/copyright/ + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; HTML Proofer/5.0.4; +https://github.com/gjtorikian/html-proofer) + Accept: + - application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Expect: + - '' + response: + status: + code: 200 + message: '' + headers: + content-type: + - text/html; charset=utf-8 + server: + - Microsoft-IIS/10.0 + access-control-allow-methods: + - GET + access-control-allow-origin: + - "*" + access-control-expose-headers: + - Request-Context + cache-control: + - private + x-aspnetmvc-version: + - '5.2' + x-aspnet-version: + - 4.0.30319 + request-context: + - appId=cid-v1:149249a1-9c0c-40ae-89b4-ef4e47a1cbd8 + x-powered-by: + - ASP.NET + date: + - Thu, 02 Mar 2023 02:12:28 GMT + set-cookie: + - loggedin-Status=false; path=/ + - user-info=; path=/ + alt-svc: + - h3=":443"; ma=93600 + x-akam-sw-version: + - 0.5.0 + strict-transport-security: + - max-age=63072000 + content-security-policy: + - 'default-src * ''unsafe-inline''; script-src * data: ''unsafe-inline'' ''unsafe-eval''; + style-src * ''unsafe-inline''; style-src-elem * ''unsafe-inline''; style-src-attr + * ''unsafe-inline''; img-src * data: blob:; font-src * data:; frame-src * + data:; frame-ancestors *; media-src * blob:; worker-src * blob:' + referrer-policy: + - strict-origin-when-cross-origin + x-xss-protection: + - 1; mode=block + x-content-type-options: + - nosniff + x-frame-options: + - SAMEORIGIN + server-timing: + - ak_p; desc="466034_388049348_2496399350_93573_4561_36_0";dur=1 + body: + encoding: ASCII-8BIT + string: '' + http_version: '2' + adapter_metadata: + effective_url: https://www.netapp.com/company/legal/copyright/ + recorded_at: Thu, 02 Mar 2023 02:12:28 GMT +- request: + method: head + uri: https://www.netapp.com/products-a-z/ + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; HTML Proofer/5.0.4; +https://github.com/gjtorikian/html-proofer) + Accept: + - application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Expect: + - '' + response: + status: + code: 200 + message: '' + headers: + content-type: + - text/html; charset=utf-8 + server: + - Microsoft-IIS/10.0 + access-control-allow-methods: + - GET + access-control-allow-origin: + - "*" + access-control-expose-headers: + - Request-Context + x-aspnetmvc-version: + - '5.2' + x-aspnet-version: + - 4.0.30319 + request-context: + - appId=cid-v1:e2d3a373-3088-4723-b22f-e41777ab70f4 + x-powered-by: + - ASP.NET + cache-control: + - private, max-age=900 + expires: + - Thu, 02 Mar 2023 02:27:29 GMT + date: + - Thu, 02 Mar 2023 02:12:29 GMT + set-cookie: + - loggedin-Status=false; path=/ + - user-info=; path=/ + alt-svc: + - h3=":443"; ma=93600 + x-akam-sw-version: + - 0.5.0 + strict-transport-security: + - max-age=63072000 + content-security-policy: + - 'default-src * ''unsafe-inline''; script-src * data: ''unsafe-inline'' ''unsafe-eval''; + style-src * ''unsafe-inline''; style-src-elem * ''unsafe-inline''; style-src-attr + * ''unsafe-inline''; img-src * data: blob:; font-src * data:; frame-src * + data:; frame-ancestors *; media-src * blob:; worker-src * blob:' + referrer-policy: + - strict-origin-when-cross-origin + x-xss-protection: + - 1; mode=block + x-content-type-options: + - nosniff + x-frame-options: + - SAMEORIGIN + server-timing: + - ak_p; desc="466034_388049348_2496399409_195795_3379_46_0";dur=1 + body: + encoding: ASCII-8BIT + string: '' + http_version: '2' + adapter_metadata: + effective_url: https://www.netapp.com/products-a-z/ + recorded_at: Thu, 02 Mar 2023 02:12:29 GMT +- request: + method: head + uri: https://customers.netapp.com/en/ + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; HTML Proofer/5.0.4; +https://github.com/gjtorikian/html-proofer) + Accept: + - application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Expect: + - '' + response: + status: + code: 200 + message: '' + headers: + content-type: + - text/html; charset=utf-8 + server: + - Microsoft-IIS/10.0 + access-control-allow-methods: + - GET + access-control-allow-origin: + - "*" + access-control-expose-headers: + - Request-Context + x-aspnetmvc-version: + - '5.2' + x-aspnet-version: + - 4.0.30319 + request-context: + - appId=cid-v1:e2d3a373-3088-4723-b22f-e41777ab70f4 + x-powered-by: + - ASP.NET + expires: + - Thu, 02 Mar 2023 02:12:29 GMT + cache-control: + - max-age=0, no-cache, no-store + pragma: + - no-cache + date: + - Thu, 02 Mar 2023 02:12:29 GMT + set-cookie: + - loggedin-Status=false; path=/ + - user-info=; path=/ + alt-svc: + - h3=":443"; ma=93600 + x-akam-sw-version: + - 0.5.0 + strict-transport-security: + - max-age=63072000 + content-security-policy: + - 'default-src * ''unsafe-inline''; script-src * data: ''unsafe-inline'' ''unsafe-eval''; + style-src * ''unsafe-inline''; style-src-elem * ''unsafe-inline''; style-src-attr + * ''unsafe-inline''; img-src * data: blob:; font-src * data:; frame-src * + data:; frame-ancestors *; media-src * blob:; worker-src * blob:' + referrer-policy: + - strict-origin-when-cross-origin + x-xss-protection: + - 1; mode=block + x-content-type-options: + - nosniff + x-frame-options: + - SAMEORIGIN + server-timing: + - ak_p; desc="466034_388049348_2496399781_204378_4175_48_0";dur=1 + body: + encoding: ASCII-8BIT + string: '' + http_version: '2' + adapter_metadata: + effective_url: https://www.netapp.com/customers/ + recorded_at: Thu, 02 Mar 2023 02:12:29 GMT +- request: + method: head + uri: https://mysupport.netapp.com/documentation/docweb/index.html?productID=63374&language=en-US + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; HTML Proofer/5.0.4; +https://github.com/gjtorikian/html-proofer) + Accept: + - application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Expect: + - '' + response: + status: + code: 200 + message: '' + headers: + content-type: + - text/html;charset=UTF-8 + server: + - envoy + cache-control: + - no-cache + x-oracle-dms-ecid: + - 9d0be3c7ffe3e488:-15776f67:186917b10a6:-8000-000000000006454f + x-envoy-upstream-service-time: + - '1257' + date: + - Thu, 02 Mar 2023 02:12:29 GMT + set-cookie: + - slang=EN; domain=.netapp.com; path=/ + - JSESSIONID_ECM=H0igF6F6Rb_5BgL8zmr5gy8aCeuI8K4FaQy1i_prRPQRGjT5tQr5!2123771580; + path=/; HttpOnly + - LTMD-COOKIE-LIBRARY-P80=02f0803383-3a83-4dtoV59Fta8KggV6yJ0bFdMH0dhmhWfBwOOstvfPrY4nVmg59Zhwl-yuZo36iJf0yCYP4; + path=/; SameSite=None; Secure + strict-transport-security: + - max-age=15768000 ; includeSubDomains ; preload + server-timing: + - ak_p; desc="466034_388049883_32821067_154653_35660_52_0";dur=1 + body: + encoding: ASCII-8BIT + string: '' + http_version: '2' + adapter_metadata: + effective_url: https://mysupport.netapp.com/documentation/docweb/index.html?productID=63374&language=en-US + recorded_at: Thu, 02 Mar 2023 02:12:29 GMT +- request: + method: head + uri: https://www.netapp.com/company/legal/cookie-policy/ + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; HTML Proofer/5.0.4; +https://github.com/gjtorikian/html-proofer) + Accept: + - application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Expect: + - '' + response: + status: + code: 200 + message: '' + headers: + content-type: + - text/html; charset=utf-8 + server: + - Microsoft-IIS/10.0 + access-control-allow-methods: + - GET + access-control-allow-origin: + - "*" + access-control-expose-headers: + - Request-Context + cache-control: + - private + x-aspnetmvc-version: + - '5.2' + x-aspnet-version: + - 4.0.30319 + request-context: + - appId=cid-v1:149249a1-9c0c-40ae-89b4-ef4e47a1cbd8 + x-powered-by: + - ASP.NET + date: + - Thu, 02 Mar 2023 02:12:30 GMT + set-cookie: + - loggedin-Status=false; path=/ + - user-info=; path=/ + alt-svc: + - h3=":443"; ma=93600 + x-akam-sw-version: + - 0.5.0 + strict-transport-security: + - max-age=63072000 + content-security-policy: + - 'default-src * ''unsafe-inline''; script-src * data: ''unsafe-inline'' ''unsafe-eval''; + style-src * ''unsafe-inline''; style-src-elem * ''unsafe-inline''; style-src-attr + * ''unsafe-inline''; img-src * data: blob:; font-src * data:; frame-src * + data:; frame-ancestors *; media-src * blob:; worker-src * blob:' + referrer-policy: + - strict-origin-when-cross-origin + x-xss-protection: + - 1; mode=block + x-content-type-options: + - nosniff + x-frame-options: + - SAMEORIGIN + server-timing: + - ak_p; desc="466034_388049348_2496399357_264265_2882_47_0";dur=1 + body: + encoding: ASCII-8BIT + string: '' + http_version: '2' + adapter_metadata: + effective_url: https://www.netapp.com/company/legal/cookie-policy/ + recorded_at: Thu, 02 Mar 2023 02:12:30 GMT +- request: + method: head + uri: https://mysupport.netapp.com/documentation/productlibrary/index.html?productID=61023&archive=true + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; HTML Proofer/5.0.4; +https://github.com/gjtorikian/html-proofer) + Accept: + - application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Expect: + - '' + response: + status: + code: 200 + message: '' + headers: + content-type: + - text/html;charset=UTF-8 + server: + - envoy + cache-control: + - no-cache + x-oracle-dms-ecid: + - 9d0be3c7ffe3e488:-15776f67:186917b10a6:-8000-0000000000064551 + x-envoy-upstream-service-time: + - '1547' + date: + - Thu, 02 Mar 2023 02:12:30 GMT + set-cookie: + - slang=EN; domain=.netapp.com; path=/ + - JSESSIONID_ECM=AqSgF6HvTCLOEquPbp2C03bcjvpadDFGnjpkYMYqB8DlWnxIRaik!2123771580; + path=/; HttpOnly + - LTMD-COOKIE-LIBRARY-P80=02f0803383-3a83-4dgVJ_rSVrwHOTEafWdnROxmniPxSx5oXJJuXQ1_kDOdTnaXQfaZq0fbLjG9b93xRrYAE; + path=/; SameSite=None; Secure + strict-transport-security: + - max-age=15768000 ; includeSubDomains ; preload + server-timing: + - ak_p; desc="466034_388049883_32821070_185820_2683_52_0";dur=1 + body: + encoding: ASCII-8BIT + string: '' + http_version: '2' + adapter_metadata: + effective_url: https://mysupport.netapp.com/documentation/productlibrary/index.html?productID=61023&archive=true + recorded_at: Thu, 02 Mar 2023 02:12:30 GMT +- request: + method: head + uri: https://community.netapp.com/ + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; HTML Proofer/5.0.4; +https://github.com/gjtorikian/html-proofer) + Accept: + - application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Expect: + - '' + response: + status: + code: 200 + message: '' + headers: + content-type: + - text/html;charset=UTF-8 + x-frame-options: + - SAMEORIGIN + x-amz-cf-pop: + - ORD52-C2 + x-amz-cf-id: + - 0HC8TtOCg1MrgK5tWcSi0CWikcS3JfAX-jkeGzCFgVJImwHZm_mVug== + content-length: + - '0' + expires: + - Thu, 02 Mar 2023 02:12:30 GMT + cache-control: + - max-age=0, no-cache, no-store + pragma: + - no-cache + date: + - Thu, 02 Mar 2023 02:12:30 GMT + set-cookie: + - AWSALB=I8ElRweuMhtaeujhC0lolWOT+62ahAU3VFv54c7KWXlTd3hWl371g+VHcOqRW22fjAbmYllJZwyAMa91w2sxsQMZsATggwbhL2OFNZHzJ5NbZQYBA25443lYui6X; + Expires=Thu, 09 Mar 2023 02:12:30 GMT; Path=/ + - AWSALBCORS=I8ElRweuMhtaeujhC0lolWOT+62ahAU3VFv54c7KWXlTd3hWl371g+VHcOqRW22fjAbmYllJZwyAMa91w2sxsQMZsATggwbhL2OFNZHzJ5NbZQYBA25443lYui6X; + Expires=Thu, 09 Mar 2023 02:12:30 GMT; Path=/; SameSite=None; Secure + - LiSESSIONID=BCBEB8F0328D0E10EA90BFBC9A10B2D2; Path=/; Secure; HttpOnly;SameSite=None + - LithiumUserInfo=""; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure + - LithiumUserSecure=""; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure + - LithiumVisitor=~2UXIlWTsw6NcIaekP~Kn0i70B1OsWvGRHG8uqaz8FsHG-LUfFYK5SfAY74hiNeD14OlSf_tIVAXa3oMRM_XoqoqgayCzqAdrA8lTPNYA..; + Path=/; HttpOnly; Max-Age=15780000; Secure; SameSite=None + - LithiumCookiesAccepted=0; Path=/; Max-Age=15780000; Secure; SameSite=None + strict-transport-security: + - max-age=15768000 + server-timing: + - ak_p; desc="466034_388049883_32821137_29166_2293_32_0";dur=1 + body: + encoding: ASCII-8BIT + string: '' + http_version: '2' + adapter_metadata: + effective_url: https://community.netapp.com/ + recorded_at: Thu, 02 Mar 2023 02:12:30 GMT +- request: + method: head + uri: https://cloud.netapp.com + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Mozilla/5.0 (compatible; HTML Proofer/5.0.4; +https://github.com/gjtorikian/html-proofer) + Accept: + - application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 + Expect: + - '' + response: + status: + code: 200 + message: '' + headers: + date: + - Thu, 02 Mar 2023 02:12:30 GMT + content-type: + - text/html; charset=UTF-8 + content-length: + - '91403' + etag: + - W/"0bec3cbd254bd698a8efefd70d3ccf9e" + last-modified: + - Mon, 27 Feb 2023 11:54:22 GMT + link: + - "; rel=preload; as=script,; + rel=preload; as=script" + strict-transport-security: + - max-age=31536000 + content-security-policy: + - upgrade-insecure-requests + edge-cache-tag: + - CT-88139867809,CT-91540621693,CT-91540621701,CT-91540621705,CT-91540621708,P-525875,W-1662046234398,W-1662637690034,W-1662646286208,W-1662730080492,W-1670273620623,W-1672676867401,CW-83668318869,CW-84017148248,CW-84020306105,CW-84310752266,CW-84324796546,CW-84437629332,CW-85034688429,CW-88685523460,CW-97139556934,E-47882098007,E-56778788163,E-83652687008,E-83669813433,E-84022661012,E-84173520477,E-84173942881,E-84210106474,E-84310312067,E-84324382526,E-84324707605,E-84437649446,E-85034902804,PGS-ALL,SW-2,GC-86778475860,GC-89393348176,GC-89592173708 + referrer-policy: + - no-referrer-when-downgrade + x-hs-cache-config: + - BrowserCache-5s-EdgeCache-0s + x-hs-cache-control: + - s-maxage=10800, max-age=0 + x-hs-cf-cache-status: + - REVALIDATED + x-hs-content-id: + - '88139867809' + x-hs-hub-id: + - '525875' + x-hs-prerendered: + - two-phase;Mon, 27 Feb 2023 11:54:21 GMT + set-cookie: + - __cf_bm=JcKj5Wwl_EKpHjs8vQy7sc.Vq.AhmerrC969dz03th0-1677723150-0-Ac2r/8ug9Mc+lLFbTrPFCZ7XrePLPtJepCm6HrfWA3o1F1PFE0u4C26OSpdebTUwawoczfrRBuqFlFcIGTIdgQs=; + path=/; expires=Thu, 02-Mar-23 02:42:30 GMT; domain=.bluexp.netapp.com; HttpOnly; + Secure; SameSite=None + - __cfruid=b2b843b331d8452f960f5c76de4a0c5e81f9ef36-1677723150; path=/; domain=.bluexp.netapp.com; + HttpOnly; Secure; SameSite=None + report-to: + - '{"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=1voj%2BY68gP2%2Frj53cCcuAhOtP8aphNThxAmsyn4xKwsf4k0kmFFXsnubczS1XlkCQVtBXvsnc3OfYLO8kSZyXnKWq%2F4P0UYMavk3BDeZ4npbuJtUX0lZOVFTQIL9EWzdi%2Bao"}],"group":"cf-nel","max_age":604800}' + nel: + - '{"success_fraction":0.01,"report_to":"cf-nel","max_age":604800}' + server: + - cloudflare + cf-ray: + - 7a161d795d0ef01d-EWR + alt-svc: + - h3=":443"; ma=86400, h3-29=":443"; ma=86400 + body: + encoding: ASCII-8BIT + string: '' + http_version: '2' + adapter_metadata: + effective_url: https://bluexp.netapp.com/ + recorded_at: Thu, 02 Mar 2023 02:12:30 GMT +recorded_with: VCR 2.9.3 diff --git a/spec/html-proofer/links_spec.rb b/spec/html-proofer/links_spec.rb index a6a5119a..18f85da4 100644 --- a/spec/html-proofer/links_spec.rb +++ b/spec/html-proofer/links_spec.rb @@ -768,4 +768,10 @@ expect(proofer.failed_checks.count).to(eq(1)) expect(proofer.failed_checks.first.description).to(match(/.pdf exists, but the hash 'page=2111115' does not/)) end + + it "navigates to sibling through parent" do + link_pointing_to_sibling = File.join(FIXTURES_DIR, "links", "root_folder", "admin", "link_to_relative_parent.html") + proofer = run_proofer(link_pointing_to_sibling, :file) + expect(proofer.failed_checks.count).to(eq(0)) + end end From 21044c9f8638dcefccce1ed6aff32496071a40d5 Mon Sep 17 00:00:00 2001 From: Riccardo Porreca Date: Tue, 7 Mar 2023 00:21:13 +0100 Subject: [PATCH 23/78] Reproduce #792 error `../` relative links and cache --- spec/html-proofer/links_spec.rb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/spec/html-proofer/links_spec.rb b/spec/html-proofer/links_spec.rb index 18f85da4..4a0fb380 100644 --- a/spec/html-proofer/links_spec.rb +++ b/spec/html-proofer/links_spec.rb @@ -774,4 +774,18 @@ proofer = run_proofer(link_pointing_to_sibling, :file) expect(proofer.failed_checks.count).to(eq(0)) end + + it "navigates to sibling through parent, with cache" do + link_pointing_to_sibling = File.join(FIXTURES_DIR, "links", "root_folder", "admin", "link_to_relative_parent.html") + cache_storage_dir = File.join(FIXTURES_DIR, "cache", "tmp_sibling_cache") + cache_file = "cache.json" + cache_filepath = File.join(cache_storage_dir, cache_file) + proofer = run_proofer( + link_pointing_to_sibling, + :file, + cache: { timeframe: { internal: "1d" }, storage_dir: cache_storage_dir, cache_file: cache_file}, + ) + File.delete(cache_filepath) if File.exist?(cache_filepath) + expect(proofer.failed_checks.count).to(eq(0)) + end end From 952669e2de21732cd96f676d02aeef0f605a1761 Mon Sep 17 00:00:00 2001 From: Riccardo Porreca Date: Tue, 7 Mar 2023 00:24:17 +0100 Subject: [PATCH 24/78] Do not cleaning URLs for the internal cache, fixes #792 --- lib/html_proofer/cache.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/html_proofer/cache.rb b/lib/html_proofer/cache.rb index c48be001..92ae038c 100644 --- a/lib/html_proofer/cache.rb +++ b/lib/html_proofer/cache.rb @@ -93,8 +93,10 @@ def retrieve_urls(urls_detected, type) # if there are no urls, bail return {} if urls_detected.empty? - urls_detected = urls_detected.transform_keys do |url| - cleaned_url(url) + if type == :external + urls_detected = urls_detected.transform_keys do |url| + cleaned_url(url) + end end urls_to_check = detect_url_changes(urls_detected, type) From b806fbd6686c4d301c43833faf945efadd935156 Mon Sep 17 00:00:00 2001 From: Riccardo Porreca Date: Tue, 7 Mar 2023 00:34:21 +0100 Subject: [PATCH 25/78] Lint --- lib/html_proofer/url_validator/external.rb | 2 +- lib/html_proofer/xpath_functions.rb | 2 +- spec/html-proofer/links_spec.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/html_proofer/url_validator/external.rb b/lib/html_proofer/url_validator/external.rb index 3e7622ac..bc6da8f0 100644 --- a/lib/html_proofer/url_validator/external.rb +++ b/lib/html_proofer/url_validator/external.rb @@ -126,7 +126,7 @@ def check_hash_in_2xx_response(href, url, response, filenames) # attempt to verify PDF hash ref; see #787 for more details # FIXME: this is re-reading the PDF response - if content_type && /pdf/.match?(content_type[1]) + if content_type && content_type[1].include?("pdf") io = URI.parse(url.to_s).open reader = PDF::Reader.new(io) diff --git a/lib/html_proofer/xpath_functions.rb b/lib/html_proofer/xpath_functions.rb index 6f759716..d458fa00 100644 --- a/lib/html_proofer/xpath_functions.rb +++ b/lib/html_proofer/xpath_functions.rb @@ -4,7 +4,7 @@ module HTMLProofer # https://stackoverflow.com/a/8812293 class XpathFunctions def case_sensitive_equals(node_set, str_to_match) - node_set.find_all { |node| node.to_s.== str_to_match.to_s } + node_set.find_all { |node| node.to_s == str_to_match.to_s } end end end diff --git a/spec/html-proofer/links_spec.rb b/spec/html-proofer/links_spec.rb index 4a0fb380..2b5a784a 100644 --- a/spec/html-proofer/links_spec.rb +++ b/spec/html-proofer/links_spec.rb @@ -783,7 +783,7 @@ proofer = run_proofer( link_pointing_to_sibling, :file, - cache: { timeframe: { internal: "1d" }, storage_dir: cache_storage_dir, cache_file: cache_file}, + cache: { timeframe: { internal: "1d" }, storage_dir: cache_storage_dir, cache_file: cache_file }, ) File.delete(cache_filepath) if File.exist?(cache_filepath) expect(proofer.failed_checks.count).to(eq(0)) From 6ee3b71e209d1c15df3024842505fa51bd43189c Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Tue, 7 Mar 2023 16:39:36 -0500 Subject: [PATCH 26/78] :gem: bump to 5.0.5 --- lib/html_proofer/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/html_proofer/version.rb b/lib/html_proofer/version.rb index 06db271d..6954358c 100644 --- a/lib/html_proofer/version.rb +++ b/lib/html_proofer/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module HTMLProofer - VERSION = "5.0.4" + VERSION = "5.0.5" end From 58c20fe7e85258ed9fb9c3dc68a93ccc4c888f23 Mon Sep 17 00:00:00 2001 From: Actions Auto Build Date: Tue, 7 Mar 2023 22:40:26 +0000 Subject: [PATCH 27/78] docs: update changelog --- CHANGELOG.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 05bb847c..26b5f1a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,20 @@ # Changelog +## [v5.0.5](https://github.com/gjtorikian/html-proofer/tree/v5.0.5) (2023-03-07) + +[Full Changelog](https://github.com/gjtorikian/html-proofer/compare/v5.0.4...v5.0.5) + +**Closed issues:** + +- Reporting broken links when using relative internal links reported as broken [\#792](https://github.com/gjtorikian/html-proofer/issues/792) +- v5 upgrade guide? [\#791](https://github.com/gjtorikian/html-proofer/issues/791) +- Anchor links are encoded in html-proofer output [\#757](https://github.com/gjtorikian/html-proofer/issues/757) + +**Merged pull requests:** + +- Fix cleaning relative links cache key [\#793](https://github.com/gjtorikian/html-proofer/pull/793) ([riccardoporreca](https://github.com/riccardoporreca)) +- remove proprietary pdf [\#790](https://github.com/gjtorikian/html-proofer/pull/790) ([gjtorikian](https://github.com/gjtorikian)) + ## [v5.0.4](https://github.com/gjtorikian/html-proofer/tree/v5.0.4) (2023-01-20) [Full Changelog](https://github.com/gjtorikian/html-proofer/compare/v5.0.3...v5.0.4) From 40c72a4481459eea805c26549de1e4c6720bb86a Mon Sep 17 00:00:00 2001 From: Riccardo Porreca Date: Thu, 9 Mar 2023 16:28:14 +0100 Subject: [PATCH 28/78] Refactor source and filename as `URL` attributes, instead of `Runner` * They are needed in `URL` methods to check internal links, and this way we avoid having to set them as `Runner` attributes while looping over collected links. * This also allows a more consistent definition and usage of internal links metadata. --- lib/html_proofer/attribute/url.rb | 25 ++++++++++++---------- lib/html_proofer/check.rb | 6 +++--- lib/html_proofer/check/images.rb | 2 +- lib/html_proofer/element.rb | 2 +- lib/html_proofer/url_validator/internal.rb | 9 +++----- 5 files changed, 22 insertions(+), 22 deletions(-) diff --git a/lib/html_proofer/attribute/url.rb b/lib/html_proofer/attribute/url.rb index 67691843..7507413a 100644 --- a/lib/html_proofer/attribute/url.rb +++ b/lib/html_proofer/attribute/url.rb @@ -3,13 +3,16 @@ module HTMLProofer class Attribute class Url < HTMLProofer::Attribute - attr_reader :url, :size + attr_reader :url, :size, :source, :filename REMOTE_SCHEMES = ["http", "https"].freeze - def initialize(runner, link_attribute, base_url: nil, extract_size: false) + def initialize(runner, link_attribute, base_url: nil, source: nil, filename: nil, extract_size: false) super + @source = source + @filename = filename + if @raw_attribute.nil? @url = nil else @@ -125,7 +128,7 @@ def base64? end def absolute_path - path = file_path || @runner.current_filename + path = file_path || @filename File.expand_path(path, Dir.pwd) end @@ -139,22 +142,22 @@ def file_path base = if absolute_path?(path) # path relative to root # either overwrite with root_dir; or, if source is directory, use that; or, just get the current file's dirname - @runner.options[:root_dir] || (File.directory?(@runner.current_source) ? @runner.current_source : File.dirname(@runner.current_source)) + @runner.options[:root_dir] || (File.directory?(@source) ? @source : File.dirname(@source)) # relative links, path is a file elsif File.exist?(File.expand_path( path, - @runner.current_source, - )) || File.exist?(File.expand_path(path_dot_ext, @runner.current_source)) - File.dirname(@runner.current_filename) + @source, + )) || File.exist?(File.expand_path(path_dot_ext, @source)) + File.dirname(@filename) # relative links in nested dir, path is a file elsif File.exist?(File.join( - File.dirname(@runner.current_filename), + File.dirname(@filename), path, - )) || File.exist?(File.join(File.dirname(@runner.current_filename), path_dot_ext)) - File.dirname(@runner.current_filename) + )) || File.exist?(File.join(File.dirname(@filename), path_dot_ext)) + File.dirname(@filename) # relative link, path is a directory else - @runner.current_filename + @filename end file = File.join(base, path) diff --git a/lib/html_proofer/check.rb b/lib/html_proofer/check.rb index 32e40a5f..bf09c5cc 100644 --- a/lib/html_proofer/check.rb +++ b/lib/html_proofer/check.rb @@ -45,8 +45,8 @@ def add_to_internal_urls(url, line) @internal_urls[url_string] = [] if @internal_urls[url_string].nil? metadata = { - source: @runner.current_source, - filename: @runner.current_filename, + source: url.source, + filename: url.filename, line: line, base_url: base_url, found: false, @@ -59,7 +59,7 @@ def add_to_external_urls(url, line) @external_urls[url_string] = [] if @external_urls[url_string].nil? - @external_urls[url_string] << { filename: @runner.current_filename, line: line } + @external_urls[url_string] << { filename: url.filename, line: line } end class << self diff --git a/lib/html_proofer/check/images.rb b/lib/html_proofer/check/images.rb index b5b34aab..dee3b4fa 100644 --- a/lib/html_proofer/check/images.rb +++ b/lib/html_proofer/check/images.rb @@ -37,7 +37,7 @@ def run ) elsif @img.multiple_srcsets? || @img.multiple_sizes? @img.srcsets_wo_sizes.each do |srcset| - srcset_url = HTMLProofer::Attribute::Url.new(@runner, srcset, base_url: @img.base_url, extract_size: true) + srcset_url = HTMLProofer::Attribute::Url.new(@runner, srcset, base_url: @img.base_url, source: @img.url.source, filename: @img.url.filename, extract_size: true) if srcset_url.protocol_relative? add_failure( diff --git a/lib/html_proofer/element.rb b/lib/html_proofer/element.rb index a0bbe55c..1b66313a 100644 --- a/lib/html_proofer/element.rb +++ b/lib/html_proofer/element.rb @@ -16,7 +16,7 @@ def initialize(runner, node, base_url: nil) swap_attributes! @base_url = base_url - @url = Attribute::Url.new(runner, link_attribute, base_url: base_url) + @url = Attribute::Url.new(runner, link_attribute, base_url: base_url, source: @runner.current_source, filename: @runner.current_filename) @line = node.line @content = node.content diff --git a/lib/html_proofer/url_validator/internal.rb b/lib/html_proofer/url_validator/internal.rb index 8af8f5cb..daec0b03 100644 --- a/lib/html_proofer/url_validator/internal.rb +++ b/lib/html_proofer/url_validator/internal.rb @@ -29,15 +29,12 @@ def run_internal_link_checker(links) matched_count_to_log = pluralize(matched_files.count, "reference", "references") @logger.log(:debug, "(#{i + 1} / #{links.count}) Internal link #{link}: Checking #{matched_count_to_log}") matched_files.each do |metadata| - url = HTMLProofer::Attribute::Url.new(@runner, link, base_url: metadata[:base_url]) - - @runner.current_source = metadata[:source] - @runner.current_filename = metadata[:filename] + url = HTMLProofer::Attribute::Url.new(@runner, link, base_url: metadata[:base_url], source: metadata[:source], filename: metadata[:filename]) target_file_path = url.absolute_path unless file_exists?(target_file_path) @failed_checks << Failure.new( - @runner.current_filename, + metadata[:filename], "Links > Internal", "internally linking to #{url}, which does not exist", line: metadata[:line], @@ -62,7 +59,7 @@ def run_internal_link_checker(links) end unless hash_exists @failed_checks << Failure.new( - @runner.current_filename, + metadata[:filename], "Links > Internal", "internally linking to #{url}; the file exists, but the hash '#{url.hash}' does not", line: metadata[:line], From 41af0a18c0b5725eff319de35231d0fc3e7cc22f Mon Sep 17 00:00:00 2001 From: Riccardo Porreca Date: Thu, 9 Mar 2023 18:04:28 +0100 Subject: [PATCH 29/78] Extend `Check.add_failure` to allow an `Element` argument * So we can extract `line` and `content` from there instead of explicitly passing them every time. --- lib/html_proofer/check.rb | 6 ++--- lib/html_proofer/check/favicon.rb | 6 ++--- lib/html_proofer/check/images.rb | 25 ++++++++------------- lib/html_proofer/check/links.rb | 33 +++++++++++----------------- lib/html_proofer/check/open_graph.rb | 12 +++++----- lib/html_proofer/check/scripts.rb | 17 +++++--------- spec/html-proofer/check_spec.rb | 2 +- 7 files changed, 39 insertions(+), 62 deletions(-) diff --git a/lib/html_proofer/check.rb b/lib/html_proofer/check.rb index bf09c5cc..77ac6df2 100644 --- a/lib/html_proofer/check.rb +++ b/lib/html_proofer/check.rb @@ -24,14 +24,14 @@ def run raise NotImplementedError, "HTMLProofer::Check subclasses must implement #run" end - def add_failure(description, line: nil, status: nil, content: nil) + def add_failure(description, element: nil, line: nil, status: nil, content: nil) @failures << Failure.new( @runner.current_filename, short_name, description, - line: line, + line: element.nil? ? line : element.line, status: status, - content: content, + content: element.nil? ? content : element.content, ) end diff --git a/lib/html_proofer/check/favicon.rb b/lib/html_proofer/check/favicon.rb index 0c22d34d..19f5601b 100644 --- a/lib/html_proofer/check/favicon.rb +++ b/lib/html_proofer/check/favicon.rb @@ -19,16 +19,14 @@ def run if @favicon.url.protocol_relative? add_failure( "favicon link #{@favicon.url} is a protocol-relative URL, use explicit https:// instead", - line: @favicon.line, - content: @favicon.content, + element: @favicon, ) elsif @favicon.url.remote? add_to_external_urls(@favicon.url, @favicon.line) elsif !@favicon.url.exists? add_failure( "internal favicon #{@favicon.url.raw_attribute} does not exist", - line: @favicon.line, - content: @favicon.content, + element: @favicon, ) end else diff --git a/lib/html_proofer/check/images.rb b/lib/html_proofer/check/images.rb index dee3b4fa..864300f7 100644 --- a/lib/html_proofer/check/images.rb +++ b/lib/html_proofer/check/images.rb @@ -14,26 +14,23 @@ def run # screenshot filenames should return because of terrible names add_failure( "image has a terrible filename (#{@img.url.raw_attribute})", - line: @img.line, - content: @img.content, + element: @img, ) if terrible_filename? # does the image exist? if missing_src? - add_failure("image has no src or srcset attribute", line: @img.line, content: @img.content) + add_failure("image has no src or srcset attribute", element: @img) elsif @img.url.protocol_relative? add_failure( "image link #{@img.url} is a protocol-relative URL, use explicit https:// instead", - line: @img.line, - content: @img.content, + element: @img, ) elsif @img.url.remote? add_to_external_urls(@img.url, @img.line) elsif !@img.url.exists? && !@img.multiple_srcsets? && !@img.multiple_sizes? add_failure( "internal image #{@img.url.raw_attribute} does not exist", - line: @img.line, - content: @img.content, + element: @img, ) elsif @img.multiple_srcsets? || @img.multiple_sizes? @img.srcsets_wo_sizes.each do |srcset| @@ -42,13 +39,12 @@ def run if srcset_url.protocol_relative? add_failure( "image link #{srcset_url.url} is a protocol-relative URL, use explicit https:// instead", - line: @img.line, - content: @img.content, + element: @img, ) elsif srcset_url.remote? add_to_external_urls(srcset_url.url, @img.line) elsif !srcset_url.exists? - add_failure("internal image #{srcset} does not exist", line: @img.line, content: @img.content) + add_failure("internal image #{srcset} does not exist", element: @img) end end end @@ -58,22 +54,19 @@ def run if missing_alt_tag? && !ignore_missing_alt? add_failure( "image #{@img.url.raw_attribute} does not have an alt attribute", - line: @img.line, - content: @img.content, + element: @img, ) elsif (empty_alt_tag? || alt_all_spaces?) && !ignore_empty_alt? add_failure( "image #{@img.url.raw_attribute} has an alt attribute, but no content", - line: @img.line, - content: @img.content, + element: @img, ) end end add_failure( "image #{@img.url.raw_attribute} uses the http scheme", - line: @img.line, - content: @img.content, + element: @img, ) if @runner.enforce_https? && @img.url.http? end diff --git a/lib/html_proofer/check/links.rb b/lib/html_proofer/check/links.rb index ec72f001..3fc47ac0 100644 --- a/lib/html_proofer/check/links.rb +++ b/lib/html_proofer/check/links.rb @@ -10,7 +10,7 @@ def run next if @link.ignore? if !allow_hash_href? && @link.node["href"] == "#" - add_failure("linking to internal hash #, which points to nowhere", line: @link.line, content: @link.content) + add_failure("linking to internal hash #, which points to nowhere", element: @link) next end @@ -18,21 +18,20 @@ def run if blank?(@link.url.raw_attribute) next if allow_missing_href? - add_failure("'#{@link.node.name}' tag is missing a reference", line: @link.line, content: @link.content) + add_failure("'#{@link.node.name}' tag is missing a reference", element: @link) next end # is it even a valid URL? unless @link.url.valid? - add_failure("#{@link.href} is an invalid URL", line: @link.line, content: @link.content) + add_failure("#{@link.href} is an invalid URL", element: @link) next end if @link.url.protocol_relative? add_failure( "#{@link.url} is a protocol-relative URL, use explicit https:// instead", - line: @link.line, - content: @link.content, + element: @link, ) next end @@ -50,7 +49,7 @@ def run next if @link.node["rel"] == "dns-prefetch" unless @link.url.path? - add_failure("#{@link.url.raw_attribute} is an invalid URL", line: @link.line, content: @link.content) + add_failure("#{@link.url.raw_attribute} is an invalid URL", element: @link) next end @@ -60,8 +59,7 @@ def run if @link.url.unslashed_directory?(@link.url.absolute_path) add_failure( "internally linking to a directory #{@link.url.raw_attribute} without trailing slash", - line: @link.line, - content: @link.content, + element: @link, ) next end @@ -88,7 +86,7 @@ def check_schemes when "http" return unless @runner.options[:enforce_https] - add_failure("#{@link.url.raw_attribute} is not an HTTPS link", line: @link.line, content: @link.content) + add_failure("#{@link.url.raw_attribute} is not an HTTPS link", element: @link) end end @@ -96,14 +94,12 @@ def handle_mailto if @link.url.path.empty? add_failure( "#{@link.url.raw_attribute} contains no email address", - line: @link.line, - content: @link.content, + element: @link, ) unless ignore_empty_mailto? elsif !/#{URI::MailTo::EMAIL_REGEXP}/o.match?(@link.url.path) add_failure( "#{@link.url.raw_attribute} contains an invalid email address", - line: @link.line, - content: @link.content, + element: @link, ) end end @@ -111,8 +107,7 @@ def handle_mailto def handle_tel add_failure( "#{@link.url.raw_attribute} contains no phone number", - line: @link.line, - content: @link.content, + element: @link, ) if @link.url.path.empty? end @@ -130,16 +125,14 @@ def check_sri if blank?(@link.node["integrity"]) && blank?(@link.node["crossorigin"]) add_failure( "SRI and CORS not provided in: #{@link.url.raw_attribute}", - line: @link.line, - content: @link.content, + element: @link, ) elsif blank?(@link.node["integrity"]) - add_failure("Integrity is missing in: #{@link.url.raw_attribute}", line: @link.line, content: @link.content) + add_failure("Integrity is missing in: #{@link.url.raw_attribute}", element: @link) elsif blank?(@link.node["crossorigin"]) add_failure( "CORS not provided for external resource in: #{@link.link.url.raw_attribute}", - line: @link.line, - content: @link.content, + element: @link, ) end end diff --git a/lib/html_proofer/check/open_graph.rb b/lib/html_proofer/check/open_graph.rb index fd32aef2..3f10ee67 100644 --- a/lib/html_proofer/check/open_graph.rb +++ b/lib/html_proofer/check/open_graph.rb @@ -11,24 +11,22 @@ def run # does the open_graph exist? if missing_content? - add_failure("open graph has no content attribute", line: @open_graph.line, content: @open_graph.content) + add_failure("open graph has no content attribute", element: @open_graph) elsif empty_content? - add_failure("open graph content attribute is empty", line: @open_graph.line, content: @open_graph.content) + add_failure("open graph content attribute is empty", element: @open_graph) elsif !@open_graph.url.valid? - add_failure("#{@open_graph.src} is an invalid URL", line: @open_graph.line) + add_failure("#{@open_graph.src} is an invalid URL", element: @open_graph) elsif @open_graph.url.protocol_relative? add_failure( "open graph link #{@open_graph.url} is a protocol-relative URL, use explicit https:// instead", - line: @open_graph.line, - content: @open_graph.content, + element: @open_graph, ) elsif @open_graph.url.remote? add_to_external_urls(@open_graph.url, @open_graph.line) else add_failure( "internal open graph #{@open_graph.url.raw_attribute} does not exist", - line: @open_graph.line, - content: @open_graph.content, + element: @open_graph, ) unless @open_graph.url.exists? end end diff --git a/lib/html_proofer/check/scripts.rb b/lib/html_proofer/check/scripts.rb index d07999fc..f80e20f8 100644 --- a/lib/html_proofer/check/scripts.rb +++ b/lib/html_proofer/check/scripts.rb @@ -12,12 +12,11 @@ def run # does the script exist? if missing_src? - add_failure("script is empty and has no src attribute", line: @script.line, content: @script.content) + add_failure("script is empty and has no src attribute", element: @script) elsif @script.url.protocol_relative? add_failure( "script link #{@script.url} is a protocol-relative URL, use explicit https:// instead", - line: @script.line, - content: @script.content, + element: @script, ) elsif @script.url.remote? add_to_external_urls(@script.url, @script.line) @@ -25,8 +24,7 @@ def run elsif !@script.url.exists? add_failure( "internal script reference #{@script.src} does not exist", - line: @script.line, - content: @script.content, + element: @script, ) end end @@ -42,20 +40,17 @@ def check_sri if blank?(@script.node["integrity"]) && blank?(@script.node["crossorigin"]) add_failure( "SRI and CORS not provided in: #{@script.url.raw_attribute}", - line: @script.line, - content: @script.content, + element: @script, ) elsif blank?(@script.node["integrity"]) add_failure( "Integrity is missing in: #{@script.url.raw_attribute}", - line: @script.line, - content: @script.content, + element: @script, ) elsif blank?(@script.node["crossorigin"]) add_failure( "CORS not provided for external resource in: #{@script.url.raw_attribute}", - line: @script.line, - content: @script.content, + element: @script, ) end end diff --git a/spec/html-proofer/check_spec.rb b/spec/html-proofer/check_spec.rb index 311077a4..09a348fb 100644 --- a/spec/html-proofer/check_spec.rb +++ b/spec/html-proofer/check_spec.rb @@ -13,7 +13,7 @@ def run next if @link.ignore? - return add_failure("Don't email the Octocat directly!", line: @link.line) if mailto_octocat? + return add_failure("Don't email the Octocat directly!", element: @link) if mailto_octocat? end end end From 4f5d22714c51596f5bea2471ed82c67dc2026b10 Mon Sep 17 00:00:00 2001 From: Riccardo Porreca Date: Thu, 9 Mar 2023 18:16:04 +0100 Subject: [PATCH 30/78] Align "Custom tests" example to the current functionality / code style * Example code as in the `check_spec.rb`. --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 7d0a5f64..7e6ed6e4 100644 --- a/README.md +++ b/README.md @@ -422,23 +422,23 @@ Want to write your own test? Sure, that's possible! Just create a class that inherits from `HTMLProofer::Check`. This subclass must define one method called `run`. This is called on your content, and is responsible for performing the validation on whatever elements you like. When you catch a broken issue, call `add_failure(message, line: line, content: content)` to explain the error. `line` refers to the line numbers, and `content` is the node content of the broken element. -If you're working with the element's attributes (as most checks do), you'll also want to call `create_element(node)` as part of your suite. This constructs an object that contains all the attributes of the HTML element you're iterating on. +If you're working with the element's attributes (as most checks do), you'll also want to call `create_element(node)` as part of your suite. This constructs an object that contains all the attributes of the HTML element you're iterating on, and can also be used directly to call `add_failure(message, element: element)`. Here's an example custom test demonstrating these concepts. It reports `mailto` links that point to `octocat@github.com`: ``` ruby -class MailToOctocat < ::HTMLProofer::Check +class MailToOctocat < HTMLProofer::Check def mailto_octocat? - @link.url.raw_attribute == 'mailto:octocat@github.com' + @link.url.raw_attribute == "mailto:octocat@github.com" end def run - @html.css('a').each do |node| + @html.css("a").each do |node| @link = create_element(node) next if @link.ignore? - return add_failure("Don't email the Octocat directly!", line: @link.line) if mailto_octocat? + return add_failure("Don't email the Octocat directly!", element: @link) if mailto_octocat? end end end @@ -448,7 +448,7 @@ Don't forget to include this new check in HTMLProofer's options, for example: ```ruby # removes default checks and just runs this one -HTMLProofer.check_directories(["out/"], {checks: ['MailToOctocat']}) +HTMLProofer.check_directories(["out/"], { checks: ["MailToOctocat"] }) ``` See our [list of third-party custom classes](https://github.com/gjtorikian/html-proofer/wiki/Extensions-(custom-classes)) and add your own to this list. From b4c76f73971248f4932e41311827e992a7e7fd9a Mon Sep 17 00:00:00 2001 From: Riccardo Porreca Date: Thu, 9 Mar 2023 18:40:11 +0100 Subject: [PATCH 31/78] Lint Ruby code chunks in README.md * Using `rubocop-md` --- README.md | 82 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 43 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index 7e6ed6e4..a5848ce8 100644 --- a/README.md +++ b/README.md @@ -88,26 +88,26 @@ It can also run through the command-line. Here's an example: ```ruby -require 'html-proofer' -require 'html/pipeline' -require 'find' +require "html-proofer" +require "html/pipeline" +require "find" # make an out dir Dir.mkdir("out") unless File.exist?("out") -pipeline = HTML::Pipeline.new [ +pipeline = HTML::Pipeline.new([ HTML::Pipeline::MarkdownFilter, - HTML::Pipeline::TableOfContentsFilter -], gfm: true + HTML::Pipeline::TableOfContentsFilter, +], +gfm: true) # iterate over files, and generate HTML from Markdown Find.find("./docs") do |path| - if File.extname(path) == ".md" - contents = File.read(path) - result = pipeline.call(contents) + next unless File.extname(path) == ".md" + contents = File.read(path) + result = pipeline.call(contents) - File.open("out/#{path.split("/").pop.sub('.md', '.html')}", 'w') { |file| file.write(result[:output].to_s) } - end + File.open("out/#{path.split("/").pop.sub(".md", ".html")}", "w") { |file| file.write(result[:output].to_s) } end # test your out dir! @@ -119,7 +119,7 @@ HTMLProofer.check_directory("./out").run If you simply want to check a single file, use the `check_file` method: ``` ruby -HTMLProofer.check_file('/path/to/a/file.html').run +HTMLProofer.check_file("/path/to/a/file.html").run ``` ### Checking directories @@ -127,13 +127,13 @@ HTMLProofer.check_file('/path/to/a/file.html').run If you want to check a directory, use `check_directory`: ``` ruby -HTMLProofer.check_directory('./out').run +HTMLProofer.check_directory("./out").run ``` If you want to check multiple directories, use `check_directories`: ``` ruby -HTMLProofer.check_directories(['./one', './two']).run +HTMLProofer.check_directories(["./one", "./two"]).run ``` ### Checking an array of links @@ -141,7 +141,7 @@ HTMLProofer.check_directories(['./one', './two']).run With `check_links`, you can also pass in an array of links: ``` ruby -HTMLProofer.check_links(['https://github.com', 'https://jekyllrb.com']).run +HTMLProofer.check_links(["https://github.com", "https://jekyllrb.com"]).run ``` ### Swapping information @@ -149,7 +149,7 @@ HTMLProofer.check_links(['https://github.com', 'https://jekyllrb.com']).run Sometimes, the information in your HTML is not the same as how your server serves content. In these cases, you can use `swap_urls` to map the URL in a file to the URL you'd like it to become. For example: ```ruby -run_proofer(file, :file, swap_urls: { %r{^https//placeholder.com}: 'https://website.com' }) +run_proofer(file, :file, swap_urls: { %r{^https//placeholder.com} => "https://website.com" }) ``` In this case, any link that matches the `^https://placeholder.com` will be converted to `https://website.com`. @@ -157,7 +157,7 @@ In this case, any link that matches the `^https://placeholder.com` will be conve A similar swapping process can be done for attributes: ```ruby -run_proofer(file, :file, swap_attributes: { 'img': [['data-src', 'src']] }) +run_proofer(file, :file, swap_attributes: { "img": [["data-src", "src"]] }) ``` In this case, we are telling HTMLProofer that, for any `img` tag detected, for any `src` attribute, pretend it's actually the `src` attribute instead. Since the value is an array of arrays, you can pass in as many attribute swaps as you need for each element. @@ -216,7 +216,7 @@ htmlproofer --assume-extension ./_site --swap-urls '^/BASEURL/:/' or in your `Rakefile` ```ruby -require 'html-proofer' +require "html-proofer" task :test do sh "bundle exec jekyll build" @@ -251,15 +251,16 @@ This can also apply to parent elements, all the way up to the `` tag: Say you've got some new files in a pull request, and your tests are failing because links to those files are not live yet. One thing you can do is run a diff against your base branch and explicitly ignore the new files, like this: ```ruby - directories = %w(content) - merge_base = `git merge-base origin/production HEAD`.chomp - diffable_files = `git diff -z --name-only --diff-filter=AC #{merge_base}`.split("\0") - diffable_files = diffable_files.select do |filename| - next true if directories.include?(File.dirname(filename)) - filename.end_with?('.md') - end.map { |f| Regexp.new(File.basename(f, File.extname(f))) } +directories = ['content'] +merge_base = %x(git merge-base origin/production HEAD).chomp +diffable_files = %x(git diff -z --name-only --diff-filter=AC #{merge_base}).split("\0") +diffable_files = diffable_files.select do |filename| + next true if directories.include?(File.dirname(filename)) + + filename.end_with?(".md") +end.map { |f| Regexp.new(File.basename(f, File.extname(f))) } - HTMLProofer.check_directory('./output', { ignore_urls: diffable_files }).run +HTMLProofer.check_directory("./output", { ignore_urls: diffable_files }).run ``` ## Configuration @@ -301,7 +302,7 @@ In addition, there are a few "namespaced" options. These are: [Typhoeus](https://github.com/typhoeus/typhoeus) is used to make fast, parallel requests to external URLs. You can pass in any of Typhoeus' options for the external link checks with the options namespace of `:typhoeus`. For example: ``` ruby -HTMLProofer.new("out/", {extensions: [".htm"], typhoeus: { verbose: true, ssl_verifyhost: 2 } }) +HTMLProofer.new("out/", { extensions: [".htm"], typhoeus: { verbose: true, ssl_verifyhost: 2 } }) ``` This sets `HTMLProofer`'s extensions to use _.htm_, gives Typhoeus a configuration for it to be verbose, and use specific SSL settings. Check the [Typhoeus documentation](https://github.com/typhoeus/typhoeus#other-curl-options) for more information on what options it can receive. @@ -316,9 +317,9 @@ The default value is: { followlocation: true, connecttimeout: 10, - timeout: 30 + timeout: 30, }, - hydra: { max_concurrency: 50 } + hydra: { max_concurrency: 50 }, } ``` @@ -331,7 +332,7 @@ You can provide a block to set some logic before an external link is checked. Fo ```ruby proofer = HTMLProofer.check_directory(item, opts) proofer.before_request do |request| - request.options[:headers]['Authorization'] = "Bearer " if request.base_url == "https://github.com" + request.options[:headers]["Authorization"] = "Bearer " if request.base_url == "https://github.com" end proofer.run ``` @@ -352,25 +353,25 @@ You can enable caching for this by passing in the configuration option `:cache`, For example, passing the following options means "recheck external links older than thirty days": ``` ruby -{ cache: { timeframe: { external: '30d' } } } +{ cache: { timeframe: { external: "30d" } } } ``` And the following options means "recheck internal links older than two weeks": ``` ruby -{ cache: { timeframe: { internal: '2w' } } } +{ cache: { timeframe: { internal: "2w" } } } ``` Naturally, to support both internal and external link caching, both keys would need to be provided. The following checks external links every two weeks, but internal links only once a week: ``` ruby -{ cache: { timeframe: { external: '2w', internal: '1w' } } } +{ cache: { timeframe: { external: "2w", internal: "1w" } } } ``` You can change the filename or the directory where the cache file is kept by also providing the `storage_dir` key: ``` ruby -{ cache: { cache_file: 'stay_cachey.json', storage_dir: '/tmp/html-proofer-cache-money' } } +{ cache: { cache_file: "stay_cachey.json", storage_dir: "/tmp/html-proofer-cache-money" } } ``` Links that were failures are kept in the cache and *always* rechecked. If they pass, the cache is updated to note the new timestamp. @@ -479,7 +480,8 @@ To ignore SSL certificates, turn off Typhoeus' SSL verification: HTMLProofer.check_directory("out/", { typhoeus: { ssl_verifypeer: false, - ssl_verifyhost: 0} + ssl_verifyhost: 0, +}, }).run ``` @@ -490,8 +492,9 @@ To change the User-Agent used by Typhoeus: ``` ruby HTMLProofer.check_directory("out/", { typhoeus: { - headers: { "User-Agent" => "Mozilla/5.0 (compatible; My New User-Agent)" } -}}).run + headers: { "User-Agent" => "Mozilla/5.0 (compatible; My New User-Agent)" }, + } +}).run ``` Alternatively, you can specifify these options on the commandline with: @@ -508,8 +511,9 @@ Sometimes links fail because they don't have access to cookies. To fix this you HTMLProofer.check_directory("out/", { typhoeus: { cookiefile: ".cookies", - cookiejar: ".cookies" -}}).run + cookiejar: ".cookies", + } +}).run ``` ```bash From e0e01702ad2bc34d3de41bb71667ef8553721946 Mon Sep 17 00:00:00 2001 From: Riccardo Porreca Date: Fri, 10 Mar 2023 11:16:23 +0100 Subject: [PATCH 32/78] Simplify relative link logic, removing unnecessary code * Most of the logic is legacy from the very early HTMLProofer, and is irrelevant not since `@filename` can only be the file where the link is defined, with `File.join` properly handling both same-directory, nested, and parent links, together with the ultimate `File.expand_path` in `absolute_path. * The legacy logic comes pretty much from #6 and #23. * This way we can also avoid `File.exist`, which can ultimately be delegated to checking the existence, not constructing the path. --- lib/html_proofer/attribute/url.rb | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/lib/html_proofer/attribute/url.rb b/lib/html_proofer/attribute/url.rb index 7507413a..59a76cac 100644 --- a/lib/html_proofer/attribute/url.rb +++ b/lib/html_proofer/attribute/url.rb @@ -136,28 +136,12 @@ def absolute_path def file_path return if path.nil? || path.empty? - path_dot_ext = "" - - path_dot_ext = path + @runner.options[:assume_extension] unless blank?(@runner.options[:assume_extension]) - base = if absolute_path?(path) # path relative to root # either overwrite with root_dir; or, if source is directory, use that; or, just get the current file's dirname @runner.options[:root_dir] || (File.directory?(@source) ? @source : File.dirname(@source)) # relative links, path is a file - elsif File.exist?(File.expand_path( - path, - @source, - )) || File.exist?(File.expand_path(path_dot_ext, @source)) - File.dirname(@filename) - # relative links in nested dir, path is a file - elsif File.exist?(File.join( - File.dirname(@filename), - path, - )) || File.exist?(File.join(File.dirname(@filename), path_dot_ext)) - File.dirname(@filename) - # relative link, path is a directory else - @filename + File.dirname(@filename) end file = File.join(base, path) From d52d82844f382e81290630a502d9a45df43c5e71 Mon Sep 17 00:00:00 2001 From: Riccardo Porreca Date: Fri, 10 Mar 2023 11:34:42 +0100 Subject: [PATCH 33/78] Refactor internal link paths resolution / existence check * We now construct and maintain a hash of resolved paths, as a way to have a single instance of going through OS for checking the existence of alternative resolved paths, including assumed extension and directory index file. --- lib/html_proofer/attribute/url.rb | 38 ++++++++++++++-------- lib/html_proofer/runner.rb | 4 +-- lib/html_proofer/url_validator/internal.rb | 10 ++---- 3 files changed, 29 insertions(+), 23 deletions(-) diff --git a/lib/html_proofer/attribute/url.rb b/lib/html_proofer/attribute/url.rb index 59a76cac..68d2d221 100644 --- a/lib/html_proofer/attribute/url.rb +++ b/lib/html_proofer/attribute/url.rb @@ -118,9 +118,29 @@ def query_values def exists? return true if base64? - return @runner.checked_paths[absolute_path] if @runner.checked_paths.key?(absolute_path) + !resolved_path.nil? + end + + def resolved_path + path_to_resolve = absolute_path + + return @runner.resolved_paths[path_to_resolve] if @runner.resolved_paths.key?(path_to_resolve) + + # extensionless URLs + path_with_extension = "#{path_to_resolve}#{@runner.options[:assume_extension]}" + resolved = if @runner.options[:assume_extension] && File.file?(path_with_extension) + path_with_extension # existence checked implicitly by File.file? + # implicit index support + elsif File.directory?(path_to_resolve) && !unslashed_directory?(path_to_resolve) + path_with_index = File.join(path_to_resolve, @runner.options[:directory_index_file]) + path_with_index if File.file?(path_with_index) + # explicit file or directory + elsif File.exist?(path_to_resolve) + path_to_resolve + end + @runner.resolved_paths[path_to_resolve] = resolved - @runner.checked_paths[absolute_path] = File.exist?(absolute_path) + resolved end def base64? @@ -128,12 +148,12 @@ def base64? end def absolute_path - path = file_path || @filename + path = resolve_path || @filename File.expand_path(path, Dir.pwd) end - def file_path + def resolve_path return if path.nil? || path.empty? base = if absolute_path?(path) # path relative to root @@ -144,15 +164,7 @@ def file_path File.dirname(@filename) end - file = File.join(base, path) - - if @runner.options[:assume_extension] && File.file?("#{file}#{@runner.options[:assume_extension]}") - file = "#{file}#{@runner.options[:assume_extension]}" - elsif File.directory?(file) && !unslashed_directory?(file) # implicit index support - file = File.join(file, @runner.options[:directory_index_file]) - end - - file + File.join(base, path) end def unslashed_directory?(file) diff --git a/lib/html_proofer/runner.rb b/lib/html_proofer/runner.rb index ce5040f4..36330775 100644 --- a/lib/html_proofer/runner.rb +++ b/lib/html_proofer/runner.rb @@ -6,7 +6,7 @@ module HTMLProofer class Runner include HTMLProofer::Utils - attr_reader :options, :cache, :logger, :internal_urls, :external_urls, :checked_paths, :current_check + attr_reader :options, :cache, :logger, :internal_urls, :external_urls, :resolved_paths, :current_check attr_accessor :current_filename, :current_source, :reporter URL_TYPES = [:external, :internal].freeze @@ -26,7 +26,7 @@ def initialize(src, opts = {}) @before_request = [] - @checked_paths = {} + @resolved_paths = {} @current_check = nil @current_source = nil diff --git a/lib/html_proofer/url_validator/internal.rb b/lib/html_proofer/url_validator/internal.rb index daec0b03..7527ba8e 100644 --- a/lib/html_proofer/url_validator/internal.rb +++ b/lib/html_proofer/url_validator/internal.rb @@ -31,8 +31,7 @@ def run_internal_link_checker(links) matched_files.each do |metadata| url = HTMLProofer::Attribute::Url.new(@runner, link, base_url: metadata[:base_url], source: metadata[:source], filename: metadata[:filename]) - target_file_path = url.absolute_path - unless file_exists?(target_file_path) + unless url.exists? @failed_checks << Failure.new( metadata[:filename], "Links > Internal", @@ -48,6 +47,7 @@ def run_internal_link_checker(links) hash_exists = hash_exists_for_url?(url) if hash_exists.nil? # the hash needs to be checked in the target file, we collect the url and metadata + target_file_path = url.resolved_path unless file_paths_hashes_to_check.key?(target_file_path) file_paths_hashes_to_check[target_file_path] = {} end @@ -106,12 +106,6 @@ def run_internal_link_checker(links) @failed_checks end - private def file_exists?(absolute_path) - return @runner.checked_paths[absolute_path] if @runner.checked_paths.key?(absolute_path) - - @runner.checked_paths[absolute_path] = File.exist?(absolute_path) - end - # verify the hash w/o just based on the URL, w/o looking at the target file # => returns nil if the has could not be verified private def hash_exists_for_url?(url) From 6913d4efb3577ad318b8392a48bb9609cbb7b004 Mon Sep 17 00:00:00 2001 From: Riccardo Porreca Date: Tue, 14 Mar 2023 23:10:28 +0100 Subject: [PATCH 34/78] Rename handling of internal full path construction * To not clash / be confusing with `resolved_path`. --- lib/html_proofer/attribute/url.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/html_proofer/attribute/url.rb b/lib/html_proofer/attribute/url.rb index 68d2d221..5b2fd004 100644 --- a/lib/html_proofer/attribute/url.rb +++ b/lib/html_proofer/attribute/url.rb @@ -148,12 +148,12 @@ def base64? end def absolute_path - path = resolve_path || @filename + path = full_path || @filename File.expand_path(path, Dir.pwd) end - def resolve_path + def full_path return if path.nil? || path.empty? base = if absolute_path?(path) # path relative to root From aba17cc6b7aade4936a522f73293602619bcb65d Mon Sep 17 00:00:00 2001 From: Riccardo Porreca Date: Tue, 14 Mar 2023 23:11:27 +0100 Subject: [PATCH 35/78] Fix inline comments for full internal path construction --- lib/html_proofer/attribute/url.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/html_proofer/attribute/url.rb b/lib/html_proofer/attribute/url.rb index 5b2fd004..5c5c59f3 100644 --- a/lib/html_proofer/attribute/url.rb +++ b/lib/html_proofer/attribute/url.rb @@ -157,10 +157,10 @@ def full_path return if path.nil? || path.empty? base = if absolute_path?(path) # path relative to root - # either overwrite with root_dir; or, if source is directory, use that; or, just get the current file's dirname + # either overwrite with root_dir; or, if source is directory, use that; or, just get the source file's dirname @runner.options[:root_dir] || (File.directory?(@source) ? @source : File.dirname(@source)) - # relative links, path is a file else + # path relative to the file where the link is defined File.dirname(@filename) end From 3d6df6e31f32c0603df023b74a97e61162fcf7d3 Mon Sep 17 00:00:00 2001 From: Riccardo Porreca Date: Wed, 15 Mar 2023 09:08:57 +0100 Subject: [PATCH 36/78] Read-only `current_filename`/`_source` attributes in `Runner` --- lib/html_proofer/runner.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/html_proofer/runner.rb b/lib/html_proofer/runner.rb index 36330775..05b2a8d9 100644 --- a/lib/html_proofer/runner.rb +++ b/lib/html_proofer/runner.rb @@ -6,8 +6,8 @@ module HTMLProofer class Runner include HTMLProofer::Utils - attr_reader :options, :cache, :logger, :internal_urls, :external_urls, :resolved_paths, :current_check - attr_accessor :current_filename, :current_source, :reporter + attr_reader :options, :cache, :logger, :internal_urls, :external_urls, :resolved_paths, :current_check, :current_filename, :current_source + attr_accessor :reporter URL_TYPES = [:external, :internal].freeze From 27bf3eedae9c41f2584b927573a9b1480163094a Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Wed, 15 Mar 2023 13:43:00 -0400 Subject: [PATCH 37/78] :gem: bump to 5.0.6 --- lib/html_proofer/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/html_proofer/version.rb b/lib/html_proofer/version.rb index 6954358c..e07675f5 100644 --- a/lib/html_proofer/version.rb +++ b/lib/html_proofer/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module HTMLProofer - VERSION = "5.0.5" + VERSION = "5.0.6" end From bcc4bac5631ee5b3df9b95bb83efcb714fe8008e Mon Sep 17 00:00:00 2001 From: Actions Auto Build Date: Wed, 15 Mar 2023 18:46:17 +0000 Subject: [PATCH 38/78] docs: update changelog --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 26b5f1a7..1c560964 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [v5.0.6](https://github.com/gjtorikian/html-proofer/tree/v5.0.6) (2023-03-15) + +[Full Changelog](https://github.com/gjtorikian/html-proofer/compare/v5.0.5...v5.0.6) + +**Merged pull requests:** + +- Refactor/simplify internal link check resolution [\#795](https://github.com/gjtorikian/html-proofer/pull/795) ([riccardoporreca](https://github.com/riccardoporreca)) + ## [v5.0.5](https://github.com/gjtorikian/html-proofer/tree/v5.0.5) (2023-03-07) [Full Changelog](https://github.com/gjtorikian/html-proofer/compare/v5.0.4...v5.0.5) From 0e3d8815b444c4a8eaed411b1a8628dd97134aa9 Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Tue, 18 Apr 2023 12:17:23 -0500 Subject: [PATCH 39/78] Support multiple email addresses in `mailto` --- lib/html_proofer/check/links.rb | 3 ++- spec/html-proofer/fixtures/links/multiple_mailto_links.html | 5 +++++ spec/html-proofer/links_spec.rb | 6 ++++++ 3 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 spec/html-proofer/fixtures/links/multiple_mailto_links.html diff --git a/lib/html_proofer/check/links.rb b/lib/html_proofer/check/links.rb index 3fc47ac0..ad0199bd 100644 --- a/lib/html_proofer/check/links.rb +++ b/lib/html_proofer/check/links.rb @@ -96,7 +96,8 @@ def handle_mailto "#{@link.url.raw_attribute} contains no email address", element: @link, ) unless ignore_empty_mailto? - elsif !/#{URI::MailTo::EMAIL_REGEXP}/o.match?(@link.url.path) + # eg., if any do not match a valid URL + elsif @link.url.path.split(",").any? { |email| !/#{URI::MailTo::EMAIL_REGEXP}/o.match?(email) } add_failure( "#{@link.url.raw_attribute} contains an invalid email address", element: @link, diff --git a/spec/html-proofer/fixtures/links/multiple_mailto_links.html b/spec/html-proofer/fixtures/links/multiple_mailto_links.html new file mode 100644 index 00000000..58e826f5 --- /dev/null +++ b/spec/html-proofer/fixtures/links/multiple_mailto_links.html @@ -0,0 +1,5 @@ + + + Mail me. + + diff --git a/spec/html-proofer/links_spec.rb b/spec/html-proofer/links_spec.rb index 2b5a784a..c641323a 100644 --- a/spec/html-proofer/links_spec.rb +++ b/spec/html-proofer/links_spec.rb @@ -246,6 +246,12 @@ expect(proofer.failed_checks).to(eq([])) end + it "accepts multiple mailto links" do + ignorable_links = File.join(FIXTURES_DIR, "links", "multiple_mailto_links.html") + proofer = run_proofer(ignorable_links, :file) + expect(proofer.failed_checks).to(eq([])) + end + it "ignores blank mailto links when configured to allow them" do blank_mail_to_link = File.join(FIXTURES_DIR, "links", "blank_mailto_link.html") proofer = run_proofer(blank_mail_to_link, :file, ignore_empty_mailto: true) From 1c517e0c22eb214077d65c0178a92b19364dc094 Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Tue, 18 Apr 2023 12:18:31 -0500 Subject: [PATCH 40/78] :gem: bump to 5.0.7 --- lib/html_proofer/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/html_proofer/version.rb b/lib/html_proofer/version.rb index e07675f5..3b61d363 100644 --- a/lib/html_proofer/version.rb +++ b/lib/html_proofer/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module HTMLProofer - VERSION = "5.0.6" + VERSION = "5.0.7" end From ad731806e9f63d3c222b7cfff6c7a6cc57f8782a Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Tue, 18 Apr 2023 12:19:43 -0500 Subject: [PATCH 41/78] lint --- Rakefile | 2 +- lib/html_proofer/log.rb | 4 ++-- lib/html_proofer/reporter.rb | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Rakefile b/Rakefile index 47ed6c01..336e1b29 100644 --- a/Rakefile +++ b/Rakefile @@ -23,7 +23,7 @@ task :proof_readme do require "html-proofer" require "redcarpet" - renderer = Redcarpet::Render::HTML.new(\ + renderer = Redcarpet::Render::HTML.new( with_toc_data: true, ) redcarpet = Redcarpet::Markdown.new(renderer) diff --git a/lib/html_proofer/log.rb b/lib/html_proofer/log.rb index b29d0b6f..f4e91d38 100644 --- a/lib/html_proofer/log.rb +++ b/lib/html_proofer/log.rb @@ -12,7 +12,7 @@ class Log def initialize(log_level) @logger = Yell.new( - format: false, \ + format: false, name: "HTMLProofer", \ level: "gte.#{log_level}", ) do |l| @@ -41,7 +41,7 @@ def colorize(level, message) :red end - if (STDOUT_LEVELS.include?(level) && $stdout.isatty) || \ + if (STDOUT_LEVELS.include?(level) && $stdout.isatty) || (STDERR_LEVELS.include?(level) && $stderr.isatty) Rainbow(message).send(color) else diff --git a/lib/html_proofer/reporter.rb b/lib/html_proofer/reporter.rb index a75a3e0c..3474fcb1 100644 --- a/lib/html_proofer/reporter.rb +++ b/lib/html_proofer/reporter.rb @@ -11,8 +11,8 @@ def initialize(logger: nil) end def failures=(failures) - @failures = failures.group_by(&:check_name) \ - .transform_values { |issues| issues.sort_by { |issue| [issue.path, issue.line] } } \ + @failures = failures.group_by(&:check_name) + .transform_values { |issues| issues.sort_by { |issue| [issue.path, issue.line] } } .sort end From a52f207ea98c5eec9dcd4eb6f03c1c3ec42f970e Mon Sep 17 00:00:00 2001 From: Actions Auto Build Date: Tue, 18 Apr 2023 18:21:41 +0000 Subject: [PATCH 42/78] docs: update changelog --- CHANGELOG.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c560964..1cdce112 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ # Changelog +## [Unreleased](https://github.com/gjtorikian/html-proofer/tree/HEAD) + +[Full Changelog](https://github.com/gjtorikian/html-proofer/compare/v5.0.7...HEAD) + +**Closed issues:** + +- Fails multi email mailto [\#796](https://github.com/gjtorikian/html-proofer/issues/796) + +## [v5.0.7](https://github.com/gjtorikian/html-proofer/tree/v5.0.7) (2023-04-18) + +[Full Changelog](https://github.com/gjtorikian/html-proofer/compare/v5.0.6...v5.0.7) + +**Merged pull requests:** + +- Support multiple email addresses in `mailto` [\#797](https://github.com/gjtorikian/html-proofer/pull/797) ([gjtorikian](https://github.com/gjtorikian)) + ## [v5.0.6](https://github.com/gjtorikian/html-proofer/tree/v5.0.6) (2023-03-15) [Full Changelog](https://github.com/gjtorikian/html-proofer/compare/v5.0.5...v5.0.6) From 758745fe429ef1a3e371092701fab3b510ad6601 Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Thu, 6 Jul 2023 11:42:00 -0400 Subject: [PATCH 43/78] the usual workflow updates --- .github/workflows/automerge.yml | 28 ++--------- .github/workflows/lint.yml | 14 +++--- .github/workflows/tag_and_release.yml | 69 ++++----------------------- .github/workflows/test.yml | 16 ++----- 4 files changed, 25 insertions(+), 102 deletions(-) diff --git a/.github/workflows/automerge.yml b/.github/workflows/automerge.yml index 4b61205e..5a719f85 100644 --- a/.github/workflows/automerge.yml +++ b/.github/workflows/automerge.yml @@ -1,6 +1,7 @@ -name: PR auto-{approve,merge} +name: "Bot auto-{approve,merge}" on: + workflow_dispatch: pull_request_target: permissions: @@ -9,26 +10,5 @@ permissions: jobs: dependabot: - name: Dependabot - runs-on: ubuntu-latest - - if: ${{ github.actor == 'dependabot[bot]' }} - steps: - - name: Fetch Dependabot metadata - id: dependabot-metadata - uses: dependabot/fetch-metadata@v1 - with: - github-token: "${{ secrets.GITHUB_TOKEN }}" - - - name: Approve Dependabot PR - if: ${{steps.dependabot-metadata.outputs.update-type != 'version-update:semver-major'}} - run: gh pr review --approve "$PR_URL" - env: - PR_URL: ${{github.event.pull_request.html_url}} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Merge Dependabot PR - run: gh pr merge --auto --squash "$PR_URL" - env: - PR_URL: ${{ github.event.pull_request.html_url }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: yettoapp/actions/.github/workflows/automerge_dependabot.yml@main + secrets: inherit diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index fceb2ae9..a1586b0e 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,23 +1,23 @@ -name: Lint +name: Linting on: pull_request: + paths: + - "**/*.rb" permissions: contents: read jobs: - test: + lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: ruby/setup-ruby@v1 + - name: Set up Ruby + uses: yettoapp/actions/setup-languages@main with: - ruby-version: 3.1 - bundler-cache: true - - - run: bundle install + ruby: true - name: Rubocop run: bundle exec rake rubocop diff --git a/.github/workflows/tag_and_release.yml b/.github/workflows/tag_and_release.yml index ace1bad5..5b45ffd2 100644 --- a/.github/workflows/tag_and_release.yml +++ b/.github/workflows/tag_and_release.yml @@ -1,4 +1,4 @@ -name: Tag and Release +name: Release on: workflow_dispatch: @@ -9,62 +9,11 @@ on: - "lib/html_proofer/version.rb" jobs: - release: - env: - GEM_NAME: html_proofer - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - GEM_HOST_API_KEY: ${{ secrets.RUBYGEMS_API_BOT_KEY }} - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - - name: Set up Ruby 3.1 - uses: ruby/setup-ruby@v1 - with: - ruby-version: 3.1 - bundler-cache: true - - - name: Configure Git - run: | - git config --local user.email "actions@github.com" - git config --local user.name "Actions Auto Build" - - - name: Get current version - id: version-label - run: | - VERSION=$(grep VERSION lib/html_proofer/version.rb | head -n 1 | cut -d'"' -f2) - echo "version=${VERSION}" >> $GITHUB_OUTPUT - - - name: Create tag - run: | - git tag -a v${{ steps.version-label.outputs.version }} -m "Release v${{ steps.version-label.outputs.version }}" - git push origin --tags - - - name: Generate CHANGELOG.md - id: changelog - run: script/generate_changelog - - - name: Commit & Push Changelog - run: | - git config --local user.email "actions@github.com" - git config --local user.name "Actions Auto Build" - git add -f CHANGELOG.md - git commit -m "docs: update changelog" || true - git push - - - name: Publish release - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - gh release create v${{ steps.version-label.outputs.version }} --generate-notes - - - name: Publish to RubyGems - run: | - mkdir -p $HOME/.gem - touch $HOME/.gem/credentials - chmod 0600 $HOME/.gem/credentials - printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials - bundle exec rake build - for gem in pkg/html-proofer-${{ steps.version-label.outputs.version }}*.gem ; do - gem push "$gem" --host https://rubygems.org - done + ruby: + uses: yettoapp/actions/.github/workflows/ruby_gem_release.yml@main + secrets: + rubygems_api_key: ${{ secrets.RUBYGEMS_API_BOT_KEY }} + gh_token: ${{ secrets.PUBLIC_PUSH_TO_PROTECTED_BRANCH }} + with: + gem_name: html_proofer + version_filepath: lib/html_proofer/version.rb diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f3ca3e6d..b0dbaf7a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,4 +1,4 @@ -name: Test +name: CI on: pull_request: @@ -8,21 +8,15 @@ permissions: jobs: test: - env: - NOKOGIRI_USE_SYSTEM_LIBRARIES: true runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Set up Ruby 3.1 - uses: ruby/setup-ruby@v1 + - name: Set up Ruby + uses: yettoapp/actions/setup-languages@main with: - ruby-version: 3.1 - bundler-cache: true - - - name: Install dependencies - run: bundle install + ruby: true - name: Run tests - run: bundle exec rake + run: bundle exec rake test From db0e1dc1ed0d4d19edf5b3fdbbfd80104c732df9 Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Thu, 6 Jul 2023 11:40:22 -0400 Subject: [PATCH 44/78] tweak debug tools --- Gemfile | 2 +- lib/html_proofer.rb | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index 0e90658d..bc7aa30a 100644 --- a/Gemfile +++ b/Gemfile @@ -8,7 +8,7 @@ gem "ruby-lsp", "~> 0.3.2", group: :development gem "github_changelog_generator", "~> 1.16" -gem "awesome_print" +gem "amazing_print" gem "debug" if "#{RbConfig::CONFIG["MAJOR"]}.#{RbConfig::CONFIG["MINOR"]}".to_f >= 3.1 gem "rake" diff --git a/lib/html_proofer.rb b/lib/html_proofer.rb index 73c25681..bfc3c9dd 100644 --- a/lib/html_proofer.rb +++ b/lib/html_proofer.rb @@ -15,8 +15,11 @@ require "fileutils" if ENV.fetch("DEBUG", false) - require "awesome_print" require "debug" + begin + require "amazing_print" + rescue LoadError # rubocop:disable Lint/SuppressedException + end end module HTMLProofer From 5bca8381f6ffaa5d69c015537902acba2a9875e0 Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Thu, 6 Jul 2023 12:03:15 -0400 Subject: [PATCH 45/78] add packaging task --- Rakefile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Rakefile b/Rakefile index 336e1b29..d54ecff8 100644 --- a/Rakefile +++ b/Rakefile @@ -35,3 +35,8 @@ task :proof_readme do opts = {} HTMLProofer.check_directory("./out", opts).run end + +GEMSPEC = Bundler.load_gemspec("html-proofer.gemspec") +gem_path = Gem::PackageTask.new(GEMSPEC).define +desc "Package the ruby gem" +task "package" => [gem_path] From 1d08f0da4015a31575f4e2892152071b0bd90979 Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Thu, 6 Jul 2023 11:44:18 -0400 Subject: [PATCH 46/78] add ruby version --- .ruby-version | 1 + 1 file changed, 1 insertion(+) create mode 100644 .ruby-version diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 00000000..e4604e3a --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +3.2.1 From f2938189c87c1797cce069ef965b515fde8eba21 Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Thu, 6 Jul 2023 11:40:30 -0400 Subject: [PATCH 47/78] :gem: 5.0.8 --- .github/workflows/tag_and_release.yml | 2 +- Rakefile | 2 ++ lib/html_proofer/version.rb | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tag_and_release.yml b/.github/workflows/tag_and_release.yml index 5b45ffd2..aff79e00 100644 --- a/.github/workflows/tag_and_release.yml +++ b/.github/workflows/tag_and_release.yml @@ -15,5 +15,5 @@ jobs: rubygems_api_key: ${{ secrets.RUBYGEMS_API_BOT_KEY }} gh_token: ${{ secrets.PUBLIC_PUSH_TO_PROTECTED_BRANCH }} with: - gem_name: html_proofer + gem_name: html-proofer version_filepath: lib/html_proofer/version.rb diff --git a/Rakefile b/Rakefile index d54ecff8..ad567be1 100644 --- a/Rakefile +++ b/Rakefile @@ -36,6 +36,8 @@ task :proof_readme do HTMLProofer.check_directory("./out", opts).run end +require "bundler/gem_tasks" +require "rubygems/package_task" GEMSPEC = Bundler.load_gemspec("html-proofer.gemspec") gem_path = Gem::PackageTask.new(GEMSPEC).define desc "Package the ruby gem" diff --git a/lib/html_proofer/version.rb b/lib/html_proofer/version.rb index 3b61d363..2b5ae8e2 100644 --- a/lib/html_proofer/version.rb +++ b/lib/html_proofer/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module HTMLProofer - VERSION = "5.0.7" + VERSION = "5.0.8" end From 3fdd5c97fc79da9e7fa91649f4da249b0f9e85c7 Mon Sep 17 00:00:00 2001 From: Actions Auto Build Date: Sun, 6 Aug 2023 23:29:32 +0000 Subject: [PATCH 48/78] [auto-docs][skip test]: update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1cdce112..ef78e870 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +## [v5.0.8] - 06-08-2023 +null # Changelog ## [Unreleased](https://github.com/gjtorikian/html-proofer/tree/HEAD) From 052343df8b995ab1d207ee493621daae1b3c68af Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Sep 2023 09:46:36 +0000 Subject: [PATCH 49/78] Bump actions/checkout from 3 to 4 Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/lint.yml | 2 +- .github/workflows/test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index a1586b0e..2497d80d 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -12,7 +12,7 @@ jobs: lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Ruby uses: yettoapp/actions/setup-languages@main diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b0dbaf7a..33435960 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Ruby uses: yettoapp/actions/setup-languages@main From b702494b3493806b6bd765d924c84c27c1f449f3 Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Fri, 26 Apr 2024 07:42:37 -0400 Subject: [PATCH 50/78] Let Rainbow handle color management --- lib/html_proofer/log.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/html_proofer/log.rb b/lib/html_proofer/log.rb index f4e91d38..f50a8235 100644 --- a/lib/html_proofer/log.rb +++ b/lib/html_proofer/log.rb @@ -41,8 +41,8 @@ def colorize(level, message) :red end - if (STDOUT_LEVELS.include?(level) && $stdout.isatty) || - (STDERR_LEVELS.include?(level) && $stderr.isatty) + if STDOUT_LEVELS.include?(level) || + STDERR_LEVELS.include?(level) Rainbow(message).send(color) else message From c02df610bb7604510050afc2ee2ef7446adb2927 Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Mon, 6 May 2024 10:37:43 -0700 Subject: [PATCH 51/78] lint --- lib/html_proofer/attribute/url.rb | 3 ++- lib/html_proofer/cache.rb | 7 ++++--- lib/html_proofer/configuration.rb | 4 ++-- lib/html_proofer/element.rb | 14 +++++++------- lib/html_proofer/runner.rb | 4 ++-- lib/html_proofer/url_validator/internal.rb | 4 +--- spec/html-proofer/attribute/url_spec.rb | 3 ++- spec/html-proofer/cache_spec.rb | 4 +++- spec/html-proofer/{ => check}/favicon_spec.rb | 2 +- spec/html-proofer/{ => check}/images_spec.rb | 2 +- spec/html-proofer/{ => check}/links_spec.rb | 2 +- .../open_graph_spec.rb} | 2 +- spec/html-proofer/{ => check}/scripts_spec.rb | 2 +- spec/html-proofer/check_spec.rb | 4 ++-- spec/html-proofer/{command_spec.rb => cli_spec.rb} | 10 +++++----- ...e_json_option_spec.rb => configuration_spec.rb} | 4 +++- spec/html-proofer/element_spec.rb | 3 ++- .../cache/version_2/.internal_and_external.json | 2 +- .../cache/version_2/.recheck_external_failure.json | 2 +- .../fixtures/cache/version_2/.removed_link.json | 2 +- .../fixtures/cache/version_2/.runner.json | 2 +- spec/html-proofer/maliciousness_spec.rb | 2 +- spec/html-proofer/proofer_spec.rb | 4 +++- .../terminal_spec.rb} | 2 +- spec/html-proofer/reporter_spec.rb | 2 +- spec/html-proofer/runner_spec.rb | 2 +- spec/html-proofer/utils_spec.rb | 4 ++-- 27 files changed, 53 insertions(+), 45 deletions(-) rename spec/html-proofer/{ => check}/favicon_spec.rb (98%) rename spec/html-proofer/{ => check}/images_spec.rb (99%) rename spec/html-proofer/{ => check}/links_spec.rb (99%) rename spec/html-proofer/{opengraph_spec.rb => check/open_graph_spec.rb} (98%) rename spec/html-proofer/{ => check}/scripts_spec.rb (98%) rename spec/html-proofer/{command_spec.rb => cli_spec.rb} (97%) rename spec/html-proofer/{parse_json_option_spec.rb => configuration_spec.rb} (96%) rename spec/html-proofer/{cli_reporter_spec.rb => reporter/terminal_spec.rb} (98%) diff --git a/lib/html_proofer/attribute/url.rb b/lib/html_proofer/attribute/url.rb index 5c5c59f3..edc26302 100644 --- a/lib/html_proofer/attribute/url.rb +++ b/lib/html_proofer/attribute/url.rb @@ -52,7 +52,8 @@ def unknown_extension? def ignore? return true if /^javascript:/.match?(@url) - return true if ignores_pattern?(@runner.options[:ignore_urls]) + + true if ignores_pattern?(@runner.options[:ignore_urls]) end def valid? diff --git a/lib/html_proofer/cache.rb b/lib/html_proofer/cache.rb index 92ae038c..ef0cf3c7 100644 --- a/lib/html_proofer/cache.rb +++ b/lib/html_proofer/cache.rb @@ -41,7 +41,7 @@ def initialize(runner, options) end def parsed_timeframe(timeframe) - return nil if timeframe.nil? + return if timeframe.nil? time, date = timeframe.match(/(\d+)(\D)/).captures time = time.to_i @@ -252,7 +252,7 @@ def size(type) SECONDS_PER_HOUR = 3600 SECONDS_PER_DAY = 86400 SECONDS_PER_WEEK = 604800 - SECONDS_PER_MONTH = 2629746 # 1/12 of a gregorian year + SECONDS_PER_MONTH = 2629746 # 1/12 of a gregorian year private def time_ago(measurement, unit) case unit @@ -269,7 +269,8 @@ def size(type) private def url_matches_type?(url, type) return true if type == :internal && url !~ URI_REGEXP - return true if type == :external && url =~ URI_REGEXP + + true if type == :external && url =~ URI_REGEXP end private def cleaned_url(url) diff --git a/lib/html_proofer/configuration.rb b/lib/html_proofer/configuration.rb index 88147a5c..58936306 100644 --- a/lib/html_proofer/configuration.rb +++ b/lib/html_proofer/configuration.rb @@ -233,8 +233,8 @@ def parse_cli_options(args) arg.split(",").each_with_object({}) do |s, hsh| split = s.split(/(?') From 4ab906c904ca002f6377ec1675af976f0a1550d2 Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Mon, 6 May 2024 10:58:32 -0700 Subject: [PATCH 52/78] update ruby --- .ruby-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ruby-version b/.ruby-version index e4604e3a..15a27998 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.2.1 +3.3.0 From b1af175034f3b1fcc5c60ab14d55044079da6523 Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Mon, 6 May 2024 15:10:52 -0700 Subject: [PATCH 53/78] Remove unnecessary regexp --- lib/html_proofer/attribute/url.rb | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/lib/html_proofer/attribute/url.rb b/lib/html_proofer/attribute/url.rb index edc26302..9d751f7c 100644 --- a/lib/html_proofer/attribute/url.rb +++ b/lib/html_proofer/attribute/url.rb @@ -221,11 +221,22 @@ def without_hash @url.to_s.sub(/##{hash}/, "") end - # catch any obvious issues, like strings in port numbers + # catch any obvious issues private def clean_url! - return if @url =~ /^([!#{Regexp.last_match(0)}-;=?-\[\]_a-z~]|%[0-9a-fA-F]{2})+$/ + parsed_url = Addressable::URI.parse(@url) + url = if parsed_url.scheme.nil? + parsed_url + else + parsed_url.normalize + end.to_s - @url = Addressable::URI.parse(@url).normalize.to_s + # normalize strips this off, which causes issues with cache + @url = if @url.end_with?("/") && !url.end_with?("/") + "#{url}/" + else + url + end + rescue Addressable::URI::InvalidURIError # rubocop:disable Lint/SuppressedException; error will be reported at check time end private def swap_urls! From f046f156a8d0b239f11a5fe7a274773b63aae799 Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Mon, 6 May 2024 15:17:19 -0700 Subject: [PATCH 54/78] this domain no longer exists! --- lib/html_proofer/attribute/url.rb | 2 + .../fixtures/links/unicode_domain.html | 2 +- ...domain_html_log_level_error_type_file_.yml | 58 ++++++++++--------- 3 files changed, 35 insertions(+), 27 deletions(-) diff --git a/lib/html_proofer/attribute/url.rb b/lib/html_proofer/attribute/url.rb index 9d751f7c..811517ec 100644 --- a/lib/html_proofer/attribute/url.rb +++ b/lib/html_proofer/attribute/url.rb @@ -233,6 +233,8 @@ def without_hash # normalize strips this off, which causes issues with cache @url = if @url.end_with?("/") && !url.end_with?("/") "#{url}/" + elsif !@url.end_with?("/") && url.end_with?("/") + url.chop else url end diff --git a/spec/html-proofer/fixtures/links/unicode_domain.html b/spec/html-proofer/fixtures/links/unicode_domain.html index 608bb04f..c7f5bcae 100644 --- a/spec/html-proofer/fixtures/links/unicode_domain.html +++ b/spec/html-proofer/fixtures/links/unicode_domain.html @@ -2,6 +2,6 @@ -

A real link

+

A real link

diff --git a/spec/html-proofer/fixtures/vcr_cassettes/links/unicode_domain_html_log_level_error_type_file_.yml b/spec/html-proofer/fixtures/vcr_cassettes/links/unicode_domain_html_log_level_error_type_file_.yml index 26cfc5e6..2bc6e344 100644 --- a/spec/html-proofer/fixtures/vcr_cassettes/links/unicode_domain_html_log_level_error_type_file_.yml +++ b/spec/html-proofer/fixtures/vcr_cassettes/links/unicode_domain_html_log_level_error_type_file_.yml @@ -2,13 +2,13 @@ http_interactions: - request: method: head - uri: https://xn--mxaaaiil1bdgepgr1bpt0d.gr/ + uri: https://xn--gran-8qa.fi body: encoding: US-ASCII string: '' headers: User-Agent: - - Mozilla/5.0 (compatible; HTML Proofer/3.19.3; +https://github.com/gjtorikian/html-proofer) + - Mozilla/5.0 (compatible; HTML Proofer/5.0.8; +https://github.com/gjtorikian/html-proofer) Accept: - application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 Expect: @@ -16,33 +16,39 @@ http_interactions: response: status: code: 200 - message: OK + message: '' headers: - Date: - - Fri, 31 Dec 2021 16:37:41 GMT - Content-Type: - - text/html; charset=UTF-8 - Connection: - - keep-alive - x-powered-by: - - PHP/8.0.13 - x-turbo-charged-by: - - LiteSpeed - CF-Cache-Status: - - DYNAMIC - Report-To: - - '{"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=vHwiFt05sw2oM%2BxOEY0YbwWDVJ7lNnaWzqt3YVttfW73qJj%2FOicx%2F2u6FF84ul4dFoAdtntXjMsZhHCWx2Q%2F2%2B842ECjjDJOLjPrkVdaHxBaMKnuzqJWI8j2aXzIKuRDADaWiYS6XcGYTXuEAXZg1g%3D%3D"}],"group":"cf-nel","max_age":604800}' - NEL: - - '{"success_fraction":0,"report_to":"cf-nel","max_age":604800}' - Server: - - cloudflare - CF-RAY: - - 6c64ef1218b18c4b-EWR + accept-ranges: + - bytes + access-control-allow-origin: + - "*" + age: + - '2084372' + cache-control: + - public, max-age=0, must-revalidate + content-disposition: + - inline + content-type: + - text/html; charset=utf-8 + date: + - Mon, 06 May 2024 22:16:55 GMT + etag: + - '"17bf20f1307387d12393425f77714bc2"' + server: + - Vercel + strict-transport-security: + - max-age=63072000 + x-vercel-cache: + - HIT + x-vercel-id: + - sfo1::jvrgm-1715033815794-3d4492f2b00f + content-length: + - '11213' body: encoding: ASCII-8BIT string: '' - http_version: '1.1' + http_version: '2' adapter_metadata: - effective_url: http://xn--mxaaaiil1bdgepgr1bpt0d.gr/ - recorded_at: Fri, 31 Dec 2021 16:37:41 GMT + effective_url: https://www.xn--gran-8qa.fi/ + recorded_at: Mon, 06 May 2024 22:16:55 GMT recorded_with: VCR 2.9.3 From d668ea389e3561c1080360c962f6f93484e0d4c0 Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Mon, 6 May 2024 15:19:43 -0700 Subject: [PATCH 55/78] Merge pull request #820 from gjtorikian/regexpiry Remove unnecessary regexp From 97ad85e1a6b81cd95e25b1c057c9427d0fb1f004 Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Mon, 6 May 2024 16:33:47 -0700 Subject: [PATCH 56/78] Merge pull request #818 from gjtorikian/color-in-non-tty Let Rainbow handle color management From baeeaf1f9acf09a43c3c0ea57456cd8aee129d36 Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Mon, 6 May 2024 16:22:32 -0700 Subject: [PATCH 57/78] provide new release workflow --- .github/workflows/tag_and_release.yml | 7 ++++++- script/generate_changelog | 3 --- 2 files changed, 6 insertions(+), 4 deletions(-) delete mode 100755 script/generate_changelog diff --git a/.github/workflows/tag_and_release.yml b/.github/workflows/tag_and_release.yml index aff79e00..ef485d96 100644 --- a/.github/workflows/tag_and_release.yml +++ b/.github/workflows/tag_and_release.yml @@ -7,13 +7,18 @@ on: - main paths: - "lib/html_proofer/version.rb" + pull_request_target: + types: + - closed jobs: ruby: uses: yettoapp/actions/.github/workflows/ruby_gem_release.yml@main secrets: rubygems_api_key: ${{ secrets.RUBYGEMS_API_BOT_KEY }} - gh_token: ${{ secrets.PUBLIC_PUSH_TO_PROTECTED_BRANCH }} + gh_token: ${{ secrets.GITHUB_TOKEN }} with: gem_name: html-proofer version_filepath: lib/html_proofer/version.rb + labeled: ${{ github.event == 'push' }} + release: ${{ github.event.pull_request.merged == true && contains(github.event.pull_request.title, 'Release:') }} diff --git a/script/generate_changelog b/script/generate_changelog deleted file mode 100755 index 9b23ea8d..00000000 --- a/script/generate_changelog +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -bundle exec github_changelog_generator --token $GITHUB_TOKEN -u gjtorikian -p html-proofer From 738ba70233e28a079cba4d1e265219e1e545ad3a Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Tue, 7 May 2024 13:26:03 -0700 Subject: [PATCH 58/78] permit manual triggers --- .github/workflows/tag_and_release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tag_and_release.yml b/.github/workflows/tag_and_release.yml index ef485d96..4d3954cf 100644 --- a/.github/workflows/tag_and_release.yml +++ b/.github/workflows/tag_and_release.yml @@ -20,5 +20,5 @@ jobs: with: gem_name: html-proofer version_filepath: lib/html_proofer/version.rb - labeled: ${{ github.event == 'push' }} - release: ${{ github.event.pull_request.merged == true && contains(github.event.pull_request.title, 'Release:') }} + prepare: ${{ github.event == 'push' || github.event == 'workflow_dispatch' }} + release: ${{ (github.event.pull_request.merged == true) && (contains(github.event.pull_request.labels.*.name, 'release')) }} From f808aa3ad0349cae7c6565ec01d41da03a1ab237 Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Tue, 7 May 2024 13:33:04 -0700 Subject: [PATCH 59/78] wrong name --- .github/workflows/tag_and_release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tag_and_release.yml b/.github/workflows/tag_and_release.yml index 4d3954cf..7bf8708e 100644 --- a/.github/workflows/tag_and_release.yml +++ b/.github/workflows/tag_and_release.yml @@ -20,5 +20,5 @@ jobs: with: gem_name: html-proofer version_filepath: lib/html_proofer/version.rb - prepare: ${{ github.event == 'push' || github.event == 'workflow_dispatch' }} + prepare: ${{ github.event_name == 'push' || github.event_name == 'workflow_dispatch' }} release: ${{ (github.event.pull_request.merged == true) && (contains(github.event.pull_request.labels.*.name, 'release')) }} From 60bee1ae25e734f75340afec6a62a29933c2a24a Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Tue, 7 May 2024 14:40:32 -0700 Subject: [PATCH 60/78] allow for skipped tests --- .github/workflows/test.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 33435960..4d69f2be 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,6 +11,13 @@ jobs: runs-on: ubuntu-latest steps: + - if: ${{ contains(github.event.pull_request.title, '[skip test]') }} + name: Skip test + shell: bash + run: | + echo "Skipping test workflow because commit message contains `[skip test]`" + exit 0 + - uses: actions/checkout@v4 - name: Set up Ruby From 164338b084166d84e2ed8a0f51275230e67a25b5 Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Tue, 7 May 2024 13:59:49 -0700 Subject: [PATCH 61/78] :gem: 5.0.9 --- lib/html_proofer/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/html_proofer/version.rb b/lib/html_proofer/version.rb index 2b5ae8e2..314269cd 100644 --- a/lib/html_proofer/version.rb +++ b/lib/html_proofer/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module HTMLProofer - VERSION = "5.0.8" + VERSION = "5.0.9" end From 3f4430f56742071f7bf18dfddc8167b5a32e79a3 Mon Sep 17 00:00:00 2001 From: gjtorikian <64050+gjtorikian@users.noreply.github.com> Date: Tue, 7 May 2024 22:22:12 +0000 Subject: [PATCH 62/78] [skip test] update changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ef78e870..431f797d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# [v5.0.9] - 07-05-2024\n +## What's Changed +* Bump actions/checkout from 3 to 4 by @dependabot in https://github.com/gjtorikian/html-proofer/pull/805 + + +**Full Changelog**: https://github.com/gjtorikian/html-proofer/compare/v5.0.8...v5.0.9 ## [v5.0.8] - 06-08-2023 null # Changelog From 67481b365a3c72439c953ee1295df14a5eadc38f Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Tue, 7 May 2024 15:25:26 -0700 Subject: [PATCH 63/78] add missing info --- CHANGELOG.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 431f797d..ef4f7fd6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,12 @@ -# [v5.0.9] - 07-05-2024\n +# [v5.0.9] - 07-05-2024 + ## What's Changed -* Bump actions/checkout from 3 to 4 by @dependabot in https://github.com/gjtorikian/html-proofer/pull/805 +- Bump actions/checkout from 3 to 4 by @dependabot in https://github.com/gjtorikian/html-proofer/pull/805 + +* Bump actions/checkout from 3 to 4 by @dependabot in https://github.com/gjtorikian/html-proofer/pull/805 +* Improved performance be removing unnecessary regexp (https://github.com/gjtorikian/html-proofer/pull/820) +* Improved color output https://github.com/gjtorikian/html-proofer/pull/818 **Full Changelog**: https://github.com/gjtorikian/html-proofer/compare/v5.0.8...v5.0.9 ## [v5.0.8] - 06-08-2023 From 7e854113162dfe2ca1aba1b1af1afe8516b6dc99 Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Tue, 7 May 2024 15:26:40 -0700 Subject: [PATCH 64/78] quote result --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4d69f2be..d9552cf8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - - if: ${{ contains(github.event.pull_request.title, '[skip test]') }} + - if: "${{ contains(github.event.pull_request.title, '[skip test]') }}" name: Skip test shell: bash run: | From ee2c50e89adb977d56eb919d6dff107ee60490db Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Wed, 8 May 2024 01:03:06 -0400 Subject: [PATCH 65/78] simplify --- .github/workflows/tag_and_release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tag_and_release.yml b/.github/workflows/tag_and_release.yml index 7bf8708e..51b673b7 100644 --- a/.github/workflows/tag_and_release.yml +++ b/.github/workflows/tag_and_release.yml @@ -20,5 +20,5 @@ jobs: with: gem_name: html-proofer version_filepath: lib/html_proofer/version.rb - prepare: ${{ github.event_name == 'push' || github.event_name == 'workflow_dispatch' }} - release: ${{ (github.event.pull_request.merged == true) && (contains(github.event.pull_request.labels.*.name, 'release')) }} + prepare: ${{ github.event_name == 'push' }} + release: ${{ github.event_name == 'workflow_dispatch' || ((github.event.pull_request.merged == true) && (contains(github.event.pull_request.labels.*.name, 'release'))) }} From cabd528f20d14c5a10c268f2ca39dc8404ae3029 Mon Sep 17 00:00:00 2001 From: Giovanni Toraldo <71768+gionn@users.noreply.github.com> Date: Mon, 13 May 2024 09:49:22 +0200 Subject: [PATCH 66/78] Fixup typhoeus arg usage in README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a5848ce8..071ee0d7 100644 --- a/README.md +++ b/README.md @@ -500,7 +500,7 @@ HTMLProofer.check_directory("out/", { Alternatively, you can specifify these options on the commandline with: ```bash -htmlproofer --typhoeus-config='{"headers":{"User-Agent":"Mozilla/5.0 (compatible; My New User-Agent)"}}' +htmlproofer --typhoeus='{"headers":{"User-Agent":"Mozilla/5.0 (compatible; My New User-Agent)"}}' ``` ### Cookies @@ -517,7 +517,7 @@ HTMLProofer.check_directory("out/", { ``` ```bash -htmlproofer --typhoeus-config='{"cookiefile":".cookies","cookiejar":".cookies"}' +htmlproofer --typhoeus='{"cookiefile":".cookies","cookiejar":".cookies"}' ``` ### Regular expressions From 3925d5384b065c9417a80cca238df2dc1d885fa4 Mon Sep 17 00:00:00 2001 From: Giovanni Toraldo <71768+gionn@users.noreply.github.com> Date: Mon, 13 May 2024 08:19:50 +0000 Subject: [PATCH 67/78] fix typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 071ee0d7..28fcd463 100644 --- a/README.md +++ b/README.md @@ -497,7 +497,7 @@ HTMLProofer.check_directory("out/", { }).run ``` -Alternatively, you can specifify these options on the commandline with: +Alternatively, you can specify these options on the command-line with: ```bash htmlproofer --typhoeus='{"headers":{"User-Agent":"Mozilla/5.0 (compatible; My New User-Agent)"}}' From 4958ecbc03660a269b346c9ebe7eec4b28b31f3e Mon Sep 17 00:00:00 2001 From: Eric Sorenson Date: Mon, 29 Apr 2024 18:39:18 -0700 Subject: [PATCH 68/78] Added test for UTF-8 encoded internal links There wasn't a specific test for this, and it fails on some setups. The link in the fixture is a direct copy-paste from one that fails on my project. But the test passes on this test suite... So there is something else going on. Relates to gjtorikian/html-proofer#757 --- spec/html-proofer/check/links_spec.rb | 6 ++++++ spec/html-proofer/fixtures/links/hash_nonascii.html | 8 ++++++++ 2 files changed, 14 insertions(+) create mode 100644 spec/html-proofer/fixtures/links/hash_nonascii.html diff --git a/spec/html-proofer/check/links_spec.rb b/spec/html-proofer/check/links_spec.rb index e614daea..bb0ec874 100644 --- a/spec/html-proofer/check/links_spec.rb +++ b/spec/html-proofer/check/links_spec.rb @@ -46,6 +46,12 @@ expect(proofer.failed_checks.first.description).to(match(/internally linking to #noHash; the file exists, but the hash 'noHash' does not/)) end + it "passes for internal links with non-ASCII characters" do + broken_hash_internal_filepath = File.join(FIXTURES_DIR, "links", "hash_nonascii.html") + proofer = run_proofer(broken_hash_internal_filepath, :file) + expect(proofer.failed_checks).to(eq([])) + end + it "passes for broken internal hash when asked to ignore" do broken_hash_internal_filepath = File.join(FIXTURES_DIR, "links", "broken_hash_internal.html") proofer = run_proofer(broken_hash_internal_filepath, :file, check_internal_hash: false) diff --git a/spec/html-proofer/fixtures/links/hash_nonascii.html b/spec/html-proofer/fixtures/links/hash_nonascii.html new file mode 100644 index 00000000..e517b82f --- /dev/null +++ b/spec/html-proofer/fixtures/links/hash_nonascii.html @@ -0,0 +1,8 @@ + + +

Blah blah blah. Hash mit ein umlaut

+ +

Hier gib's

+ + + From 55348841943a0af783c4664a58fec07086f0b9f4 Mon Sep 17 00:00:00 2001 From: Eric Sorenson Date: Wed, 1 May 2024 19:01:54 -0700 Subject: [PATCH 69/78] Reproducible case for anchor link encoding failures Looking a little deeper into the source code of the failures, I noticed that not _all_ the non-ASCII links were failing, only some of them. The site gets built with relative links between pages, and it was links to another page with a "../page/#hash" syntax which failed. This commit adds a test directory which mimics that structure and reliably reproduces the error... I think! --- spec/html-proofer/check/links_spec.rb | 6 +++--- .../fixtures/links/hash_nonascii_dir/source/index.html | 8 ++++++++ .../target/index.html} | 6 ++++-- 3 files changed, 15 insertions(+), 5 deletions(-) create mode 100644 spec/html-proofer/fixtures/links/hash_nonascii_dir/source/index.html rename spec/html-proofer/fixtures/links/{hash_nonascii.html => hash_nonascii_dir/target/index.html} (50%) diff --git a/spec/html-proofer/check/links_spec.rb b/spec/html-proofer/check/links_spec.rb index bb0ec874..8face6e8 100644 --- a/spec/html-proofer/check/links_spec.rb +++ b/spec/html-proofer/check/links_spec.rb @@ -46,9 +46,9 @@ expect(proofer.failed_checks.first.description).to(match(/internally linking to #noHash; the file exists, but the hash 'noHash' does not/)) end - it "passes for internal links with non-ASCII characters" do - broken_hash_internal_filepath = File.join(FIXTURES_DIR, "links", "hash_nonascii.html") - proofer = run_proofer(broken_hash_internal_filepath, :file) + it "passes for internal links with non-ASCII characters from implicit indexes" do + broken_hash_internal_filepath = File.join(FIXTURES_DIR, "links", "hash_nonascii_dir") + proofer = run_proofer(broken_hash_internal_filepath, :directory, check_internal_hash: true) expect(proofer.failed_checks).to(eq([])) end diff --git a/spec/html-proofer/fixtures/links/hash_nonascii_dir/source/index.html b/spec/html-proofer/fixtures/links/hash_nonascii_dir/source/index.html new file mode 100644 index 00000000..7fb9447f --- /dev/null +++ b/spec/html-proofer/fixtures/links/hash_nonascii_dir/source/index.html @@ -0,0 +1,8 @@ + + +

Hash mit ein umlaut

+

Hash ohne ein umlaut

+ + + + diff --git a/spec/html-proofer/fixtures/links/hash_nonascii.html b/spec/html-proofer/fixtures/links/hash_nonascii_dir/target/index.html similarity index 50% rename from spec/html-proofer/fixtures/links/hash_nonascii.html rename to spec/html-proofer/fixtures/links/hash_nonascii_dir/target/index.html index e517b82f..313ce700 100644 --- a/spec/html-proofer/fixtures/links/hash_nonascii.html +++ b/spec/html-proofer/fixtures/links/hash_nonascii_dir/target/index.html @@ -1,8 +1,10 @@ -

Blah blah blah. Hash mit ein umlaut

-

Hier gib's

+ + blah de blah + +

Hier auch

From 3748112b7086781fc6404b199f2fe259740cb1c5 Mon Sep 17 00:00:00 2001 From: Eric Sorenson Date: Thu, 23 May 2024 13:31:40 -0700 Subject: [PATCH 70/78] Fix trailing whitespace --- spec/html-proofer/check/links_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/html-proofer/check/links_spec.rb b/spec/html-proofer/check/links_spec.rb index 8face6e8..f50154b5 100644 --- a/spec/html-proofer/check/links_spec.rb +++ b/spec/html-proofer/check/links_spec.rb @@ -50,7 +50,7 @@ broken_hash_internal_filepath = File.join(FIXTURES_DIR, "links", "hash_nonascii_dir") proofer = run_proofer(broken_hash_internal_filepath, :directory, check_internal_hash: true) expect(proofer.failed_checks).to(eq([])) - end + end it "passes for broken internal hash when asked to ignore" do broken_hash_internal_filepath = File.join(FIXTURES_DIR, "links", "broken_hash_internal.html") From 87c556524576c98418870d2bf8bc5e387048efc2 Mon Sep 17 00:00:00 2001 From: MakWigglz Date: Fri, 2 Aug 2024 23:39:48 +0300 Subject: [PATCH 71/78] Fix variable assignment in index.php --- spec/html-proofer/fixtures/links/folder-php/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/html-proofer/fixtures/links/folder-php/index.php b/spec/html-proofer/fixtures/links/folder-php/index.php index 6ef6b583..392776b0 100644 --- a/spec/html-proofer/fixtures/links/folder-php/index.php +++ b/spec/html-proofer/fixtures/links/folder-php/index.php @@ -1,2 +1,2 @@ Date: Mon, 19 Aug 2024 14:05:33 -0400 Subject: [PATCH 72/78] Correct README example --- README.md | 181 +++++++++++++++++++++++++++--------------------------- 1 file changed, 90 insertions(+), 91 deletions(-) diff --git a/README.md b/README.md index 28fcd463..e7927684 100644 --- a/README.md +++ b/README.md @@ -36,45 +36,45 @@ Below is a mostly comprehensive list of checks that HTMLProofer can perform. `img` elements: -* Whether all your images have alt tags -* Whether your internal image references are not broken -* Whether external images are showing -* Whether your images are HTTP +- Whether all your images have alt tags +- Whether your internal image references are not broken +- Whether external images are showing +- Whether your images are HTTP ### Links `a`, `link` elements: -* Whether your internal links are working -* Whether your internal hash references (`#linkToMe`) are working -* Whether external links are working -* Whether your links are HTTPS -* Whether CORS/SRI is enabled +- Whether your internal links are working +- Whether your internal hash references (`#linkToMe`) are working +- Whether external links are working +- Whether your links are HTTPS +- Whether CORS/SRI is enabled ### Scripts `script` elements: -* Whether your internal script references are working -* Whether external scripts are loading -* Whether CORS/SRI is enabled +- Whether your internal script references are working +- Whether external scripts are loading +- Whether CORS/SRI is enabled ### Favicon -* Whether your favicons are valid. +- Whether your favicons are valid. ### OpenGraph -* Whether the images and URLs in the OpenGraph metadata are valid. +- Whether the images and URLs in the OpenGraph metadata are valid. ## Usage You can configure HTMLProofer to run on: -* a file -* a directory -* an array of directories -* an array of links +- a file +- a directory +- an array of directories +- an array of links It can also run through the command-line. @@ -118,7 +118,7 @@ HTMLProofer.check_directory("./out").run If you simply want to check a single file, use the `check_file` method: -``` ruby +```ruby HTMLProofer.check_file("/path/to/a/file.html").run ``` @@ -126,13 +126,13 @@ HTMLProofer.check_file("/path/to/a/file.html").run If you want to check a directory, use `check_directory`: -``` ruby +```ruby HTMLProofer.check_directory("./out").run ``` If you want to check multiple directories, use `check_directories`: -``` ruby +```ruby HTMLProofer.check_directories(["./one", "./two"]).run ``` @@ -140,7 +140,7 @@ HTMLProofer.check_directories(["./one", "./two"]).run With `check_links`, you can also pass in an array of links: -``` ruby +```ruby HTMLProofer.check_links(["https://github.com", "https://jekyllrb.com"]).run ``` @@ -157,7 +157,7 @@ In this case, any link that matches the `^https://placeholder.com` will be conve A similar swapping process can be done for attributes: ```ruby -run_proofer(file, :file, swap_attributes: { "img": [["data-src", "src"]] }) +run_proofer(file, :file, swap_attributes: { "img" => [["data-src", "src"]] }) ``` In this case, we are telling HTMLProofer that, for any `img` tag detected, for any `src` attribute, pretend it's actually the `src` attribute instead. Since the value is an array of arrays, you can pass in as many attribute swaps as you need for each element. @@ -168,7 +168,7 @@ You'll also get a new program called `htmlproofer` with this gem. Terrific! Pass in options through the command-line as flags, like this: -``` bash +```bash htmlproofer --extensions .html.erb ./out ``` @@ -179,14 +179,14 @@ Use `htmlproofer --help` to see all command line options. For options which require an array of input, surround the value with quotes, and don't use any spaces. For example, to exclude an array of HTTP status code, you might do: -``` bash +```bash htmlproofer --ignore-status-codes "999,401,404" ./out ``` For something like `url-ignore`, and other options that require an array of regular expressions, you can pass in a syntax like this: -``` bash +```bash htmlproofer --ignore-urls "/www.github.com/,/foo.com/" ./out ``` @@ -194,7 +194,7 @@ Since `swap_urls` is a bit special, you'll pass in a pair of `RegEx:String` values. The escape sequences `\:` should be used to produce literal `:`s `htmlproofer` will figure out what you mean. -``` bash +```bash htmlproofer --swap-urls "wow:cow,mow:doh" --extensions .html.erb --ignore-urls www.github.com ./out ``` @@ -229,18 +229,17 @@ end If you have trouble with (or don't want to) install Ruby/Nokogumbo, the command-line tool can be run through Docker. See [klakegg/html-proofer](https://hub.docker.com/r/klakegg/html-proofer) for more information. - ## Ignoring content Add the `data-proofer-ignore` attribute to any tag to ignore it from every check. -``` html +```html Not checked. ``` This can also apply to parent elements, all the way up to the `` tag: -``` html +```html @@ -267,41 +266,41 @@ HTMLProofer.check_directory("./output", { ignore_urls: diffable_files }).run The `HTMLProofer` constructor takes an optional hash of additional options: -| Option | Description | Default | -| :----- | :---------- | :------ | -| `allow_hash_href` | If `true`, assumes `href="#"` anchors are valid | `true` | -| `allow_missing_href` | If `true`, does not flag `a` tags missing `href`. In HTML5, this is technically allowed, but could also be human error. | `false` | -| `assume_extension` | Automatically add specified extension to files for internal links, to allow extensionless URLs (as supported by most servers) | `.html` | -| `checks`| An array of Strings indicating which checks you want to run | `['Links', 'Images', 'Scripts']` -| `check_external_hash` | Checks whether external hashes exist (even if the webpage exists) | `true` | -| `check_internal_hash` | Checks whether internal hashes exist (even if the webpage exists) | `true` | -| `check_sri` | Check that `` and `