Skip to content

Commit 7c150b9

Browse files
committed
fix double https://
1 parent 60a2493 commit 7c150b9

9 files changed

Lines changed: 71 additions & 12 deletions

File tree

app/controllers/concerns/json_error_responses.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ module JSONErrorResponses
1717

1818
STATUS_ALIASES = { unprocessable_entity: :unprocessable_content }.freeze
1919

20-
def self.canonical_host = ENV["CDN_HOST"].presence || "cdn.hackclub.com"
20+
def self.canonical_host = CDNHost.host
2121

22-
def self.documentation_url = "https://#{canonical_host}#{DOCUMENTATION_PATH}"
22+
def self.documentation_url = "#{CDNHost.base_url}#{DOCUMENTATION_PATH}"
2323

2424
def self.payload(code:, status:, message:, hint: nil, error: nil, **extra)
2525
body = {

app/helpers/metadata_helper.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ module MetadataHelper
44
SITE_NAME = "Hack Club CDN"
55
SITE_DESCRIPTION = "File hosting for Hack Clubbers. Upload files through the dashboard or the HTTP API and get permanent CDN URLs."
66

7-
def canonical_host = ENV["CDN_HOST"].presence || "cdn.hackclub.com"
8-
def canonical_root = "https://#{canonical_host}"
7+
def canonical_host = CDNHost.host
8+
def canonical_root = CDNHost.base_url
99
def canonical_url = content_for(:canonical_url).presence || "#{canonical_root}#{request.path}"
1010
def page_title = content_for(:title).presence || SITE_NAME
1111
def page_description = content_for(:description).presence || SITE_DESCRIPTION

app/models/cdn_host.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# frozen_string_literal: true
2+
3+
# Single source of truth for the CDN's public hostname. CDN_HOST is documented
4+
# as a bare hostname, but some deployments store a full https:// URL there.
5+
# Normalize it so URL builders that add their own scheme never emit
6+
# "https://https://cdn.hackclub.com".
7+
module CDNHost
8+
DEFAULT_HOST = "cdn.hackclub.com"
9+
10+
module_function
11+
12+
def host
13+
raw = ENV["CDN_HOST"].presence || DEFAULT_HOST
14+
raw.sub(%r{\Ahttps?://}i, "").sub(%r{/+\z}, "")
15+
end
16+
17+
def base_url = "https://#{host}"
18+
end

app/models/llms_txt.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ class LlmsTxt
1717
AUTH_URL = "https://auth.hackclub.com"
1818

1919
class << self
20-
def host = ENV["CDN_HOST"].presence || "cdn.hackclub.com"
20+
def host = CDNHost.host
2121

22-
def base_url = "https://#{host}"
22+
def base_url = CDNHost.base_url
2323

2424
def to_s
2525
[ header, guidance, when_to_use, api, docs, optional ].join("\n")

app/models/open_api_spec.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ class OpenAPISpec
55
API_VERSION = "4.0.0"
66

77
class << self
8-
def host = ENV["CDN_HOST"].presence || "cdn.hackclub.com"
8+
def host = CDNHost.host
99

10-
def base_url = "https://#{host}"
10+
def base_url = CDNHost.base_url
1111

1212
def as_json(*) = document
1313

app/models/sitemap.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ class Sitemap
1111
Entry = Data.define(:loc, :lastmod, :changefreq)
1212

1313
class << self
14-
def host = ENV["CDN_HOST"].presence || "cdn.hackclub.com"
14+
def host = CDNHost.host
1515

16-
def base_url = "https://#{host}"
16+
def base_url = CDNHost.base_url
1717

1818
def entries = [ home_entry, *doc_entries ]
1919

app/models/upload.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ def cdn_url
8080
Rails.application.routes.url_helpers.external_upload_url(
8181
id:,
8282
filename:,
83-
host: ENV["CDN_HOST"] || "cdn.hackclub.com"
83+
host: CDNHost.host
8484
)
8585
end
8686

lib/tasks/import_slack_files.rake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace :import do
77
desc "Import files from Slack using a CSV with slack_file_url and slack_user_id"
88
task slack_files: :environment do
99
# Set URL options for ActiveStorage in rake context
10-
ActiveStorage::Current.url_options = { host: ENV.fetch("CDN_HOST", "cdn.hackclub.com"), protocol: "https" }
10+
ActiveStorage::Current.url_options = { host: CDNHost.host, protocol: "https" }
1111
csv_path = ENV.fetch("CSV_PATH", "files_with_slack_url.csv")
1212
slack_token = ENV.fetch("SLACK_TOKEN") { raise "SLACK_TOKEN (xoxp-...) is required" }
1313
thread_count = ENV.fetch("THREADS", 67).to_i

test/models/cdn_host_test.rb

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# frozen_string_literal: true
2+
3+
require "test_helper"
4+
5+
class CDNHostTest < ActiveSupport::TestCase
6+
def with_cdn_host(value)
7+
previous = ENV["CDN_HOST"]
8+
value.nil? ? ENV.delete("CDN_HOST") : ENV["CDN_HOST"] = value
9+
yield
10+
ensure
11+
previous.nil? ? ENV.delete("CDN_HOST") : ENV["CDN_HOST"] = previous
12+
end
13+
14+
test "defaults to the production hostname when CDN_HOST is unset" do
15+
with_cdn_host(nil) do
16+
assert_equal "cdn.hackclub.com", CDNHost.host
17+
assert_equal "https://cdn.hackclub.com", CDNHost.base_url
18+
end
19+
end
20+
21+
test "accepts a bare hostname" do
22+
with_cdn_host("cdn.example.com") do
23+
assert_equal "cdn.example.com", CDNHost.host
24+
assert_equal "https://cdn.example.com", CDNHost.base_url
25+
end
26+
end
27+
28+
test "strips a scheme and trailing slash from CDN_HOST" do
29+
with_cdn_host("https://cdn.example.com/") do
30+
assert_equal "cdn.example.com", CDNHost.host
31+
assert_equal "https://cdn.example.com", CDNHost.base_url
32+
end
33+
end
34+
35+
test "never produces a doubled scheme" do
36+
with_cdn_host("https://cdn.hackclub.com") do
37+
assert_equal "https://cdn.hackclub.com", CDNHost.base_url
38+
refute_includes CDNHost.base_url, "https://https://"
39+
end
40+
end
41+
end

0 commit comments

Comments
 (0)