mirror of
https://github.com/basecamp/once-campfire.git
synced 2026-10-25 15:16:48 +09:00
Merge pull request #326: Reuse push connections pinned to the address the guard just approved
Reviewed and merged by GPT on behalf of DHH.
This commit is contained in:
commit
4ceb92ea04
8 files changed
+489
-38
No files matched your search
@@ -1,4 +1,5 @@
|
||||
require "web-push"
|
||||
require "web_push/connections"
|
||||
require "web_push/pool"
|
||||
require "web_push/notification"
|
||||
|
||||
@@ -17,43 +18,31 @@ end
|
||||
|
||||
module WebPush::PersistentRequest
|
||||
def perform
|
||||
if endpoint_ip = @options[:endpoint_ip]
|
||||
# Pin the connection to the public IP resolved (and guarded) by
|
||||
# Push::Subscription so delivery can't be rebound to a private address
|
||||
# between resolution and connect. Bypasses the shared persistent pool,
|
||||
# which would re-resolve the host itself.
|
||||
#
|
||||
# The explicit nil proxy address disables proxy discovery from
|
||||
# http_proxy/https_proxy. An egress proxy would open the TCP connection
|
||||
# itself and re-resolve the endpoint host, so http.ipaddr would no longer
|
||||
# pin the destination and the DNS-rebinding guarantee would be lost. This
|
||||
# path is already committed to a direct connection (it bypasses the pool);
|
||||
# push delivery to public vendor endpoints goes direct.
|
||||
http = Net::HTTP.new(uri.host, uri.port, nil)
|
||||
http.ipaddr = endpoint_ip
|
||||
http.use_ssl = true
|
||||
http.ssl_timeout = @options[:ssl_timeout] unless @options[:ssl_timeout].nil?
|
||||
http.open_timeout = @options[:open_timeout] unless @options[:open_timeout].nil?
|
||||
http.read_timeout = @options[:read_timeout] unless @options[:read_timeout].nil?
|
||||
elsif @options[:connection]
|
||||
http = @options[:connection]
|
||||
else
|
||||
http = Net::HTTP.new(uri.host, uri.port, *proxy_options)
|
||||
http.use_ssl = true
|
||||
http.ssl_timeout = @options[:ssl_timeout] unless @options[:ssl_timeout].nil?
|
||||
http.open_timeout = @options[:open_timeout] unless @options[:open_timeout].nil?
|
||||
http.read_timeout = @options[:read_timeout] unless @options[:read_timeout].nil?
|
||||
end
|
||||
# Pin the connection to the public IP resolved (and guarded) by
|
||||
# Push::Subscription so delivery can't be rebound to a private address
|
||||
# between resolution and connect. There is no unpinned path: a delivery
|
||||
# without a resolved IP is not sent.
|
||||
endpoint_ip = @options[:endpoint_ip] or raise ArgumentError, "Push deliveries must be pinned to a resolved endpoint IP"
|
||||
|
||||
# The explicit nil proxy address disables proxy discovery from
|
||||
# http_proxy/https_proxy. An egress proxy would open the TCP connection
|
||||
# itself and re-resolve the endpoint host, so http.ipaddr would no longer
|
||||
# pin the destination and the DNS-rebinding guarantee would be lost.
|
||||
# Push delivery to public vendor endpoints goes direct.
|
||||
http = Net::HTTP.new(uri.host, uri.port, nil)
|
||||
http.ipaddr = endpoint_ip
|
||||
http.use_ssl = true
|
||||
http.ssl_timeout = @options[:ssl_timeout] unless @options[:ssl_timeout].nil?
|
||||
http.open_timeout = @options[:open_timeout] unless @options[:open_timeout].nil?
|
||||
http.read_timeout = @options[:read_timeout] unless @options[:read_timeout].nil?
|
||||
|
||||
req = Net::HTTP::Post.new(uri.request_uri, headers)
|
||||
req.body = body
|
||||
|
||||
if http.is_a?(Net::HTTP::Persistent)
|
||||
response = http.request uri, req
|
||||
else
|
||||
resp = http.request(req)
|
||||
verify_response(resp)
|
||||
end
|
||||
# WebPush::Connections reuses an open connection only for this same host
|
||||
# and pinned IP, so the guarantee holds for every request it sends.
|
||||
resp = @options[:connection] ? @options[:connection].request(http, req) : http.request(req)
|
||||
verify_response(resp)
|
||||
|
||||
resp
|
||||
end
|
||||
|
||||
Reference in new issue
Block a user