diff options
author | Adam Wanninger <ajwann@ajwann.codes> | 2017-08-19 14:54:23 -0400 |
---|---|---|
committer | Adam Wanninger <ajwann@ajwann.codes> | 2017-08-27 10:55:37 -0400 |
commit | 31b8f312ac09cdbd94ccc9607221fa8a95ad24b4 (patch) | |
tree | 2a8d69a673ae91c085ec7077af76b27d6e8e797a /lib/bundler/compact_index_client | |
parent | 938ceb37cae42c8e45576918c63422b74b2f1790 (diff) | |
download | bundler-31b8f312ac09cdbd94ccc9607221fa8a95ad24b4.tar.gz |
ensure $HOME and Dir.tmpdir are writable
Diffstat (limited to 'lib/bundler/compact_index_client')
-rw-r--r-- | lib/bundler/compact_index_client/updater.rb | 96 |
1 files changed, 55 insertions, 41 deletions
diff --git a/lib/bundler/compact_index_client/updater.rb b/lib/bundler/compact_index_client/updater.rb index 6a66fbc3fe..f69b81f116 100644 --- a/lib/bundler/compact_index_client/updater.rb +++ b/lib/bundler/compact_index_client/updater.rb @@ -28,55 +28,59 @@ module Bundler def update(local_path, remote_path, retrying = nil) headers = {} - Dir.mktmpdir("bundler-compact-index-") do |local_temp_dir| - local_temp_path = Pathname.new(local_temp_dir).join(local_path.basename) - - # first try to fetch any new bytes on the existing file - if retrying.nil? && local_path.file? - FileUtils.cp local_path, local_temp_path - headers["If-None-Match"] = etag_for(local_temp_path) - headers["Range"] = - if local_temp_path.size.nonzero? - # Subtract a byte to ensure the range won't be empty. - # Avoids 416 (Range Not Satisfiable) responses. - "bytes=#{local_temp_path.size - 1}-" - else - "bytes=#{local_temp_path.size}-" - end - else - # Fastly ignores Range when Accept-Encoding: gzip is set - headers["Accept-Encoding"] = "gzip" - end + Bundler::SharedHelpers.filesystem_access(Dir.tmpdir, :write) do + validate_permissions_on_home + + Dir.mktmpdir("bundler-compact-index-") do |local_temp_dir| + local_temp_path = Pathname.new(local_temp_dir).join(local_path.basename) + + # first try to fetch any new bytes on the existing file + if retrying.nil? && local_path.file? + FileUtils.cp local_path, local_temp_path + headers["If-None-Match"] = etag_for(local_temp_path) + headers["Range"] = + if local_temp_path.size.nonzero? + # Subtract a byte to ensure the range won't be empty. + # Avoids 416 (Range Not Satisfiable) responses. + "bytes=#{local_temp_path.size - 1}-" + else + "bytes=#{local_temp_path.size}-" + end + else + # Fastly ignores Range when Accept-Encoding: gzip is set + headers["Accept-Encoding"] = "gzip" + end - response = @fetcher.call(remote_path, headers) - return nil if response.is_a?(Net::HTTPNotModified) + response = @fetcher.call(remote_path, headers) + return nil if response.is_a?(Net::HTTPNotModified) - content = response.body - if response["Content-Encoding"] == "gzip" - content = Zlib::GzipReader.new(StringIO.new(content)).read - end + content = response.body + if response["Content-Encoding"] == "gzip" + content = Zlib::GzipReader.new(StringIO.new(content)).read + end - SharedHelpers.filesystem_access(local_temp_path) do - if response.is_a?(Net::HTTPPartialContent) && local_temp_path.size.nonzero? - local_temp_path.open("a") {|f| f << slice_body(content, 1..-1) } - else - local_temp_path.open("w") {|f| f << content } + SharedHelpers.filesystem_access(local_temp_path) do + if response.is_a?(Net::HTTPPartialContent) && local_temp_path.size.nonzero? + local_temp_path.open("a") {|f| f << slice_body(content, 1..-1) } + else + local_temp_path.open("w") {|f| f << content } + end end - end - response_etag = (response["ETag"] || "").gsub(%r{\AW/}, "") - if etag_for(local_temp_path) == response_etag - SharedHelpers.filesystem_access(local_path) do - FileUtils.mv(local_temp_path, local_path) + response_etag = (response["ETag"] || "").gsub(%r{\AW/}, "") + if etag_for(local_temp_path) == response_etag + SharedHelpers.filesystem_access(local_path) do + FileUtils.mv(local_temp_path, local_path) + end + return nil end - return nil - end - if retrying - raise MisMatchedChecksumError.new(remote_path, response_etag, etag_for(local_temp_path)) - end + if retrying + raise MisMatchedChecksumError.new(remote_path, response_etag, etag_for(local_temp_path)) + end - update(local_path, remote_path, :retrying) + update(local_path, remote_path, :retrying) + end end end @@ -102,6 +106,16 @@ module Bundler Digest::MD5.hexdigest(IO.read(path)) end end + + private + + def validate_permissions_on_home + return if File.stat(ENV["HOME"]).writable? + raise Bundler::PermissionError, + "Bundler does not have write access to $HOME. Bundler must " \ + "have write access to $HOME to function properly. " \ + "$HOME is currently #{ENV["HOME"]}" + end end end end |