diff --git a/shard.lock b/shard.lock index 4771feb..10cf827 100644 --- a/shard.lock +++ b/shard.lock @@ -28,6 +28,10 @@ shards: github: crystal-loot/exception_page version: 0.1.4 + http_proxy: + github: mamantoha/http_proxy + version: 0.7.1 + kemal: github: kemalcr/kemal version: 0.26.1 diff --git a/shard.yml b/shard.yml index 824d91d..9e64fd9 100644 --- a/shard.yml +++ b/shard.yml @@ -32,3 +32,5 @@ dependencies: version: ~> 0.20.0 myhtml: github: kostya/myhtml + http_proxy: + github: mamantoha/http_proxy diff --git a/src/util/proxy.cr b/src/util/proxy.cr new file mode 100644 index 0000000..26c8d5a --- /dev/null +++ b/src/util/proxy.cr @@ -0,0 +1,42 @@ +require "http_proxy" + +# Monkey-patch `HTTP::Client` to make it respect the `*_PROXY` +# environment variables +module HTTP + class Client + private def self.exec(uri : URI, tls : TLSContext = nil) + Logger.debug "Using monkey-patched HTTP::Client" + previous_def uri, tls do |client, path| + client.set_proxy get_proxy uri + yield client, path + end + end + end +end + +private def get_proxy(uri : URI) : HTTP::Proxy::Client? + no_proxy = ENV["no_proxy"]? || ENV["NO_PROXY"]? + return if no_proxy && + no_proxy.split(",").any? &.== uri.hostname + + case uri.scheme + when "http" + env_to_proxy "http_proxy" + when "https" + env_to_proxy "https_proxy" + else + nil + end +end + +private def env_to_proxy(key : String) : HTTP::Proxy::Client? + val = ENV[key.downcase]? || ENV[key.upcase]? + return if val.nil? + + begin + uri = URI.parse val + HTTP::Proxy::Client.new uri.hostname.not_nil!, uri.port.not_nil! + rescue + nil + end +end