locals { code_host = "http.host eq \"${var.forge_code_hostname}\"" code_path = <<-EOT (${local.code_host}) and not ends_with(http.request.uri.path, "/info/refs") and not ends_with(http.request.uri.path, "/git-upload-pack") and not ends_with(http.request.uri.path, "/git-receive-pack") and not ends_with(http.request.uri.path, "/HEAD") and not http.request.uri.path contains "/objects/" EOT # Forgejo parses multipart GET bodies, including HTTP/2 bodies without Content-Length. code_read = <<-EOT (${local.code_path}) and http.request.method in {"GET" "HEAD"} and not any(lower(http.request.headers.names[*])[*] in {"content-type" "content-length" "transfer-encoding"}) EOT code_response = <<-EOT (${local.code_read}) and http.response.code in {200 206 304} and not any(http.response.headers["cache-control"][*] contains "no-store") EOT } resource "cloudflare_ruleset" "code_requests" { provider = cloudflare.cache zone_id = var.zone_id name = "forge-code-requests" kind = "zone" phase = "http_request_cache_settings" rules = [ { ref = "code_bypass" expression = local.code_host action = "set_cache_settings" action_parameters = { cache = false } }, { # Include Cloudflare's internal PURGE method so URL purges use the same cache settings. ref = "code_reads" expression = "((${local.code_path}) and http.request.method eq \"PURGE\") or ((${local.code_read}) and not http.request.headers.truncated)" action = "set_cache_settings" action_parameters = { cache = true edge_ttl = { mode = "respect_origin" } browser_ttl = { mode = "respect_origin" } vary = { default = { action = "bypass" } headers = { accept = { action = "passthrough" } accept-language = { action = "passthrough" } accept-encoding = { action = "normalize" } } } } }, ] } resource "cloudflare_ruleset" "code_responses" { provider = cloudflare.cache zone_id = var.zone_id name = "forge-code-responses" kind = "zone" phase = "http_response_cache_settings" rules = [ { ref = "code_errors" expression = "(${local.code_host}) and not http.response.code in {200 206 304}" action = "set_cache_control" action_parameters = { no_store = { operation = "set" cloudflare_only = true } } }, { ref = "code_public" expression = local.code_response action = "set_cache_control" action_parameters = { private = { operation = "remove" cloudflare_only = true } public = { operation = "set" cloudflare_only = true } s_maxage = { operation = "set" value = 300 cloudflare_only = true } } }, { ref = "code_assets" expression = "(${local.code_response}) and starts_with(http.request.uri.path, \"/assets/\")" action = "set_cache_control" action_parameters = { s_maxage = { operation = "set" value = 21600 cloudflare_only = true } } }, ] }