class URI::Generic

Public Instance Methods

download(target, options?) click to toggle source

Downloads the resource to the target.

The target may be a file name (string or task), in which case the file is created from the resource. The target may also be any object that responds to write, e.g. File, StringIO, Pipe.

Use the progress bar when running in verbose mode.

# File lib/buildr/core/transports.rb, line 137
def download(target, options = nil)
  case target
  when Rake::Task
    download target.name, options
  when String
    # If download breaks we end up with a partial file which is
    # worse than not having a file at all, so download to temporary
    # file and then move over.
    modified = File.stat(target).mtime if File.exist?(target)
    temp = Tempfile.new(File.basename(target))
    temp.binmode
    read({:progress=>verbose}.merge(options || {}).merge(:modified=>modified)) { |chunk| temp.write chunk }
    temp.close
    mkpath File.dirname(target)
    mv temp.path, target
  when File
    read({:progress=>verbose}.merge(options || {}).merge(:modified=>target.mtime)) { |chunk| target.write chunk }
    target.flush
  else
    raise ArgumentError, 'Expecting a target that is either a file name (string, task) or object that responds to write (file, pipe).' unless target.respond_to?(:write)
    read({:progress=>verbose}.merge(options || {})) { |chunk| target.write chunk }
    target.flush
  end
end
find_proxy() click to toggle source

returns a proxy URI. The proxy URI is obtained from environment variables such as http_proxy, ftp_proxy, no_proxy, etc. If there is no proper proxy, nil is returned.

Note that capitalized variables (HTTP_PROXY, FTP_PROXY, NO_PROXY, etc.) are examined too.

But http_proxy and HTTP_PROXY is treated specially under CGI environment. It’s because HTTP_PROXY may be set by Proxy: header. So HTTP_PROXY is not used. http_proxy is not used too if the variable is case insensitive. CGI_HTTP_PROXY can be used instead.

# File rake/lib/open-uri.rb, line 709
def find_proxy
  name = self.scheme.downcase + '_proxy'
  proxy_uri = nil
  if name == 'http_proxy' && ENV.include?('REQUEST_METHOD') # CGI?
    # HTTP_PROXY conflicts with *_proxy for proxy settings and
    # HTTP_* for header information in CGI.
    # So it should be careful to use it.
    pairs = ENV.reject {|k, v| /\Ahttp_proxy\z/ !~ k }
    case pairs.length
    when 0 # no proxy setting anyway.
      proxy_uri = nil
    when 1
      k, _ = pairs.shift
      if k == 'http_proxy' && ENV[k.upcase] == nil
        # http_proxy is safe to use because ENV is case sensitive.
        proxy_uri = ENV[name]
      else
        proxy_uri = nil
      end
    else # http_proxy is safe to use because ENV is case sensitive.
      proxy_uri = ENV.to_hash[name]
    end
    if !proxy_uri
      # Use CGI_HTTP_PROXY.  cf. libwww-perl.
      proxy_uri = ENV["CGI_#{name.upcase}"]
    end
  elsif name == 'http_proxy'
    unless proxy_uri = ENV[name]
      if proxy_uri = ENV[name.upcase]
        warn 'The environment variable HTTP_PROXY is discouraged.  Use http_proxy.'
      end
    end
  else
    proxy_uri = ENV[name] || ENV[name.upcase]
  end

  if proxy_uri && self.hostname
    require 'socket'
    begin
      addr = IPSocket.getaddress(self.hostname)
      proxy_uri = nil if /\A127\.|\A::1\z/ =~ addr
    rescue SocketError
    end
  end

  if proxy_uri
    proxy_uri = URI.parse(proxy_uri)
    name = 'no_proxy'
    if no_proxy = ENV[name] || ENV[name.upcase]
      no_proxy.scan(/([^:,]*)(?::(\d+))?/) {|host, port|
        if /(\A|\.)#{Regexp.quote host}\z/ =~ self.host &&
           (!port || self.port == port.to_i)
          proxy_uri = nil
          break
        end
      }
    end
    proxy_uri
  else
    nil
  end
end
read(options?) → content click to toggle source
read(options?) { |chunk| ... }

Reads from the resource behind this URI. The first form returns the content of the resource, the second form yields to the block with each chunk of content (usually more than one).

For options, see URI.read.

# File lib/buildr/core/transports.rb, line 124
def read(options = nil, &block)
  fail 'This protocol doesn\t support reading (yet, how about helping by implementing it?)'
end
upload(source, options?) click to toggle source

Uploads from source to the resource.

The source may be a file name (string or task), in which case the file is uploaded to the resource. If the source is a directory, uploads all files inside the directory (including nested directories). The source may also be any object that responds to read (and optionally size), e.g. File, StringIO, Pipe.

Use the progress bar when running in verbose mode.

# File lib/buildr/core/transports.rb, line 197
def upload(source, options = nil)
  source = source.name if Rake::Task === source
  options ||= {}
  if String === source
    raise NotFoundError, 'No source file/directory to upload.' unless File.exist?(source)
    if File.directory?(source)
      Dir.glob("#{source}/**/*").reject { |file| File.directory?(file) }.each do |file|
        uri = self + (File.join(self.path, file.sub(source, '')))
        uri.upload file, {:digests=>[]}.merge(options)
      end
    else
      File.open(source, 'rb') { |input| upload input, options }
    end
  elsif source.respond_to?(:read)
    digests = (options[:digests] || [:md5, :sha1]).
      inject({}) { |hash, name| hash[name] = Digest.const_get(name.to_s.upcase).new ; hash }
    size = source.stat.size rescue nil
    write (options).merge(:progress=>verbose && size, :size=>size) do |bytes|
      source.read(bytes).tap do |chunk|
        digests.values.each { |digest| digest << chunk } if chunk
      end
    end
    digests.each do |key, digest|
      self.merge("#{self.path}.#{key}").write digest.hexdigest,
        (options).merge(:progress=>false)
    end
  else
    raise ArgumentError, 'Expecting source to be a file name (string, task) or any object that responds to read (file, pipe).'
  end
end
write(content, options?) click to toggle source
write(options?) { |bytes| .. }

Writes to the resource behind the URI. The first form writes the content from a string or an object that responds to read and optionally size. The second form writes the content by yielding to the block. Each yield should return up to the specified number of bytes, the last yield returns nil.

For options, see URI.write.

# File lib/buildr/core/transports.rb, line 171
def write(*args, &block)
  options = args.pop if Hash === args.last
  options ||= {}
  if String === args.first
    ios = StringIO.new(args.first, 'r')
    write(options.merge(:size=>args.first.size)) { |bytes| ios.read(bytes) }
  elsif args.first.respond_to?(:read)
    size = args.first.size rescue nil
    write({:size=>size}.merge(options)) { |bytes| args.first.read(bytes) }
  elsif args.empty? && block
    write_internal options, &block
  else
    raise ArgumentError, 'Either give me the content, or pass me a block, otherwise what would I upload?'
  end
end

Protected Instance Methods

proxy_uri → URI? click to toggle source

Returns the proxy server to use. Obtains the proxy from the relevant environment variable (e.g. HTTP_PROXY). Supports exclusions based on host name and port number from environment variable NO_PROXY.

# File lib/buildr/core/transports.rb, line 252
def proxy_uri
  proxy = ENV["#{scheme.upcase}_PROXY"]
  proxy = URI.parse(proxy) if String === proxy
  excludes = ENV['NO_PROXY'].to_s.split(/\s*,\s*/).compact
  excludes = excludes.map { |exclude| exclude =~ /:\d+$/ ? exclude : "#{exclude}:*" }
  return proxy unless excludes.any? { |exclude| File.fnmatch(exclude, "#{host}:#{port}") }
end