Merge branch 'fix-varnish7-support' into 'develop'

Fix Varnish7 support

See merge request pleroma/pleroma!3722
This commit is contained in:
feld 2022-08-11 15:14:16 +00:00
commit 514caed573
3 changed files with 15 additions and 46 deletions

View file

@ -1,4 +1,5 @@
# Recommended varnishncsa logging format: '%h %l %u %t "%m %{X-Forwarded-Proto}i://%{Host}i%U%q %H" %s %b "%{Referer}i" "%{User-agent}i"' # Recommended varnishncsa logging format: '%h %l %u %t "%m %{X-Forwarded-Proto}i://%{Host}i%U%q %H" %s %b "%{Referer}i" "%{User-agent}i"'
# Please use Varnish 7.0+ for proper Range Requests / Chunked encoding support
vcl 4.1; vcl 4.1;
import std; import std;
@ -22,11 +23,6 @@ sub vcl_recv {
set req.http.X-Forwarded-Proto = "https"; set req.http.X-Forwarded-Proto = "https";
} }
# CHUNKED SUPPORT
if (req.http.Range ~ "bytes=") {
set req.http.x-range = req.http.Range;
}
# Pipe if WebSockets request is coming through # Pipe if WebSockets request is coming through
if (req.http.upgrade ~ "(?i)websocket") { if (req.http.upgrade ~ "(?i)websocket") {
return (pipe); return (pipe);
@ -35,9 +31,9 @@ sub vcl_recv {
# Allow purging of the cache # Allow purging of the cache
if (req.method == "PURGE") { if (req.method == "PURGE") {
if (!client.ip ~ purge) { if (!client.ip ~ purge) {
return(synth(405,"Not allowed.")); return (synth(405,"Not allowed."));
} }
return(purge); return (purge);
} }
} }
@ -53,17 +49,11 @@ sub vcl_backend_response {
return (retry); return (retry);
} }
# CHUNKED SUPPORT
if (bereq.http.x-range ~ "bytes=" && beresp.status == 206) {
set beresp.ttl = 10m;
set beresp.http.CR = beresp.http.content-range;
}
# Bypass cache for large files # Bypass cache for large files
# 50000000 ~ 50MB # 50000000 ~ 50MB
if (std.integer(beresp.http.content-length, 0) > 50000000) { if (std.integer(beresp.http.content-length, 0) > 50000000) {
set beresp.uncacheable = true; set beresp.uncacheable = true;
return(deliver); return (deliver);
} }
# Don't cache objects that require authentication # Don't cache objects that require authentication
@ -94,7 +84,7 @@ sub vcl_synth {
if (resp.status == 750) { if (resp.status == 750) {
set resp.status = 301; set resp.status = 301;
set resp.http.Location = req.http.x-redir; set resp.http.Location = req.http.x-redir;
return(deliver); return (deliver);
} }
} }
@ -106,25 +96,12 @@ sub vcl_pipe {
} }
} }
sub vcl_hash {
# CHUNKED SUPPORT
if (req.http.x-range ~ "bytes=") {
hash_data(req.http.x-range);
unset req.http.Range;
}
}
sub vcl_backend_fetch { sub vcl_backend_fetch {
# Be more lenient for slow servers on the fediverse # Be more lenient for slow servers on the fediverse
if (bereq.url ~ "^/proxy/") { if (bereq.url ~ "^/proxy/") {
set bereq.first_byte_timeout = 300s; set bereq.first_byte_timeout = 300s;
} }
# CHUNKED SUPPORT
if (bereq.http.x-range) {
set bereq.http.Range = bereq.http.x-range;
}
if (bereq.retries == 0) { if (bereq.retries == 0) {
# Clean up the X-Varnish-Backend-503 flag that is used internally # Clean up the X-Varnish-Backend-503 flag that is used internally
# to mark broken backend responses that should be retried. # to mark broken backend responses that should be retried.
@ -143,14 +120,6 @@ sub vcl_backend_fetch {
} }
} }
sub vcl_deliver {
# CHUNKED SUPPORT
if (resp.http.CR) {
set resp.http.Content-Range = resp.http.CR;
unset resp.http.CR;
}
}
sub vcl_backend_error { sub vcl_backend_error {
# Retry broken backend responses. # Retry broken backend responses.
set bereq.http.X-Varnish-Backend-503 = "1"; set bereq.http.X-Varnish-Backend-503 = "1";

View file

@ -54,7 +54,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyController do
media_proxy_url = MediaProxy.url(url) media_proxy_url = MediaProxy.url(url)
with {:ok, %{status: status} = head_response} when status in 200..299 <- with {:ok, %{status: status} = head_response} when status in 200..299 <-
Pleroma.HTTP.request("head", media_proxy_url, [], [], pool: :media) do Pleroma.HTTP.request("HEAD", media_proxy_url, [], [], pool: :media) do
content_type = Tesla.get_header(head_response, "content-type") content_type = Tesla.get_header(head_response, "content-type")
content_length = Tesla.get_header(head_response, "content-length") content_length = Tesla.get_header(head_response, "content-length")
content_length = content_length && String.to_integer(content_length) content_length = content_length && String.to_integer(content_length)

View file

@ -158,7 +158,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
media_proxy_url: media_proxy_url media_proxy_url: media_proxy_url
} do } do
Tesla.Mock.mock(fn Tesla.Mock.mock(fn
%{method: "head", url: ^media_proxy_url} -> %{method: "HEAD", url: ^media_proxy_url} ->
%Tesla.Env{status: 500, body: ""} %Tesla.Env{status: 500, body: ""}
end) end)
@ -173,7 +173,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
media_proxy_url: media_proxy_url media_proxy_url: media_proxy_url
} do } do
Tesla.Mock.mock(fn Tesla.Mock.mock(fn
%{method: "head", url: ^media_proxy_url} -> %{method: "HEAD", url: ^media_proxy_url} ->
%Tesla.Env{status: 200, body: "", headers: [{"content-type", "application/pdf"}]} %Tesla.Env{status: 200, body: "", headers: [{"content-type", "application/pdf"}]}
end) end)
@ -193,7 +193,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
clear_config([:media_preview_proxy, :min_content_length], 1_000_000_000) clear_config([:media_preview_proxy, :min_content_length], 1_000_000_000)
Tesla.Mock.mock(fn Tesla.Mock.mock(fn
%{method: "head", url: ^media_proxy_url} -> %{method: "HEAD", url: ^media_proxy_url} ->
%Tesla.Env{ %Tesla.Env{
status: 200, status: 200,
body: "", body: "",
@ -218,7 +218,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
media_proxy_url: media_proxy_url media_proxy_url: media_proxy_url
} do } do
Tesla.Mock.mock(fn Tesla.Mock.mock(fn
%{method: "head", url: ^media_proxy_url} -> %{method: "HEAD", url: ^media_proxy_url} ->
%Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/gif"}]} %Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/gif"}]}
end) end)
@ -236,7 +236,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
media_proxy_url: media_proxy_url media_proxy_url: media_proxy_url
} do } do
Tesla.Mock.mock(fn Tesla.Mock.mock(fn
%{method: "head", url: ^media_proxy_url} -> %{method: "HEAD", url: ^media_proxy_url} ->
%Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/jpeg"}]} %Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/jpeg"}]}
end) end)
@ -256,7 +256,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
clear_config([:media_preview_proxy, :min_content_length], 100_000) clear_config([:media_preview_proxy, :min_content_length], 100_000)
Tesla.Mock.mock(fn Tesla.Mock.mock(fn
%{method: "head", url: ^media_proxy_url} -> %{method: "HEAD", url: ^media_proxy_url} ->
%Tesla.Env{ %Tesla.Env{
status: 200, status: 200,
body: "", body: "",
@ -278,7 +278,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
assert_dependencies_installed() assert_dependencies_installed()
Tesla.Mock.mock(fn Tesla.Mock.mock(fn
%{method: "head", url: ^media_proxy_url} -> %{method: "HEAD", url: ^media_proxy_url} ->
%Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/png"}]} %Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/png"}]}
%{method: :get, url: ^media_proxy_url} -> %{method: :get, url: ^media_proxy_url} ->
@ -300,7 +300,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
assert_dependencies_installed() assert_dependencies_installed()
Tesla.Mock.mock(fn Tesla.Mock.mock(fn
%{method: "head", url: ^media_proxy_url} -> %{method: "HEAD", url: ^media_proxy_url} ->
%Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/jpeg"}]} %Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/jpeg"}]}
%{method: :get, url: ^media_proxy_url} -> %{method: :get, url: ^media_proxy_url} ->
@ -320,7 +320,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
media_proxy_url: media_proxy_url media_proxy_url: media_proxy_url
} do } do
Tesla.Mock.mock(fn Tesla.Mock.mock(fn
%{method: "head", url: ^media_proxy_url} -> %{method: "HEAD", url: ^media_proxy_url} ->
%Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/jpeg"}]} %Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/jpeg"}]}
%{method: :get, url: ^media_proxy_url} -> %{method: :get, url: ^media_proxy_url} ->