add smusher dep
							
								
								
									
										1
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						| 
						 | 
				
			
			@ -26,3 +26,4 @@ bin/spec
 | 
			
		|||
bin/sprocketize
 | 
			
		||||
bin/thin
 | 
			
		||||
bin/tt
 | 
			
		||||
bin/smusher
 | 
			
		||||
							
								
								
									
										1
									
								
								Gemfile
									
										
									
									
									
								
							
							
						
						| 
						 | 
				
			
			@ -11,6 +11,7 @@ gem "rack-test"
 | 
			
		|||
gem "yui-compressor"
 | 
			
		||||
gem "haml"
 | 
			
		||||
gem "compass"
 | 
			
		||||
gem "smusher"
 | 
			
		||||
 | 
			
		||||
gem "rspec"
 | 
			
		||||
gem "sdoc"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										1
									
								
								Rakefile
									
										
									
									
									
								
							
							
						
						| 
						 | 
				
			
			@ -21,6 +21,7 @@ begin
 | 
			
		|||
    gem.add_dependency("sinatra-content-for")
 | 
			
		||||
    gem.add_dependency("rack-test")
 | 
			
		||||
    gem.add_dependency("yui-compressor")
 | 
			
		||||
    gem.add_dependency("smusher")
 | 
			
		||||
    gem.add_dependency("haml", ">=2.1.0")
 | 
			
		||||
    gem.add_dependency("compass")
 | 
			
		||||
    gem.add_development_dependency("rspec")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,9 +26,9 @@ configure :build do
 | 
			
		|||
  # Shrink/smush PNG/JPEGs on build
 | 
			
		||||
  # enable :smush_pngs
 | 
			
		||||
  
 | 
			
		||||
  # Enable cache buster
 | 
			
		||||
  # enable :cache_buster
 | 
			
		||||
  
 | 
			
		||||
  # Or use a different image path
 | 
			
		||||
  # set :http_path, "/Content/images/"
 | 
			
		||||
  
 | 
			
		||||
  # Disable cache buster
 | 
			
		||||
  # disable :cache_buster
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								vendor/gems/cache/httpclient-2.1.5.2.gem
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								vendor/gems/cache/smusher-0.4.2.gem
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										98
									
								
								vendor/gems/environment.rb
									
										
									
									
										vendored
									
									
								
							
							
						
						| 
						 | 
				
			
			@ -6,64 +6,68 @@ module Bundler
 | 
			
		|||
  ENV["PATH"]     = "#{dir}/../../bin:#{ENV["PATH"]}"
 | 
			
		||||
  ENV["RUBYOPT"]  = "-r#{file} #{ENV["RUBYOPT"]}"
 | 
			
		||||
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/rdoc-2.4.3/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/rdoc-2.4.3/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/configuration-1.1.0/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/configuration-1.1.0/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/builder-2.1.2/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/builder-2.1.2/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/daemons-1.0.10/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/daemons-1.0.10/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/extlib-0.9.13/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/extlib-0.9.13/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/json-1.2.0/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/json-1.2.0/ext/json/ext")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/json-1.2.0/ext")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/json-1.2.0/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/eventmachine-0.12.10/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/eventmachine-0.12.10/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/rack-1.0.1/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/rack-1.0.1/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/shotgun-0.4/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/shotgun-0.4/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/rack-test-0.5.2/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/rack-test-0.5.2/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/sinatra-0.9.4/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/sinatra-0.9.4/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/thin-1.2.5/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/thin-1.2.5/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/sdoc-0.2.14.1/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/sdoc-0.2.14.1/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/yui-compressor-0.9.1/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/yui-compressor-0.9.1/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/polyglot-0.2.9/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/polyglot-0.2.9/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/treetop-1.4.2/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/treetop-1.4.2/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/rake-0.8.7/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/rake-0.8.7/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/launchy-0.3.3/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/launchy-0.3.3/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/sprockets-1.0.2/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/sprockets-1.0.2/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/haml-2.2.13/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/haml-2.2.13/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/diff-lcs-1.1.2/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/diff-lcs-1.1.2/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/rspec-1.2.9/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/rspec-1.2.9/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/highline-1.5.1/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/highline-1.5.1/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/templater-1.0.0/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/templater-1.0.0/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/term-ansicolor-1.0.4/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/term-ansicolor-1.0.4/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/extlib-0.9.13/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/extlib-0.9.13/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/highline-1.5.1/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/highline-1.5.1/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/diff-lcs-1.1.2/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/diff-lcs-1.1.2/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/cucumber-0.4.4/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/cucumber-0.4.4/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/sinatra-content-for-0.2/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/sinatra-content-for-0.2/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/rspec-1.2.9/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/rspec-1.2.9/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/templater-1.0.0/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/templater-1.0.0/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/eventmachine-0.12.10/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/eventmachine-0.12.10/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/daemons-1.0.10/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/daemons-1.0.10/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/haml-2.2.13/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/haml-2.2.13/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/httpclient-2.1.5.2/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/httpclient-2.1.5.2/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/json-1.2.0/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/json-1.2.0/ext/json/ext")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/json-1.2.0/ext")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/json-1.2.0/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/rake-0.8.7/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/rake-0.8.7/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/sprockets-1.0.2/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/sprockets-1.0.2/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/rack-1.0.1/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/rack-1.0.1/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/thin-1.2.5/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/thin-1.2.5/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/rack-test-0.5.2/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/rack-test-0.5.2/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/configuration-1.1.0/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/configuration-1.1.0/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/launchy-0.3.3/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/launchy-0.3.3/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/shotgun-0.4/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/shotgun-0.4/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/sinatra-0.9.4/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/sinatra-0.9.4/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/smusher-0.4.2/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/smusher-0.4.2/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/rdoc-2.4.3/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/rdoc-2.4.3/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/sdoc-0.2.14.1/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/sdoc-0.2.14.1/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/compass-0.8.17/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/compass-0.8.17/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/sinatra-content-for-0.2/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/sinatra-content-for-0.2/lib")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/yui-compressor-0.9.1/bin")
 | 
			
		||||
  $LOAD_PATH.unshift File.expand_path("#{dir}/gems/yui-compressor-0.9.1/lib")
 | 
			
		||||
 | 
			
		||||
  @gemfile = "#{dir}/../../Gemfile"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -134,7 +138,7 @@ end
 | 
			
		|||
 | 
			
		||||
# Define all the Gem errors for gems that reference them.
 | 
			
		||||
module Gem
 | 
			
		||||
  def self.ruby ; "/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby" ; end
 | 
			
		||||
  def self.ruby ; "/Users/tdreyno/homebrew/Cellar/ruby/1.9.1-p243/bin/ruby" ; end
 | 
			
		||||
  class LoadError < ::LoadError; end
 | 
			
		||||
  class Exception < RuntimeError; end
 | 
			
		||||
  class CommandLineError < Exception; end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										53
									
								
								vendor/gems/gems/httpclient-2.1.5.2/lib/http-access2.rb
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,53 @@
 | 
			
		|||
# HTTPAccess2 - HTTP accessing library.
 | 
			
		||||
# Copyright (C) 2000-2007  NAKAMURA, Hiroshi  <nakahiro@sarion.co.jp>.
 | 
			
		||||
 | 
			
		||||
# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
 | 
			
		||||
# redistribute it and/or modify it under the same terms of Ruby's license;
 | 
			
		||||
# either the dual license version in 2003, or any later version.
 | 
			
		||||
 | 
			
		||||
# http-access2.rb is based on http-access.rb in http-access/0.0.4.  Some part
 | 
			
		||||
# of code in http-access.rb was recycled in http-access2.rb.  Those part is
 | 
			
		||||
# copyrighted by Maehashi-san.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
require 'httpclient'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
module HTTPAccess2
 | 
			
		||||
  VERSION = ::HTTPClient::VERSION
 | 
			
		||||
  RUBY_VERSION_STRING = ::HTTPClient::RUBY_VERSION_STRING
 | 
			
		||||
  SSLEnabled = ::HTTPClient::SSLEnabled
 | 
			
		||||
  SSPIEnabled = ::HTTPClient::SSPIEnabled
 | 
			
		||||
  DEBUG_SSL = true
 | 
			
		||||
 | 
			
		||||
  Util = ::HTTPClient::Util
 | 
			
		||||
 | 
			
		||||
  class Client < ::HTTPClient
 | 
			
		||||
    class RetryableResponse < StandardError
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  SSLConfig = ::HTTPClient::SSLConfig
 | 
			
		||||
  BasicAuth = ::HTTPClient::BasicAuth
 | 
			
		||||
  DigestAuth = ::HTTPClient::DigestAuth
 | 
			
		||||
  NegotiateAuth = ::HTTPClient::NegotiateAuth
 | 
			
		||||
  AuthFilterBase = ::HTTPClient::AuthFilterBase
 | 
			
		||||
  WWWAuth = ::HTTPClient::WWWAuth
 | 
			
		||||
  ProxyAuth = ::HTTPClient::ProxyAuth
 | 
			
		||||
  Site = ::HTTPClient::Site
 | 
			
		||||
  Connection = ::HTTPClient::Connection
 | 
			
		||||
  SessionManager = ::HTTPClient::SessionManager
 | 
			
		||||
  SSLSocketWrap = ::HTTPClient::SSLSocketWrap
 | 
			
		||||
  DebugSocket = ::HTTPClient::DebugSocket
 | 
			
		||||
 | 
			
		||||
  class Session < ::HTTPClient::Session
 | 
			
		||||
    class Error < StandardError
 | 
			
		||||
    end
 | 
			
		||||
    class InvalidState < Error
 | 
			
		||||
    end
 | 
			
		||||
    class BadResponse < Error
 | 
			
		||||
    end
 | 
			
		||||
    class KeepAliveDisconnected < Error
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										1
									
								
								vendor/gems/gems/httpclient-2.1.5.2/lib/http-access2/cookie.rb
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
require 'httpclient/cookie'
 | 
			
		||||
							
								
								
									
										1
									
								
								vendor/gems/gems/httpclient-2.1.5.2/lib/http-access2/http.rb
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
require 'httpclient/http'
 | 
			
		||||
							
								
								
									
										1020
									
								
								vendor/gems/gems/httpclient-2.1.5.2/lib/httpclient.rb
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										522
									
								
								vendor/gems/gems/httpclient-2.1.5.2/lib/httpclient/auth.rb
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,522 @@
 | 
			
		|||
# HTTPClient - HTTP client library.
 | 
			
		||||
# Copyright (C) 2000-2009  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>.
 | 
			
		||||
#
 | 
			
		||||
# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
 | 
			
		||||
# redistribute it and/or modify it under the same terms of Ruby's license;
 | 
			
		||||
# either the dual license version in 2003, or any later version.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
require 'digest/md5'
 | 
			
		||||
require 'httpclient/session'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class HTTPClient
 | 
			
		||||
 | 
			
		||||
  begin
 | 
			
		||||
    require 'net/ntlm'
 | 
			
		||||
    NTLMEnabled = true
 | 
			
		||||
  rescue LoadError
 | 
			
		||||
    NTLMEnabled = false
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  begin
 | 
			
		||||
    require 'win32/sspi'
 | 
			
		||||
    SSPIEnabled = true
 | 
			
		||||
  rescue LoadError
 | 
			
		||||
    SSPIEnabled = false
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  # Common abstract class for authentication filter.
 | 
			
		||||
  #
 | 
			
		||||
  # There are 2 authentication filters.
 | 
			
		||||
  # WWWAuth:: Authentication filter for handling authentication negotiation
 | 
			
		||||
  #           between Web server.  Parses 'WWW-Authentication' header in
 | 
			
		||||
  #           response and generates 'Authorization' header in request.
 | 
			
		||||
  # ProxyAuth:: Authentication filter for handling authentication negotiation
 | 
			
		||||
  #             between Proxy server.  Parses 'Proxy-Authentication' header in
 | 
			
		||||
  #             response and generates 'Proxy-Authorization' header in request.
 | 
			
		||||
  class AuthFilterBase
 | 
			
		||||
  private
 | 
			
		||||
 | 
			
		||||
    def parse_authentication_header(res, tag)
 | 
			
		||||
      challenge = res.header[tag]
 | 
			
		||||
      return nil unless challenge
 | 
			
		||||
      challenge.collect { |c| parse_challenge_header(c) }.compact
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def parse_challenge_header(challenge)
 | 
			
		||||
      scheme, param_str = challenge.scan(/\A(\S+)(?:\s+(.*))?\z/)[0]
 | 
			
		||||
      return nil if scheme.nil?
 | 
			
		||||
      return scheme, param_str
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  # Authentication filter for handling authentication negotiation between
 | 
			
		||||
  # Web server.  Parses 'WWW-Authentication' header in response and
 | 
			
		||||
  # generates 'Authorization' header in request.
 | 
			
		||||
  #
 | 
			
		||||
  # Authentication filter is implemented using request filter of HTTPClient.
 | 
			
		||||
  # It traps HTTP response header and maintains authentication state, and
 | 
			
		||||
  # traps HTTP request header for inserting necessary authentication header.
 | 
			
		||||
  #
 | 
			
		||||
  # WWWAuth has sub filters (BasicAuth, DigestAuth, NegotiateAuth and
 | 
			
		||||
  # SSPINegotiateAuth) and delegates some operations to it.
 | 
			
		||||
  # NegotiateAuth requires 'ruby/ntlm' module.
 | 
			
		||||
  # SSPINegotiateAuth requires 'win32/sspi' module.
 | 
			
		||||
  class WWWAuth < AuthFilterBase
 | 
			
		||||
    attr_reader :basic_auth
 | 
			
		||||
    attr_reader :digest_auth
 | 
			
		||||
    attr_reader :negotiate_auth
 | 
			
		||||
    attr_reader :sspi_negotiate_auth
 | 
			
		||||
 | 
			
		||||
    # Creates new WWWAuth.
 | 
			
		||||
    def initialize
 | 
			
		||||
      @basic_auth = BasicAuth.new
 | 
			
		||||
      @digest_auth = DigestAuth.new
 | 
			
		||||
      @negotiate_auth = NegotiateAuth.new
 | 
			
		||||
      @sspi_negotiate_auth = SSPINegotiateAuth.new
 | 
			
		||||
      # sort authenticators by priority
 | 
			
		||||
      @authenticator = [@negotiate_auth, @sspi_negotiate_auth, @digest_auth, @basic_auth]
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Resets challenge state.  See sub filters for more details.
 | 
			
		||||
    def reset_challenge
 | 
			
		||||
      @authenticator.each do |auth|
 | 
			
		||||
        auth.reset_challenge
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Set authentication credential.  See sub filters for more details.
 | 
			
		||||
    def set_auth(uri, user, passwd)
 | 
			
		||||
      @authenticator.each do |auth|
 | 
			
		||||
        auth.set(uri, user, passwd)
 | 
			
		||||
      end
 | 
			
		||||
      reset_challenge
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Filter API implementation.  Traps HTTP request and insert
 | 
			
		||||
    # 'Authorization' header if needed.
 | 
			
		||||
    def filter_request(req)
 | 
			
		||||
      @authenticator.each do |auth|
 | 
			
		||||
        if cred = auth.get(req)
 | 
			
		||||
          req.header.set('Authorization', auth.scheme + " " + cred)
 | 
			
		||||
          return
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Filter API implementation.  Traps HTTP response and parses
 | 
			
		||||
    # 'WWW-Authenticate' header.
 | 
			
		||||
    def filter_response(req, res)
 | 
			
		||||
      command = nil
 | 
			
		||||
      if res.status == HTTP::Status::UNAUTHORIZED
 | 
			
		||||
        if challenge = parse_authentication_header(res, 'www-authenticate')
 | 
			
		||||
          uri = req.header.request_uri
 | 
			
		||||
          challenge.each do |scheme, param_str|
 | 
			
		||||
            @authenticator.each do |auth|
 | 
			
		||||
              if scheme.downcase == auth.scheme.downcase
 | 
			
		||||
                challengeable = auth.challenge(uri, param_str)
 | 
			
		||||
                command = :retry if challengeable
 | 
			
		||||
              end
 | 
			
		||||
            end
 | 
			
		||||
          end
 | 
			
		||||
          # ignore unknown authentication scheme
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
      command
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  # Authentication filter for handling authentication negotiation between
 | 
			
		||||
  # Proxy server.  Parses 'Proxy-Authentication' header in response and
 | 
			
		||||
  # generates 'Proxy-Authorization' header in request.
 | 
			
		||||
  #
 | 
			
		||||
  # Authentication filter is implemented using request filter of HTTPClient.
 | 
			
		||||
  # It traps HTTP response header and maintains authentication state, and
 | 
			
		||||
  # traps HTTP request header for inserting necessary authentication header.
 | 
			
		||||
  #
 | 
			
		||||
  # ProxyAuth has sub filters (BasicAuth, NegotiateAuth, and SSPINegotiateAuth)
 | 
			
		||||
  # and delegates some operations to it.
 | 
			
		||||
  # NegotiateAuth requires 'ruby/ntlm' module.
 | 
			
		||||
  # SSPINegotiateAuth requires 'win32/sspi' module.
 | 
			
		||||
  class ProxyAuth < AuthFilterBase
 | 
			
		||||
    attr_reader :basic_auth
 | 
			
		||||
    attr_reader :negotiate_auth
 | 
			
		||||
    attr_reader :sspi_negotiate_auth
 | 
			
		||||
 | 
			
		||||
    # Creates new ProxyAuth.
 | 
			
		||||
    def initialize
 | 
			
		||||
      @basic_auth = BasicAuth.new
 | 
			
		||||
      @negotiate_auth = NegotiateAuth.new
 | 
			
		||||
      @sspi_negotiate_auth = SSPINegotiateAuth.new
 | 
			
		||||
      # sort authenticators by priority
 | 
			
		||||
      @authenticator = [@negotiate_auth, @sspi_negotiate_auth, @basic_auth]
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Resets challenge state.  See sub filters for more details.
 | 
			
		||||
    def reset_challenge
 | 
			
		||||
      @authenticator.each do |auth|
 | 
			
		||||
        auth.reset_challenge
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Set authentication credential.  See sub filters for more details.
 | 
			
		||||
    def set_auth(user, passwd)
 | 
			
		||||
      @authenticator.each do |auth|
 | 
			
		||||
        auth.set(nil, user, passwd)
 | 
			
		||||
      end
 | 
			
		||||
      reset_challenge
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Filter API implementation.  Traps HTTP request and insert
 | 
			
		||||
    # 'Proxy-Authorization' header if needed.
 | 
			
		||||
    def filter_request(req)
 | 
			
		||||
      @authenticator.each do |auth|
 | 
			
		||||
        if cred = auth.get(req)
 | 
			
		||||
          req.header.set('Proxy-Authorization', auth.scheme + " " + cred)
 | 
			
		||||
          return
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Filter API implementation.  Traps HTTP response and parses
 | 
			
		||||
    # 'Proxy-Authenticate' header.
 | 
			
		||||
    def filter_response(req, res)
 | 
			
		||||
      command = nil
 | 
			
		||||
      if res.status == HTTP::Status::PROXY_AUTHENTICATE_REQUIRED
 | 
			
		||||
        if challenge = parse_authentication_header(res, 'proxy-authenticate')
 | 
			
		||||
          uri = req.header.request_uri
 | 
			
		||||
          challenge.each do |scheme, param_str|
 | 
			
		||||
            @authenticator.each do |auth|
 | 
			
		||||
              if scheme.downcase == auth.scheme.downcase
 | 
			
		||||
                challengeable = auth.challenge(uri, param_str)
 | 
			
		||||
                command = :retry if challengeable
 | 
			
		||||
              end
 | 
			
		||||
            end
 | 
			
		||||
          end
 | 
			
		||||
          # ignore unknown authentication scheme
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
      command
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # Authentication filter for handling BasicAuth negotiation.
 | 
			
		||||
  # Used in WWWAuth and ProxyAuth.
 | 
			
		||||
  class BasicAuth
 | 
			
		||||
    # Authentication scheme.
 | 
			
		||||
    attr_reader :scheme
 | 
			
		||||
 | 
			
		||||
    # Creates new BasicAuth filter.
 | 
			
		||||
    def initialize
 | 
			
		||||
      @cred = nil
 | 
			
		||||
      @auth = {}
 | 
			
		||||
      @challengeable = {}
 | 
			
		||||
      @scheme = "Basic"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Resets challenge state.  Do not send '*Authorization' header until the
 | 
			
		||||
    # server sends '*Authentication' again.
 | 
			
		||||
    def reset_challenge
 | 
			
		||||
      @challengeable.clear
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Set authentication credential.
 | 
			
		||||
    # uri == nil for generic purpose (allow to use user/password for any URL).
 | 
			
		||||
    def set(uri, user, passwd)
 | 
			
		||||
      if uri.nil?
 | 
			
		||||
        @cred = ["#{user}:#{passwd}"].pack('m').tr("\n", '')
 | 
			
		||||
      else
 | 
			
		||||
        uri = Util.uri_dirname(uri)
 | 
			
		||||
        @auth[uri] = ["#{user}:#{passwd}"].pack('m').tr("\n", '')
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Response handler: returns credential.
 | 
			
		||||
    # It sends cred only when a given uri is;
 | 
			
		||||
    # * child page of challengeable(got *Authenticate before) uri and,
 | 
			
		||||
    # * child page of defined credential
 | 
			
		||||
    def get(req)
 | 
			
		||||
      target_uri = req.header.request_uri
 | 
			
		||||
      return nil unless @challengeable.find { |uri, ok|
 | 
			
		||||
        Util.uri_part_of(target_uri, uri) and ok
 | 
			
		||||
      }
 | 
			
		||||
      return @cred if @cred
 | 
			
		||||
      Util.hash_find_value(@auth) { |uri, cred|
 | 
			
		||||
        Util.uri_part_of(target_uri, uri)
 | 
			
		||||
      }
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Challenge handler: remember URL for response.
 | 
			
		||||
    def challenge(uri, param_str)
 | 
			
		||||
      @challengeable[uri] = true
 | 
			
		||||
      true
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  # Authentication filter for handling DigestAuth negotiation.
 | 
			
		||||
  # Used in WWWAuth.
 | 
			
		||||
  class DigestAuth
 | 
			
		||||
    # Authentication scheme.
 | 
			
		||||
    attr_reader :scheme
 | 
			
		||||
 | 
			
		||||
    # Creates new DigestAuth filter.
 | 
			
		||||
    def initialize
 | 
			
		||||
      @auth = {}
 | 
			
		||||
      @challenge = {}
 | 
			
		||||
      @nonce_count = 0
 | 
			
		||||
      @scheme = "Digest"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Resets challenge state.  Do not send '*Authorization' header until the
 | 
			
		||||
    # server sends '*Authentication' again.
 | 
			
		||||
    def reset_challenge
 | 
			
		||||
      @challenge.clear
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Set authentication credential.
 | 
			
		||||
    # uri == nil is ignored.
 | 
			
		||||
    def set(uri, user, passwd)
 | 
			
		||||
      if uri
 | 
			
		||||
        uri = Util.uri_dirname(uri)
 | 
			
		||||
        @auth[uri] = [user, passwd]
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Response handler: returns credential.
 | 
			
		||||
    # It sends cred only when a given uri is;
 | 
			
		||||
    # * child page of challengeable(got *Authenticate before) uri and,
 | 
			
		||||
    # * child page of defined credential
 | 
			
		||||
    def get(req)
 | 
			
		||||
      target_uri = req.header.request_uri
 | 
			
		||||
      param = Util.hash_find_value(@challenge) { |uri, v|
 | 
			
		||||
        Util.uri_part_of(target_uri, uri)
 | 
			
		||||
      }
 | 
			
		||||
      return nil unless param
 | 
			
		||||
      user, passwd = Util.hash_find_value(@auth) { |uri, auth_data|
 | 
			
		||||
        Util.uri_part_of(target_uri, uri)
 | 
			
		||||
      }
 | 
			
		||||
      return nil unless user
 | 
			
		||||
      uri = req.header.request_uri
 | 
			
		||||
      calc_cred(req.header.request_method, uri, user, passwd, param)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Challenge handler: remember URL and challenge token for response.
 | 
			
		||||
    def challenge(uri, param_str)
 | 
			
		||||
      @challenge[uri] = parse_challenge_param(param_str)
 | 
			
		||||
      true
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
  private
 | 
			
		||||
 | 
			
		||||
    # this method is implemented by sromano and posted to
 | 
			
		||||
    # http://tools.assembla.com/breakout/wiki/DigestForSoap
 | 
			
		||||
    # Thanks!
 | 
			
		||||
    # supported algorithm: MD5 only for now
 | 
			
		||||
    def calc_cred(method, uri, user, passwd, param)
 | 
			
		||||
      a_1 = "#{user}:#{param['realm']}:#{passwd}"
 | 
			
		||||
      a_2 = "#{method}:#{uri.path}"
 | 
			
		||||
      nonce = param['nonce']
 | 
			
		||||
      cnonce = generate_cnonce()
 | 
			
		||||
      @nonce_count += 1
 | 
			
		||||
      message_digest = []
 | 
			
		||||
      message_digest << Digest::MD5.hexdigest(a_1)
 | 
			
		||||
      message_digest << nonce
 | 
			
		||||
      message_digest << ('%08x' % @nonce_count)
 | 
			
		||||
      message_digest << cnonce
 | 
			
		||||
      message_digest << param['qop']
 | 
			
		||||
      message_digest << Digest::MD5.hexdigest(a_2)
 | 
			
		||||
      header = []
 | 
			
		||||
      header << "username=\"#{user}\""
 | 
			
		||||
      header << "realm=\"#{param['realm']}\""
 | 
			
		||||
      header << "nonce=\"#{nonce}\""
 | 
			
		||||
      header << "uri=\"#{uri.path}\""
 | 
			
		||||
      header << "cnonce=\"#{cnonce}\""
 | 
			
		||||
      header << "nc=#{'%08x' % @nonce_count}"
 | 
			
		||||
      header << "qop=\"#{param['qop']}\""
 | 
			
		||||
      header << "response=\"#{Digest::MD5.hexdigest(message_digest.join(":"))}\""
 | 
			
		||||
      header << "algorithm=\"MD5\""
 | 
			
		||||
      header << "opaque=\"#{param['opaque']}\"" if param.key?('opaque')
 | 
			
		||||
      header.join(", ")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # cf. WEBrick::HTTPAuth::DigestAuth#generate_next_nonce(aTime)
 | 
			
		||||
    def generate_cnonce
 | 
			
		||||
      now = "%012d" % Time.now.to_i
 | 
			
		||||
      pk = Digest::MD5.hexdigest([now, self.__id__, Process.pid, rand(65535)].join)[0, 32]
 | 
			
		||||
      [now + ':' + pk].pack('m*').chop
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def parse_challenge_param(param_str)
 | 
			
		||||
      param = {}
 | 
			
		||||
      param_str.scan(/\s*([^\,]+(?:\\.[^\,]*)*)/).each do |str|
 | 
			
		||||
        key, value = str[0].scan(/\A([^=]+)=(.*)\z/)[0]
 | 
			
		||||
        if /\A"(.*)"\z/ =~ value
 | 
			
		||||
          value = $1.gsub(/\\(.)/, '\1')
 | 
			
		||||
        end
 | 
			
		||||
        param[key] = value
 | 
			
		||||
      end
 | 
			
		||||
      param
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  # Authentication filter for handling Negotiate/NTLM negotiation.
 | 
			
		||||
  # Used in WWWAuth and ProxyAuth.
 | 
			
		||||
  #
 | 
			
		||||
  # NegotiateAuth depends on 'ruby/ntlm' module.
 | 
			
		||||
  class NegotiateAuth
 | 
			
		||||
    # Authentication scheme.
 | 
			
		||||
    attr_reader :scheme
 | 
			
		||||
    # NTLM opt for ruby/ntlm.  {:ntlmv2 => true} by default.
 | 
			
		||||
    attr_reader :ntlm_opt
 | 
			
		||||
 | 
			
		||||
    # Creates new NegotiateAuth filter.
 | 
			
		||||
    def initialize
 | 
			
		||||
      @auth = {}
 | 
			
		||||
      @auth_default = nil
 | 
			
		||||
      @challenge = {}
 | 
			
		||||
      @scheme = "Negotiate"
 | 
			
		||||
      @ntlm_opt = {
 | 
			
		||||
        :ntlmv2 => true
 | 
			
		||||
      }
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Resets challenge state.  Do not send '*Authorization' header until the
 | 
			
		||||
    # server sends '*Authentication' again.
 | 
			
		||||
    def reset_challenge
 | 
			
		||||
      @challenge.clear
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Set authentication credential.
 | 
			
		||||
    # uri == nil for generic purpose (allow to use user/password for any URL).
 | 
			
		||||
    def set(uri, user, passwd)
 | 
			
		||||
      if uri
 | 
			
		||||
        uri = Util.uri_dirname(uri)
 | 
			
		||||
        @auth[uri] = [user, passwd]
 | 
			
		||||
      else
 | 
			
		||||
        @auth_default = [user, passwd]
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Response handler: returns credential.
 | 
			
		||||
    # See ruby/ntlm for negotiation state transition.
 | 
			
		||||
    def get(req)
 | 
			
		||||
      return nil unless NTLMEnabled
 | 
			
		||||
      target_uri = req.header.request_uri
 | 
			
		||||
      domain_uri, param = @challenge.find { |uri, v|
 | 
			
		||||
        Util.uri_part_of(target_uri, uri)
 | 
			
		||||
      }
 | 
			
		||||
      return nil unless param
 | 
			
		||||
      user, passwd = Util.hash_find_value(@auth) { |uri, auth_data|
 | 
			
		||||
        Util.uri_part_of(target_uri, uri)
 | 
			
		||||
      }
 | 
			
		||||
      unless user
 | 
			
		||||
        user, passwd = @auth_default
 | 
			
		||||
      end
 | 
			
		||||
      return nil unless user
 | 
			
		||||
      state = param[:state]
 | 
			
		||||
      authphrase = param[:authphrase]
 | 
			
		||||
      case state
 | 
			
		||||
      when :init
 | 
			
		||||
        t1 = Net::NTLM::Message::Type1.new
 | 
			
		||||
        return t1.encode64
 | 
			
		||||
      when :response
 | 
			
		||||
        t2 = Net::NTLM::Message.decode64(authphrase)
 | 
			
		||||
        t3 = t2.response({:user => user, :password => passwd}, @ntlm_opt.dup)
 | 
			
		||||
        @challenge.delete(domain_uri)
 | 
			
		||||
        return t3.encode64
 | 
			
		||||
      end
 | 
			
		||||
      nil
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Challenge handler: remember URL and challenge token for response.
 | 
			
		||||
    def challenge(uri, param_str)
 | 
			
		||||
      return false unless NTLMEnabled
 | 
			
		||||
      if param_str.nil? or @challenge[uri].nil?
 | 
			
		||||
        c = @challenge[uri] = {}
 | 
			
		||||
        c[:state] = :init
 | 
			
		||||
        c[:authphrase] = ""
 | 
			
		||||
      else
 | 
			
		||||
        c = @challenge[uri]
 | 
			
		||||
        c[:state] = :response
 | 
			
		||||
        c[:authphrase] = param_str
 | 
			
		||||
      end
 | 
			
		||||
      true
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  # Authentication filter for handling Negotiate/NTLM negotiation.
 | 
			
		||||
  # Used in ProxyAuth.
 | 
			
		||||
  #
 | 
			
		||||
  # SSPINegotiateAuth depends on 'win32/sspi' module.
 | 
			
		||||
  class SSPINegotiateAuth
 | 
			
		||||
    # Authentication scheme.
 | 
			
		||||
    attr_reader :scheme
 | 
			
		||||
 | 
			
		||||
    # Creates new SSPINegotiateAuth filter.
 | 
			
		||||
    def initialize
 | 
			
		||||
      @challenge = {}
 | 
			
		||||
      @scheme = "Negotiate"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Resets challenge state.  Do not send '*Authorization' header until the
 | 
			
		||||
    # server sends '*Authentication' again.
 | 
			
		||||
    def reset_challenge
 | 
			
		||||
      @challenge.clear
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Set authentication credential.
 | 
			
		||||
    # NOT SUPPORTED: username and necessary data is retrieved by win32/sspi.
 | 
			
		||||
    # See win32/sspi for more details.
 | 
			
		||||
    def set(uri, user, passwd)
 | 
			
		||||
      # not supported
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Response handler: returns credential.
 | 
			
		||||
    # See win32/sspi for negotiation state transition.
 | 
			
		||||
    def get(req)
 | 
			
		||||
      return nil unless SSPIEnabled
 | 
			
		||||
      target_uri = req.header.request_uri
 | 
			
		||||
      domain_uri, param = @challenge.find { |uri, v|
 | 
			
		||||
        Util.uri_part_of(target_uri, uri)
 | 
			
		||||
      }
 | 
			
		||||
      return nil unless param
 | 
			
		||||
      state = param[:state]
 | 
			
		||||
      authenticator = param[:authenticator]
 | 
			
		||||
      authphrase = param[:authphrase]
 | 
			
		||||
      case state
 | 
			
		||||
      when :init
 | 
			
		||||
        authenticator = param[:authenticator] = Win32::SSPI::NegotiateAuth.new
 | 
			
		||||
        return authenticator.get_initial_token(@scheme)
 | 
			
		||||
      when :response
 | 
			
		||||
        @challenge.delete(domain_uri)
 | 
			
		||||
        return authenticator.complete_authentication(authphrase)
 | 
			
		||||
      end
 | 
			
		||||
      nil
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Challenge handler: remember URL and challenge token for response.
 | 
			
		||||
    def challenge(uri, param_str)
 | 
			
		||||
      return false unless SSPIEnabled
 | 
			
		||||
      if param_str.nil? or @challenge[uri].nil?
 | 
			
		||||
        c = @challenge[uri] = {}
 | 
			
		||||
        c[:state] = :init
 | 
			
		||||
        c[:authenticator] = nil
 | 
			
		||||
        c[:authphrase] = ""
 | 
			
		||||
      else
 | 
			
		||||
        c = @challenge[uri]
 | 
			
		||||
        c[:state] = :response
 | 
			
		||||
        c[:authphrase] = param_str
 | 
			
		||||
      end
 | 
			
		||||
      true
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										1579
									
								
								vendor/gems/gems/httpclient-2.1.5.2/lib/httpclient/cacert.p7s
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										1579
									
								
								vendor/gems/gems/httpclient-2.1.5.2/lib/httpclient/cacert_sha1.p7s
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										84
									
								
								vendor/gems/gems/httpclient-2.1.5.2/lib/httpclient/connection.rb
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,84 @@
 | 
			
		|||
# HTTPClient - HTTP client library.
 | 
			
		||||
# Copyright (C) 2000-2009  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>.
 | 
			
		||||
#
 | 
			
		||||
# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
 | 
			
		||||
# redistribute it and/or modify it under the same terms of Ruby's license;
 | 
			
		||||
# either the dual license version in 2003, or any later version.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class HTTPClient
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  # Represents a HTTP response to an asynchronous request.  Async methods of
 | 
			
		||||
  # HTTPClient such as get_async, post_async, etc. returns an instance of
 | 
			
		||||
  # Connection.
 | 
			
		||||
  #
 | 
			
		||||
  # == How to use
 | 
			
		||||
  #
 | 
			
		||||
  # 1. Invoke HTTP method asynchronously and check if it's been finished
 | 
			
		||||
  #    periodically.
 | 
			
		||||
  #
 | 
			
		||||
  #     connection = clnt.post_async(url, body)
 | 
			
		||||
  #     print 'posting.'
 | 
			
		||||
  #     while true
 | 
			
		||||
  #       break if connection.finished?
 | 
			
		||||
  #       print '.'
 | 
			
		||||
  #       sleep 1
 | 
			
		||||
  #     end
 | 
			
		||||
  #     puts '.'
 | 
			
		||||
  #     res = connection.pop
 | 
			
		||||
  #     p res.status
 | 
			
		||||
  #
 | 
			
		||||
  # 2. Read the response as an IO.
 | 
			
		||||
  #
 | 
			
		||||
  #     connection = clnt.get_async('http://dev.ctor.org/')
 | 
			
		||||
  #     io = connection.pop.content
 | 
			
		||||
  #     while str = io.read(40)
 | 
			
		||||
  #       p str
 | 
			
		||||
  #     end
 | 
			
		||||
  class Connection
 | 
			
		||||
    attr_accessor :async_thread
 | 
			
		||||
 | 
			
		||||
    def initialize(header_queue = [], body_queue = []) # :nodoc:
 | 
			
		||||
      @headers = header_queue
 | 
			
		||||
      @body = body_queue
 | 
			
		||||
      @async_thread = nil
 | 
			
		||||
      @queue = Queue.new
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Checks if the asynchronous invocation has been finished or not.
 | 
			
		||||
    def finished?
 | 
			
		||||
      if !@async_thread
 | 
			
		||||
        # Not in async mode.
 | 
			
		||||
        true
 | 
			
		||||
      elsif @async_thread.alive?
 | 
			
		||||
        # Working...
 | 
			
		||||
        false
 | 
			
		||||
      else
 | 
			
		||||
        # Async thread have been finished.
 | 
			
		||||
        join
 | 
			
		||||
        true
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Retrieves a HTTP::Message instance of HTTP response.  Do not invoke this
 | 
			
		||||
    # method twice for now.  The second invocation will be blocked.
 | 
			
		||||
    def pop
 | 
			
		||||
      @queue.pop
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def push(result) # :nodoc:
 | 
			
		||||
      @queue.push(result)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Waits the completion of the asynchronous invocation.
 | 
			
		||||
    def join
 | 
			
		||||
      if @async_thread
 | 
			
		||||
        @async_thread.join
 | 
			
		||||
      end
 | 
			
		||||
      nil
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										562
									
								
								vendor/gems/gems/httpclient-2.1.5.2/lib/httpclient/cookie.rb
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,562 @@
 | 
			
		|||
# cookie.rb is redistributed file which is originally included in Webagent
 | 
			
		||||
# version 0.6.2 by TAKAHASHI `Maki' Masayoshi.  And it contains some bug fixes.
 | 
			
		||||
# You can download the entire package of Webagent from
 | 
			
		||||
# http://www.rubycolor.org/arc/.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Cookie class
 | 
			
		||||
#
 | 
			
		||||
# I refered to w3m's source to make these classes. Some comments
 | 
			
		||||
# are quoted from it. I'm thanksful for author(s) of it.
 | 
			
		||||
#
 | 
			
		||||
#    w3m homepage:  http://ei5nazha.yz.yamagata-u.ac.jp/~aito/w3m/eng/
 | 
			
		||||
 | 
			
		||||
require 'uri'
 | 
			
		||||
require 'time'
 | 
			
		||||
require 'monitor'
 | 
			
		||||
 | 
			
		||||
class WebAgent
 | 
			
		||||
 | 
			
		||||
  module CookieUtils
 | 
			
		||||
 | 
			
		||||
    def head_match?(str1, str2)
 | 
			
		||||
      str1 == str2[0, str1.length]
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def tail_match?(str1, str2)
 | 
			
		||||
      if str1.length > 0
 | 
			
		||||
	str1 == str2[-str1.length..-1].to_s
 | 
			
		||||
      else
 | 
			
		||||
	true
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def domain_match(host, domain)
 | 
			
		||||
      domainname = domain.sub(/\.\z/, '').downcase
 | 
			
		||||
      hostname = host.sub(/\.\z/, '').downcase
 | 
			
		||||
      case domain
 | 
			
		||||
      when /\d+\.\d+\.\d+\.\d+/
 | 
			
		||||
	return (hostname == domainname)
 | 
			
		||||
      when '.' 
 | 
			
		||||
	return true
 | 
			
		||||
      when /^\./
 | 
			
		||||
        # allows; host == rubyforge.org, domain == .rubyforge.org
 | 
			
		||||
	return tail_match?(domainname, '.' + hostname)
 | 
			
		||||
      else
 | 
			
		||||
	return (hostname == domainname)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def total_dot_num(string)
 | 
			
		||||
      string.scan(/\./).length()
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  class Cookie
 | 
			
		||||
    include CookieUtils
 | 
			
		||||
 | 
			
		||||
    attr_accessor :name, :value
 | 
			
		||||
    attr_accessor :domain, :path
 | 
			
		||||
    attr_accessor :expires      ## for Netscape Cookie
 | 
			
		||||
    attr_accessor :url
 | 
			
		||||
    attr_writer :use, :secure, :discard, :domain_orig, :path_orig, :override
 | 
			
		||||
 | 
			
		||||
    USE = 1
 | 
			
		||||
    SECURE = 2
 | 
			
		||||
    DOMAIN = 4
 | 
			
		||||
    PATH = 8
 | 
			
		||||
    DISCARD = 16
 | 
			
		||||
    OVERRIDE = 32
 | 
			
		||||
    OVERRIDE_OK = 32
 | 
			
		||||
 | 
			
		||||
    def initialize()
 | 
			
		||||
      @name = @value = @domain = @path = nil
 | 
			
		||||
      @expires = nil
 | 
			
		||||
      @url = nil
 | 
			
		||||
      @use = @secure = @discard = @domain_orig = @path_orig = @override = nil
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def discard?
 | 
			
		||||
      @discard
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def use?
 | 
			
		||||
      @use
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def secure?
 | 
			
		||||
      @secure
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def domain_orig?
 | 
			
		||||
      @domain_orig
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def path_orig?
 | 
			
		||||
      @path_orig
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def override?
 | 
			
		||||
      @override
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def flag
 | 
			
		||||
      flg = 0
 | 
			
		||||
      flg += USE  if @use
 | 
			
		||||
      flg += SECURE  if @secure
 | 
			
		||||
      flg += DOMAIN  if @domain_orig
 | 
			
		||||
      flg += PATH  if @path_orig
 | 
			
		||||
      flg += DISCARD if @discard
 | 
			
		||||
      flg += OVERRIDE if @override
 | 
			
		||||
      flg
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def set_flag(flag)
 | 
			
		||||
      flag = flag.to_i
 | 
			
		||||
      @use = true      if flag & USE > 0
 | 
			
		||||
      @secure = true   if flag & SECURE > 0
 | 
			
		||||
      @domain_orig = true if flag & DOMAIN > 0
 | 
			
		||||
      @path_orig = true if flag & PATH > 0
 | 
			
		||||
      @discard  = true if flag & DISCARD > 0
 | 
			
		||||
      @override = true if flag & OVERRIDE > 0
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def match?(url)
 | 
			
		||||
      domainname = url.host
 | 
			
		||||
      if (!domainname ||
 | 
			
		||||
	  !domain_match(domainname, @domain) ||
 | 
			
		||||
	  (@path && !head_match?(@path, url.path)) ||
 | 
			
		||||
	  (@secure && (url.scheme != 'https')) )
 | 
			
		||||
	return false
 | 
			
		||||
      else
 | 
			
		||||
	return true
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def join_quotedstr(array, sep)
 | 
			
		||||
      ret = Array.new()
 | 
			
		||||
      old_elem = nil
 | 
			
		||||
      array.each{|elem|
 | 
			
		||||
	if (elem.scan(/"/).length % 2) == 0
 | 
			
		||||
	  if old_elem
 | 
			
		||||
	    old_elem << sep << elem
 | 
			
		||||
	  else
 | 
			
		||||
	    ret << elem
 | 
			
		||||
	    old_elem = nil
 | 
			
		||||
	  end  
 | 
			
		||||
	else
 | 
			
		||||
	  if old_elem
 | 
			
		||||
	    old_elem << sep << elem
 | 
			
		||||
	    ret << old_elem
 | 
			
		||||
	    old_elem = nil
 | 
			
		||||
	  else
 | 
			
		||||
	    old_elem = elem.dup
 | 
			
		||||
	  end
 | 
			
		||||
	end
 | 
			
		||||
      }
 | 
			
		||||
      ret
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def parse(str, url)
 | 
			
		||||
      @url = url
 | 
			
		||||
      # TODO: should not depend on join_quotedstr. scan with escape like CSV.
 | 
			
		||||
      cookie_elem = str.split(/;/)
 | 
			
		||||
      cookie_elem = join_quotedstr(cookie_elem, ';')
 | 
			
		||||
      cookie_elem -= [""] # del empty elements, a cookie might included ";;"
 | 
			
		||||
      first_elem = cookie_elem.shift
 | 
			
		||||
      if first_elem !~ /([^=]*)(\=(.*))?/
 | 
			
		||||
	return
 | 
			
		||||
	## raise ArgumentError 'invalid cookie value'
 | 
			
		||||
      end
 | 
			
		||||
      @name = $1.strip
 | 
			
		||||
      @value = normalize_cookie_value($3)
 | 
			
		||||
      cookie_elem.each{|pair|
 | 
			
		||||
	key, value = pair.split(/=/, 2)  ## value may nil
 | 
			
		||||
	key.strip!
 | 
			
		||||
        value = normalize_cookie_value(value)
 | 
			
		||||
	case key.downcase
 | 
			
		||||
	when 'domain'
 | 
			
		||||
	  @domain = value
 | 
			
		||||
	when 'expires'
 | 
			
		||||
          @expires = nil
 | 
			
		||||
	  begin
 | 
			
		||||
	    @expires = Time.parse(value).gmtime() if value
 | 
			
		||||
	  rescue ArgumentError
 | 
			
		||||
	  end
 | 
			
		||||
	when 'path'
 | 
			
		||||
	  @path = value
 | 
			
		||||
	when 'secure'
 | 
			
		||||
	  @secure = true  ## value may nil, but must 'true'.
 | 
			
		||||
	else
 | 
			
		||||
	  ## ignore
 | 
			
		||||
	end
 | 
			
		||||
      }
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def normalize_cookie_value(value)
 | 
			
		||||
      if value
 | 
			
		||||
        value = value.strip.sub(/\A"(.*)"\z/) { $1 }
 | 
			
		||||
        value = nil if value.empty?
 | 
			
		||||
      end
 | 
			
		||||
      value
 | 
			
		||||
    end
 | 
			
		||||
    private :normalize_cookie_value
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  class CookieManager
 | 
			
		||||
    include CookieUtils
 | 
			
		||||
 | 
			
		||||
    ### errors
 | 
			
		||||
    class Error < StandardError; end
 | 
			
		||||
    class ErrorOverrideOK < Error; end
 | 
			
		||||
    class SpecialError < Error; end
 | 
			
		||||
 | 
			
		||||
    attr_reader :cookies
 | 
			
		||||
    attr_accessor :cookies_file
 | 
			
		||||
    attr_accessor :accept_domains, :reject_domains
 | 
			
		||||
 | 
			
		||||
    # for conformance to http://wp.netscape.com/newsref/std/cookie_spec.html
 | 
			
		||||
    attr_accessor :netscape_rule
 | 
			
		||||
    SPECIAL_DOMAIN = [".com",".edu",".gov",".mil",".net",".org",".int"]
 | 
			
		||||
 | 
			
		||||
    def initialize(file=nil)
 | 
			
		||||
      @cookies = Array.new()
 | 
			
		||||
      @cookies.extend(MonitorMixin)
 | 
			
		||||
      @cookies_file = file
 | 
			
		||||
      @is_saved = true
 | 
			
		||||
      @reject_domains = Array.new()
 | 
			
		||||
      @accept_domains = Array.new()
 | 
			
		||||
      @netscape_rule = false
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def cookies=(cookies)
 | 
			
		||||
      @cookies = cookies
 | 
			
		||||
      @cookies.extend(MonitorMixin)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def save_all_cookies(force = nil, save_unused = true, save_discarded = true)
 | 
			
		||||
      @cookies.synchronize do
 | 
			
		||||
        check_expired_cookies()
 | 
			
		||||
        if @is_saved and !force
 | 
			
		||||
          return
 | 
			
		||||
        end
 | 
			
		||||
        File.open(@cookies_file, 'w') do |f|
 | 
			
		||||
          @cookies.each do |cookie|
 | 
			
		||||
            if (cookie.use? or save_unused) and
 | 
			
		||||
                (!cookie.discard? or save_discarded)
 | 
			
		||||
              f.print(cookie.url.to_s,"\t",
 | 
			
		||||
                      cookie.name,"\t",
 | 
			
		||||
                      cookie.value,"\t",
 | 
			
		||||
                      cookie.expires.to_i,"\t",
 | 
			
		||||
                      cookie.domain,"\t",
 | 
			
		||||
                      cookie.path,"\t",
 | 
			
		||||
                      cookie.flag,"\n")
 | 
			
		||||
            end
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
      @is_saved = true
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def save_cookies(force = nil)
 | 
			
		||||
      save_all_cookies(force, false, false)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def check_expired_cookies()
 | 
			
		||||
      @cookies.reject!{|cookie|
 | 
			
		||||
        is_expired = (cookie.expires && (cookie.expires < Time.now.gmtime))
 | 
			
		||||
        if is_expired && !cookie.discard?
 | 
			
		||||
          @is_saved = false
 | 
			
		||||
        end
 | 
			
		||||
        is_expired
 | 
			
		||||
      }
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def parse(str, url)
 | 
			
		||||
      cookie = WebAgent::Cookie.new()
 | 
			
		||||
      cookie.parse(str, url)
 | 
			
		||||
      add(cookie)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def make_cookie_str(cookie_list)
 | 
			
		||||
      if cookie_list.empty?
 | 
			
		||||
	return nil
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      ret = ''
 | 
			
		||||
      c = cookie_list.shift
 | 
			
		||||
      ret += "#{c.name}=#{c.value}"
 | 
			
		||||
      cookie_list.each{|cookie|
 | 
			
		||||
	ret += "; #{cookie.name}=#{cookie.value}"
 | 
			
		||||
      }
 | 
			
		||||
      return ret
 | 
			
		||||
    end
 | 
			
		||||
    private :make_cookie_str
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def find(url)
 | 
			
		||||
      return nil if @cookies.empty?
 | 
			
		||||
 | 
			
		||||
      cookie_list = Array.new()
 | 
			
		||||
      @cookies.each{|cookie|
 | 
			
		||||
        is_expired = (cookie.expires && (cookie.expires < Time.now.gmtime))
 | 
			
		||||
        if cookie.use? && !is_expired && cookie.match?(url)
 | 
			
		||||
          if cookie_list.select{|c1| c1.name == cookie.name}.empty?
 | 
			
		||||
            cookie_list << cookie
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      }
 | 
			
		||||
      return make_cookie_str(cookie_list)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def find_cookie_info(domain, path, name)
 | 
			
		||||
      @cookies.find{|c|
 | 
			
		||||
	c.domain == domain && c.path == path && c.name == name
 | 
			
		||||
      }
 | 
			
		||||
    end
 | 
			
		||||
    private :find_cookie_info
 | 
			
		||||
 | 
			
		||||
    # not tested well; used only netscape_rule = true.
 | 
			
		||||
    def cookie_error(err, override)
 | 
			
		||||
      if !err.kind_of?(ErrorOverrideOK) || !override
 | 
			
		||||
	raise err
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
    private :cookie_error
 | 
			
		||||
 | 
			
		||||
    def add(cookie)
 | 
			
		||||
      url = cookie.url
 | 
			
		||||
      name, value = cookie.name, cookie.value
 | 
			
		||||
      expires, domain, path = 
 | 
			
		||||
	cookie.expires, cookie.domain, cookie.path
 | 
			
		||||
      secure, domain_orig, path_orig = 
 | 
			
		||||
	cookie.secure?, cookie.domain_orig?, cookie.path_orig?
 | 
			
		||||
      discard, override = 
 | 
			
		||||
	cookie.discard?, cookie.override?
 | 
			
		||||
 | 
			
		||||
      domainname = url.host
 | 
			
		||||
      domain_orig, path_orig = domain, path
 | 
			
		||||
      use_security = override
 | 
			
		||||
 | 
			
		||||
      if domain
 | 
			
		||||
 | 
			
		||||
	# [DRAFT 12] s. 4.2.2 (does not apply in the case that
 | 
			
		||||
	# host name is the same as domain attribute for version 0
 | 
			
		||||
	# cookie)
 | 
			
		||||
	# I think that this rule has almost the same effect as the
 | 
			
		||||
	# tail match of [NETSCAPE].
 | 
			
		||||
	if domain !~ /^\./ && domainname != domain
 | 
			
		||||
	  domain = '.'+domain
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
        # [NETSCAPE] rule
 | 
			
		||||
        if @netscape_rule
 | 
			
		||||
          n = total_dot_num(domain)
 | 
			
		||||
          if n < 2
 | 
			
		||||
            cookie_error(SpecialError.new(), override)
 | 
			
		||||
          elsif n == 2
 | 
			
		||||
            ## [NETSCAPE] rule
 | 
			
		||||
            ok = SPECIAL_DOMAIN.select{|sdomain|
 | 
			
		||||
              sdomain == domain[-(sdomain.length)..-1]
 | 
			
		||||
            }
 | 
			
		||||
            if ok.empty?
 | 
			
		||||
              cookie_error(SpecialError.new(), override)
 | 
			
		||||
            end
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        # this implementation does not check RFC2109 4.3.2 case 2;
 | 
			
		||||
        # the portion of host not in domain does not contain a dot.
 | 
			
		||||
        # according to nsCookieService.cpp in Firefox 3.0.4, Firefox 3.0.4
 | 
			
		||||
        # and IE does not check, too.
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      path ||= url.path.sub(%r|/[^/]*|, '')
 | 
			
		||||
      domain ||= domainname
 | 
			
		||||
      @cookies.synchronize do
 | 
			
		||||
        cookie = find_cookie_info(domain, path, name)
 | 
			
		||||
        if !cookie
 | 
			
		||||
          cookie = WebAgent::Cookie.new()
 | 
			
		||||
          cookie.use = true
 | 
			
		||||
          @cookies << cookie
 | 
			
		||||
        end
 | 
			
		||||
        check_expired_cookies()
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      cookie.url = url
 | 
			
		||||
      cookie.name = name
 | 
			
		||||
      cookie.value = value
 | 
			
		||||
      cookie.expires = expires
 | 
			
		||||
      cookie.domain = domain
 | 
			
		||||
      cookie.path = path
 | 
			
		||||
 | 
			
		||||
      ## for flag
 | 
			
		||||
      cookie.secure = secure
 | 
			
		||||
      cookie.domain_orig = domain_orig
 | 
			
		||||
      cookie.path_orig = path_orig
 | 
			
		||||
      if discard || cookie.expires == nil
 | 
			
		||||
	cookie.discard = true
 | 
			
		||||
      else
 | 
			
		||||
	cookie.discard = false
 | 
			
		||||
	@is_saved = false
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def load_cookies()
 | 
			
		||||
      return if !File.readable?(@cookies_file)
 | 
			
		||||
      @cookies.synchronize do
 | 
			
		||||
        @cookies.clear
 | 
			
		||||
        File.open(@cookies_file,'r'){|f|
 | 
			
		||||
          while line = f.gets
 | 
			
		||||
            cookie = WebAgent::Cookie.new()
 | 
			
		||||
            @cookies << cookie
 | 
			
		||||
            col = line.chomp.split(/\t/)
 | 
			
		||||
            cookie.url = URI.parse(col[0])
 | 
			
		||||
            cookie.name = col[1]
 | 
			
		||||
            cookie.value = col[2]
 | 
			
		||||
            if col[3].empty? or col[3] == '0'
 | 
			
		||||
              cookie.expires = nil
 | 
			
		||||
            else
 | 
			
		||||
              cookie.expires = Time.at(col[3].to_i).gmtime
 | 
			
		||||
            end
 | 
			
		||||
            cookie.domain = col[4]
 | 
			
		||||
            cookie.path = col[5]
 | 
			
		||||
            cookie.set_flag(col[6])
 | 
			
		||||
          end
 | 
			
		||||
        }
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def check_cookie_accept_domain(domain)
 | 
			
		||||
      unless domain
 | 
			
		||||
	return false
 | 
			
		||||
      end
 | 
			
		||||
      @accept_domains.each{|dom|
 | 
			
		||||
	if domain_match(domain, dom)
 | 
			
		||||
	  return true
 | 
			
		||||
	end
 | 
			
		||||
      }
 | 
			
		||||
      @reject_domains.each{|dom|
 | 
			
		||||
	if domain_match(domain, dom)
 | 
			
		||||
	  return false
 | 
			
		||||
	end
 | 
			
		||||
      }
 | 
			
		||||
      return true
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
__END__
 | 
			
		||||
 | 
			
		||||
=begin
 | 
			
		||||
 | 
			
		||||
== WebAgent::CookieManager Class
 | 
			
		||||
 | 
			
		||||
Load, save, parse and send cookies.
 | 
			
		||||
 | 
			
		||||
=== Usage
 | 
			
		||||
 | 
			
		||||
  ## initialize
 | 
			
		||||
  cm = WebAgent::CookieManager.new("/home/foo/bar/cookie")
 | 
			
		||||
 | 
			
		||||
  ## load cookie data
 | 
			
		||||
  cm.load_cookies()
 | 
			
		||||
 | 
			
		||||
  ## parse cookie from string (maybe "Set-Cookie:" header)
 | 
			
		||||
  cm.parse(str)
 | 
			
		||||
 | 
			
		||||
  ## send cookie data to url
 | 
			
		||||
  f.write(cm.find(url))
 | 
			
		||||
 | 
			
		||||
  ## save cookie to cookiefile
 | 
			
		||||
  cm.save_cookies()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
=== Class Methods
 | 
			
		||||
 | 
			
		||||
 -- CookieManager::new(file=nil)
 | 
			
		||||
 | 
			
		||||
     create new CookieManager. If a file is provided,
 | 
			
		||||
     use it as cookies' file.
 | 
			
		||||
 | 
			
		||||
=== Methods
 | 
			
		||||
 | 
			
		||||
 -- CookieManager#save_cookies(force = nil)
 | 
			
		||||
 | 
			
		||||
     save cookies' data into file. if argument is true,
 | 
			
		||||
     save data although data is not modified.
 | 
			
		||||
 | 
			
		||||
 -- CookieManager#parse(str, url)
 | 
			
		||||
 | 
			
		||||
     parse string and store cookie (to parse HTTP response header).
 | 
			
		||||
 | 
			
		||||
 -- CookieManager#find(url)
 | 
			
		||||
 | 
			
		||||
     get cookies and make into string (to send as HTTP request header).
 | 
			
		||||
 | 
			
		||||
 -- CookieManager#add(cookie)
 | 
			
		||||
 | 
			
		||||
     add new cookie.
 | 
			
		||||
 | 
			
		||||
 -- CookieManager#load_cookies()
 | 
			
		||||
 | 
			
		||||
     load cookies' data from file.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
== WebAgent::CookieUtils Module
 | 
			
		||||
 | 
			
		||||
 -- CookieUtils::head_match?(str1, str2)
 | 
			
		||||
 -- CookieUtils::tail_match?(str1, str2)
 | 
			
		||||
 -- CookieUtils::domain_match(host, domain)
 | 
			
		||||
 -- CookieUtils::total_dot_num(str)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
== WebAgent::Cookie Class
 | 
			
		||||
 | 
			
		||||
=== Class Methods
 | 
			
		||||
 | 
			
		||||
 -- Cookie::new()
 | 
			
		||||
 | 
			
		||||
      create new cookie.
 | 
			
		||||
 | 
			
		||||
=== Methods
 | 
			
		||||
 | 
			
		||||
 -- Cookie#match?(url)
 | 
			
		||||
 | 
			
		||||
       match cookie by url. if match, return true. otherwise,
 | 
			
		||||
       return false.
 | 
			
		||||
 | 
			
		||||
 -- Cookie#name
 | 
			
		||||
 -- Cookie#name=(name)
 | 
			
		||||
 -- Cookie#value
 | 
			
		||||
 -- Cookie#value=(value)
 | 
			
		||||
 -- Cookie#domain
 | 
			
		||||
 -- Cookie#domain=(domain)
 | 
			
		||||
 -- Cookie#path
 | 
			
		||||
 -- Cookie#path=(path)
 | 
			
		||||
 -- Cookie#expires
 | 
			
		||||
 -- Cookie#expires=(expires)
 | 
			
		||||
 -- Cookie#url
 | 
			
		||||
 -- Cookie#url=(url)
 | 
			
		||||
 | 
			
		||||
      accessor methods for cookie's items.
 | 
			
		||||
 | 
			
		||||
 -- Cookie#discard?
 | 
			
		||||
 -- Cookie#discard=(discard)
 | 
			
		||||
 -- Cookie#use?
 | 
			
		||||
 -- Cookie#use=(use)
 | 
			
		||||
 -- Cookie#secure?
 | 
			
		||||
 -- Cookie#secure=(secure)
 | 
			
		||||
 -- Cookie#domain_orig?
 | 
			
		||||
 -- Cookie#domain_orig=(domain_orig)
 | 
			
		||||
 -- Cookie#path_orig?
 | 
			
		||||
 -- Cookie#path_orig=(path_orig)
 | 
			
		||||
 -- Cookie#override?
 | 
			
		||||
 -- Cookie#override=(override)
 | 
			
		||||
 -- Cookie#flag
 | 
			
		||||
 -- Cookie#set_flag(flag_num)
 | 
			
		||||
 | 
			
		||||
      accessor methods for flags.
 | 
			
		||||
 | 
			
		||||
=end
 | 
			
		||||
							
								
								
									
										867
									
								
								vendor/gems/gems/httpclient-2.1.5.2/lib/httpclient/http.rb
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,867 @@
 | 
			
		|||
# HTTPClient - HTTP client library.
 | 
			
		||||
# Copyright (C) 2000-2009  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>.
 | 
			
		||||
#
 | 
			
		||||
# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
 | 
			
		||||
# redistribute it and/or modify it under the same terms of Ruby's license;
 | 
			
		||||
# either the dual license version in 2003, or any later version.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
require 'time'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# A namespace module for HTTP Message definitions used by HTTPClient.
 | 
			
		||||
module HTTP
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  # Represents HTTP response status code.  Defines constants for HTTP response
 | 
			
		||||
  # and some conditional methods.
 | 
			
		||||
  module Status
 | 
			
		||||
    OK = 200
 | 
			
		||||
    CREATED = 201
 | 
			
		||||
    ACCEPTED = 202
 | 
			
		||||
    NON_AUTHORITATIVE_INFORMATION = 203
 | 
			
		||||
    NO_CONTENT = 204
 | 
			
		||||
    RESET_CONTENT = 205
 | 
			
		||||
    PARTIAL_CONTENT = 206
 | 
			
		||||
    MOVED_PERMANENTLY = 301
 | 
			
		||||
    FOUND = 302
 | 
			
		||||
    SEE_OTHER = 303
 | 
			
		||||
    TEMPORARY_REDIRECT = MOVED_TEMPORARILY = 307
 | 
			
		||||
    BAD_REQUEST = 400
 | 
			
		||||
    UNAUTHORIZED = 401
 | 
			
		||||
    PROXY_AUTHENTICATE_REQUIRED = 407
 | 
			
		||||
    INTERNAL = 500
 | 
			
		||||
 | 
			
		||||
    # Status codes for successful HTTP response.
 | 
			
		||||
    SUCCESSFUL_STATUS = [
 | 
			
		||||
      OK, CREATED, ACCEPTED,
 | 
			
		||||
      NON_AUTHORITATIVE_INFORMATION, NO_CONTENT,
 | 
			
		||||
      RESET_CONTENT, PARTIAL_CONTENT
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    # Status codes which is a redirect.
 | 
			
		||||
    REDIRECT_STATUS = [
 | 
			
		||||
      MOVED_PERMANENTLY, FOUND, SEE_OTHER,
 | 
			
		||||
      TEMPORARY_REDIRECT, MOVED_TEMPORARILY
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    # Returns true if the given status represents successful HTTP response.
 | 
			
		||||
    # See also SUCCESSFUL_STATUS.
 | 
			
		||||
    def self.successful?(status)
 | 
			
		||||
      SUCCESSFUL_STATUS.include?(status)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Returns true if the given status is thought to be redirect.
 | 
			
		||||
    # See also REDIRECT_STATUS.
 | 
			
		||||
    def self.redirect?(status)
 | 
			
		||||
      REDIRECT_STATUS.include?(status)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  # Represents a HTTP message.  A message is for a request or a response.
 | 
			
		||||
  #
 | 
			
		||||
  # Request message is generated from given parameters internally so users
 | 
			
		||||
  # don't need to care about it.  Response message is the instance that
 | 
			
		||||
  # methods of HTTPClient returns so users need to know how to extract
 | 
			
		||||
  # HTTP response data from Message.
 | 
			
		||||
  #
 | 
			
		||||
  # Some attributes are only for a request or a response, not both.
 | 
			
		||||
  #
 | 
			
		||||
  # == How to use HTTP response message
 | 
			
		||||
  #
 | 
			
		||||
  # 1. Gets response message body.
 | 
			
		||||
  #
 | 
			
		||||
  #     res = clnt.get(url)
 | 
			
		||||
  #     p res.content #=> String
 | 
			
		||||
  #
 | 
			
		||||
  # 2. Gets response status code.
 | 
			
		||||
  #
 | 
			
		||||
  #     res = clnt.get(url)
 | 
			
		||||
  #     p res.status #=> 200, 501, etc. (Integer)
 | 
			
		||||
  #
 | 
			
		||||
  # 3. Gets response header.
 | 
			
		||||
  #
 | 
			
		||||
  #     res = clnt.get(url)
 | 
			
		||||
  #     res.header['set-cookie'].each do |value|
 | 
			
		||||
  #       p value
 | 
			
		||||
  #     end
 | 
			
		||||
  #     assert_equal(1, res.header['last-modified'].size)
 | 
			
		||||
  #     p res.header['last-modified'].first
 | 
			
		||||
  #
 | 
			
		||||
  class Message
 | 
			
		||||
 | 
			
		||||
    CRLF = "\r\n"
 | 
			
		||||
 | 
			
		||||
    # Represents HTTP message header.
 | 
			
		||||
    class Headers
 | 
			
		||||
      # HTTP version in a HTTP header.  Float.
 | 
			
		||||
      attr_accessor :http_version
 | 
			
		||||
      # Size of body.  nil when size is unknown (e.g. chunked response).
 | 
			
		||||
      attr_reader :body_size
 | 
			
		||||
      # Request/Response is chunked or not.
 | 
			
		||||
      attr_accessor :chunked
 | 
			
		||||
 | 
			
		||||
      # Request only.  Requested method.
 | 
			
		||||
      attr_reader :request_method
 | 
			
		||||
      # Request only.  Requested URI.
 | 
			
		||||
      attr_accessor :request_uri
 | 
			
		||||
      # Request only.  Requested query.
 | 
			
		||||
      attr_accessor :request_query
 | 
			
		||||
      # Request only.  Requested via proxy or not.
 | 
			
		||||
      attr_accessor :request_via_proxy
 | 
			
		||||
 | 
			
		||||
      # Response only.  HTTP status
 | 
			
		||||
      attr_reader :status_code
 | 
			
		||||
      # Response only.  HTTP status reason phrase.
 | 
			
		||||
      attr_accessor :reason_phrase
 | 
			
		||||
 | 
			
		||||
      # Used for dumping response.
 | 
			
		||||
      attr_accessor :body_type # :nodoc:
 | 
			
		||||
      # Used for dumping response.
 | 
			
		||||
      attr_accessor :body_charset # :nodoc:
 | 
			
		||||
      # Used for dumping response.
 | 
			
		||||
      attr_accessor :body_date # :nodoc:
 | 
			
		||||
 | 
			
		||||
      # HTTP response status code to reason phrase mapping definition.
 | 
			
		||||
      STATUS_CODE_MAP = {
 | 
			
		||||
        Status::OK => 'OK',
 | 
			
		||||
        Status::CREATED => "Created",
 | 
			
		||||
        Status::NON_AUTHORITATIVE_INFORMATION => "Non-Authoritative Information",
 | 
			
		||||
        Status::NO_CONTENT => "No Content",
 | 
			
		||||
        Status::RESET_CONTENT => "Reset Content",
 | 
			
		||||
        Status::PARTIAL_CONTENT => "Partial Content",
 | 
			
		||||
        Status::MOVED_PERMANENTLY => 'Moved Permanently',
 | 
			
		||||
        Status::FOUND => 'Found',
 | 
			
		||||
        Status::SEE_OTHER => 'See Other',
 | 
			
		||||
        Status::TEMPORARY_REDIRECT => 'Temporary Redirect',
 | 
			
		||||
        Status::MOVED_TEMPORARILY => 'Temporary Redirect',
 | 
			
		||||
        Status::BAD_REQUEST => 'Bad Request',
 | 
			
		||||
        Status::INTERNAL => 'Internal Server Error',
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      # $KCODE to charset mapping definition.
 | 
			
		||||
      CHARSET_MAP = {
 | 
			
		||||
        'NONE' => 'us-ascii',
 | 
			
		||||
        'EUC'  => 'euc-jp',
 | 
			
		||||
        'SJIS' => 'shift_jis',
 | 
			
		||||
        'UTF8' => 'utf-8',
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      # Creates a Message::Headers.  Use init_request, init_response, or
 | 
			
		||||
      # init_connect_request for acutual initialize.
 | 
			
		||||
      def initialize
 | 
			
		||||
        @http_version = 1.1
 | 
			
		||||
        @body_size = nil
 | 
			
		||||
        @chunked = false
 | 
			
		||||
 | 
			
		||||
        @request_method = nil
 | 
			
		||||
        @request_uri = nil
 | 
			
		||||
        @request_query = nil
 | 
			
		||||
        @request_via_proxy = nil
 | 
			
		||||
 | 
			
		||||
        @status_code = nil
 | 
			
		||||
        @reason_phrase = nil
 | 
			
		||||
 | 
			
		||||
        @body_type = nil
 | 
			
		||||
        @body_charset = nil
 | 
			
		||||
        @body_date = nil
 | 
			
		||||
 | 
			
		||||
        @is_request = nil
 | 
			
		||||
        @header_item = []
 | 
			
		||||
        @dumped = false
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Initialize this instance as a CONNECT request.
 | 
			
		||||
      def init_connect_request(uri)
 | 
			
		||||
        @is_request = true
 | 
			
		||||
        @request_method = 'CONNECT'
 | 
			
		||||
        @request_uri = uri
 | 
			
		||||
        @request_query = nil
 | 
			
		||||
        @http_version = 1.0
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Placeholder URI object for nil uri.
 | 
			
		||||
      NIL_URI = URI.parse('http://nil-uri-given/')
 | 
			
		||||
      # Initialize this instance as a general request.
 | 
			
		||||
      def init_request(method, uri, query = nil)
 | 
			
		||||
        @is_request = true
 | 
			
		||||
        @request_method = method
 | 
			
		||||
        @request_uri = uri || NIL_URI
 | 
			
		||||
        @request_query = query
 | 
			
		||||
        @request_via_proxy = false
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Initialize this instance as a response.
 | 
			
		||||
      def init_response(status_code)
 | 
			
		||||
        @is_request = false
 | 
			
		||||
        self.status_code = status_code
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Sets status code and reason phrase.
 | 
			
		||||
      def status_code=(status_code)
 | 
			
		||||
        @status_code = status_code
 | 
			
		||||
        @reason_phrase = STATUS_CODE_MAP[@status_code]
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Returns 'Content-Type' header value.
 | 
			
		||||
      def contenttype
 | 
			
		||||
        self['Content-Type'][0]
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Sets 'Content-Type' header value.  Overrides if already exists.
 | 
			
		||||
      def contenttype=(contenttype)
 | 
			
		||||
        delete('Content-Type')
 | 
			
		||||
        self['Content-Type'] = contenttype
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Sets byte size of message body.
 | 
			
		||||
      # body_size == nil means that the body is_a? IO
 | 
			
		||||
      def body_size=(body_size)
 | 
			
		||||
        @body_size = body_size
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Dumps message header part and returns a dumped String.
 | 
			
		||||
      def dump
 | 
			
		||||
        set_header
 | 
			
		||||
        str = nil
 | 
			
		||||
        if @is_request
 | 
			
		||||
          str = request_line
 | 
			
		||||
        else
 | 
			
		||||
          str = response_status_line
 | 
			
		||||
        end
 | 
			
		||||
        str + @header_item.collect { |key, value|
 | 
			
		||||
          "#{ key }: #{ value }#{ CRLF }"
 | 
			
		||||
        }.join
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Adds a header.  Addition order is preserved.
 | 
			
		||||
      def add(key, value)
 | 
			
		||||
        if value.is_a?(Array)
 | 
			
		||||
          value.each do |v|
 | 
			
		||||
            @header_item.push([key, v])
 | 
			
		||||
          end
 | 
			
		||||
        else
 | 
			
		||||
          @header_item.push([key, value])
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Sets a header.
 | 
			
		||||
      def set(key, value)
 | 
			
		||||
        delete(key)
 | 
			
		||||
        add(key, value)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Returns an Array of headers for the given key.  Each element is a pair
 | 
			
		||||
      # of key and value.  It returns an single element Array even if the only
 | 
			
		||||
      # one header exists.  If nil key given, it returns all headers.
 | 
			
		||||
      def get(key = nil)
 | 
			
		||||
        if key.nil?
 | 
			
		||||
          all
 | 
			
		||||
        else
 | 
			
		||||
          key = key.upcase
 | 
			
		||||
          @header_item.find_all { |k, v| k.upcase == key }
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Returns an Array of all headers.
 | 
			
		||||
      def all
 | 
			
		||||
        @header_item
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Deletes headers of the given key.
 | 
			
		||||
      def delete(key)
 | 
			
		||||
        key = key.upcase
 | 
			
		||||
        @header_item.delete_if { |k, v| k.upcase == key }
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Adds a header.  See set.
 | 
			
		||||
      def []=(key, value)
 | 
			
		||||
        set(key, value)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Returns an Array of header values for the given key.
 | 
			
		||||
      def [](key)
 | 
			
		||||
        get(key).collect { |item| item[1] }
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
    private
 | 
			
		||||
 | 
			
		||||
      def request_line
 | 
			
		||||
        path = create_query_uri(@request_uri, @request_query)
 | 
			
		||||
        if @request_via_proxy
 | 
			
		||||
          path = "#{ @request_uri.scheme }://#{ @request_uri.host }:#{ @request_uri.port }#{ path }"
 | 
			
		||||
        end
 | 
			
		||||
        "#{ @request_method } #{ path } HTTP/#{ @http_version }#{ CRLF }"
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def response_status_line
 | 
			
		||||
        if defined?(Apache)
 | 
			
		||||
          "HTTP/#{ @http_version } #{ @status_code } #{ @reason_phrase }#{ CRLF }"
 | 
			
		||||
        else
 | 
			
		||||
          "Status: #{ @status_code } #{ @reason_phrase }#{ CRLF }"
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def set_header
 | 
			
		||||
        if @is_request
 | 
			
		||||
          set_request_header
 | 
			
		||||
        else
 | 
			
		||||
          set_response_header
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def set_request_header
 | 
			
		||||
        return if @dumped
 | 
			
		||||
        @dumped = true
 | 
			
		||||
        keep_alive = Message.keep_alive_enabled?(@http_version)
 | 
			
		||||
        if !keep_alive and @request_method != 'CONNECT'
 | 
			
		||||
          set('Connection', 'close')
 | 
			
		||||
        end
 | 
			
		||||
        if @chunked
 | 
			
		||||
          set('Transfer-Encoding', 'chunked')
 | 
			
		||||
        elsif @body_size and (keep_alive or @body_size != 0)
 | 
			
		||||
          set('Content-Length', @body_size.to_s)
 | 
			
		||||
        end
 | 
			
		||||
        if @http_version >= 1.1
 | 
			
		||||
          if @request_uri.port == @request_uri.default_port
 | 
			
		||||
            # GFE/1.3 dislikes default port number (returns 404)
 | 
			
		||||
            set('Host', "#{@request_uri.host}")
 | 
			
		||||
          else
 | 
			
		||||
            set('Host', "#{@request_uri.host}:#{@request_uri.port}")
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def set_response_header
 | 
			
		||||
        return if @dumped
 | 
			
		||||
        @dumped = true
 | 
			
		||||
        if defined?(Apache) && self['Date'].empty?
 | 
			
		||||
          set('Date', Time.now.httpdate)
 | 
			
		||||
        end
 | 
			
		||||
        keep_alive = Message.keep_alive_enabled?(@http_version)
 | 
			
		||||
        if @chunked
 | 
			
		||||
          set('Transfer-Encoding', 'chunked')
 | 
			
		||||
        else
 | 
			
		||||
          if keep_alive or @body_size != 0
 | 
			
		||||
            set('Content-Length', @body_size.to_s)
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
        if @body_date
 | 
			
		||||
          set('Last-Modified', @body_date.httpdate)
 | 
			
		||||
        end
 | 
			
		||||
        if self['Content-Type'].empty?
 | 
			
		||||
          set('Content-Type', "#{ @body_type || 'text/html' }; charset=#{ charset_label(@body_charset || $KCODE) }")
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def charset_label(charset)
 | 
			
		||||
        CHARSET_MAP[charset] || 'us-ascii'
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def create_query_uri(uri, query)
 | 
			
		||||
        if @request_method == 'CONNECT'
 | 
			
		||||
          return "#{uri.host}:#{uri.port}"
 | 
			
		||||
        end
 | 
			
		||||
        path = uri.path
 | 
			
		||||
        path = '/' if path.nil? or path.empty?
 | 
			
		||||
        query_str = nil
 | 
			
		||||
        if uri.query
 | 
			
		||||
          query_str = uri.query
 | 
			
		||||
        end
 | 
			
		||||
        if query
 | 
			
		||||
          if query_str
 | 
			
		||||
            query_str += "&#{Message.create_query_part_str(query)}"
 | 
			
		||||
          else
 | 
			
		||||
            query_str = Message.create_query_part_str(query)
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
        if query_str
 | 
			
		||||
          path += "?#{query_str}"
 | 
			
		||||
        end
 | 
			
		||||
        path
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    # Represents HTTP message body.
 | 
			
		||||
    class Body
 | 
			
		||||
      # Size of body.  nil when size is unknown (e.g. chunked response).
 | 
			
		||||
      attr_reader :size
 | 
			
		||||
      # maxbytes of IO#read for streaming request.  See DEFAULT_CHUNK_SIZE.
 | 
			
		||||
      attr_accessor :chunk_size
 | 
			
		||||
 | 
			
		||||
      # Default value for chunk_size
 | 
			
		||||
      DEFAULT_CHUNK_SIZE = 1024 * 16
 | 
			
		||||
 | 
			
		||||
      # Creates a Message::Body.  Use init_request or init_response
 | 
			
		||||
      # for acutual initialize.
 | 
			
		||||
      def initialize
 | 
			
		||||
        @body = nil
 | 
			
		||||
        @size = nil
 | 
			
		||||
        @positions = nil
 | 
			
		||||
        @chunk_size = nil
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Initialize this instance as a request.
 | 
			
		||||
      def init_request(body = nil, boundary = nil)
 | 
			
		||||
        @boundary = boundary
 | 
			
		||||
        @positions = {}
 | 
			
		||||
        set_content(body, boundary)
 | 
			
		||||
        @chunk_size = DEFAULT_CHUNK_SIZE
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Initialize this instance as a response.
 | 
			
		||||
      def init_response(body = nil)
 | 
			
		||||
        @body = body
 | 
			
		||||
        if @body.respond_to?(:size)
 | 
			
		||||
          @size = @body.size
 | 
			
		||||
        else
 | 
			
		||||
          @size = nil
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Dumps message body to given dev.
 | 
			
		||||
      # dev needs to respond to <<.
 | 
			
		||||
      #
 | 
			
		||||
      # Message header must be given as the first argument for performance
 | 
			
		||||
      # reason. (header is dumped to dev, too)
 | 
			
		||||
      # If no dev (the second argument) given, this method returns a dumped
 | 
			
		||||
      # String.
 | 
			
		||||
      def dump(header = '', dev = '')
 | 
			
		||||
        if @body.is_a?(Parts)
 | 
			
		||||
          dev << header
 | 
			
		||||
          buf = ''
 | 
			
		||||
          @body.parts.each do |part|
 | 
			
		||||
            if Message.file?(part)
 | 
			
		||||
              reset_pos(part)
 | 
			
		||||
              while !part.read(@chunk_size, buf).nil?
 | 
			
		||||
                dev << buf
 | 
			
		||||
              end
 | 
			
		||||
            else
 | 
			
		||||
              dev << part
 | 
			
		||||
            end
 | 
			
		||||
          end
 | 
			
		||||
        elsif @body
 | 
			
		||||
          dev << header + @body
 | 
			
		||||
        else
 | 
			
		||||
          dev << header
 | 
			
		||||
        end
 | 
			
		||||
        dev
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Dumps message body with chunked encoding to given dev.
 | 
			
		||||
      # dev needs to respond to <<.
 | 
			
		||||
      #
 | 
			
		||||
      # Message header must be given as the first argument for performance
 | 
			
		||||
      # reason. (header is dumped to dev, too)
 | 
			
		||||
      # If no dev (the second argument) given, this method returns a dumped
 | 
			
		||||
      # String.
 | 
			
		||||
      def dump_chunked(header = '', dev = '')
 | 
			
		||||
        dev << header
 | 
			
		||||
        if @body.is_a?(Parts)
 | 
			
		||||
          @body.parts.each do |part|
 | 
			
		||||
            if Message.file?(part)
 | 
			
		||||
              reset_pos(part)
 | 
			
		||||
              dump_chunks(part, dev)
 | 
			
		||||
            else
 | 
			
		||||
              dev << dump_chunk(part)
 | 
			
		||||
            end
 | 
			
		||||
          end
 | 
			
		||||
          dev << (dump_last_chunk + CRLF)
 | 
			
		||||
        elsif @body
 | 
			
		||||
          reset_pos(@body)
 | 
			
		||||
          dump_chunks(@body, dev)
 | 
			
		||||
          dev << (dump_last_chunk + CRLF)
 | 
			
		||||
        end
 | 
			
		||||
        dev
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Returns a message body itself.
 | 
			
		||||
      def content
 | 
			
		||||
        @body
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
    private
 | 
			
		||||
 | 
			
		||||
      def set_content(body, boundary = nil)
 | 
			
		||||
        if body.respond_to?(:read)
 | 
			
		||||
          # uses Transfer-Encoding: chunked.  bear in mind that server may not
 | 
			
		||||
          # support it.  at least ruby's CGI doesn't.
 | 
			
		||||
          @body = body
 | 
			
		||||
          remember_pos(@body)
 | 
			
		||||
          @size = nil
 | 
			
		||||
        elsif boundary and Message.multiparam_query?(body)
 | 
			
		||||
          @body = build_query_multipart_str(body, boundary)
 | 
			
		||||
          @size = @body.size
 | 
			
		||||
        else
 | 
			
		||||
          @body = Message.create_query_part_str(body)
 | 
			
		||||
          @size = @body.size
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def remember_pos(io)
 | 
			
		||||
        # IO may not support it (ex. IO.pipe)
 | 
			
		||||
        @positions[io] = io.pos rescue nil
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def reset_pos(io)
 | 
			
		||||
        io.pos = @positions[io] if @positions.key?(io)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def dump_chunks(io, dev)
 | 
			
		||||
        buf = ''
 | 
			
		||||
        while !io.read(@chunk_size, buf).nil?
 | 
			
		||||
          dev << dump_chunk(buf)
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def dump_chunk(str)
 | 
			
		||||
        dump_chunk_size(str.size) + (str + CRLF)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def dump_last_chunk
 | 
			
		||||
        dump_chunk_size(0)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def dump_chunk_size(size)
 | 
			
		||||
        sprintf("%x", size) + CRLF
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      class Parts
 | 
			
		||||
        attr_reader :size
 | 
			
		||||
 | 
			
		||||
        def initialize
 | 
			
		||||
          @body = []
 | 
			
		||||
          @size = 0
 | 
			
		||||
          @as_stream = false
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def add(part)
 | 
			
		||||
          if Message.file?(part)
 | 
			
		||||
            @as_stream = true
 | 
			
		||||
            @body << part
 | 
			
		||||
            if part.respond_to?(:size)
 | 
			
		||||
              if sz = part.size
 | 
			
		||||
                @size += sz
 | 
			
		||||
              else
 | 
			
		||||
                @size = nil
 | 
			
		||||
              end
 | 
			
		||||
            elsif part.respond_to?(:lstat)
 | 
			
		||||
              @size += part.lstat.size
 | 
			
		||||
            else
 | 
			
		||||
              # use chunked upload
 | 
			
		||||
              @size = nil
 | 
			
		||||
            end
 | 
			
		||||
          elsif @body[-1].is_a?(String)
 | 
			
		||||
            @body[-1] += part.to_s
 | 
			
		||||
            @size += part.to_s.size if @size
 | 
			
		||||
          else
 | 
			
		||||
            @body << part.to_s
 | 
			
		||||
            @size += part.to_s.size if @size
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def parts
 | 
			
		||||
          if @as_stream
 | 
			
		||||
            @body
 | 
			
		||||
          else
 | 
			
		||||
            [@body.join]
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def build_query_multipart_str(query, boundary)
 | 
			
		||||
        parts = Parts.new
 | 
			
		||||
        query.each do |attr, value|
 | 
			
		||||
          value ||= ''
 | 
			
		||||
          headers = ["--#{boundary}"]
 | 
			
		||||
          if Message.file?(value)
 | 
			
		||||
            remember_pos(value)
 | 
			
		||||
            param_str = params_from_file(value).collect { |k, v|
 | 
			
		||||
              "#{k}=\"#{v}\""
 | 
			
		||||
            }.join("; ")
 | 
			
		||||
            if value.respond_to?(:mime_type)
 | 
			
		||||
              content_type = value.mime_type
 | 
			
		||||
            else
 | 
			
		||||
              content_type = Message.mime_type(value.path)
 | 
			
		||||
            end
 | 
			
		||||
            headers << %{Content-Disposition: form-data; name="#{attr}"; #{param_str}}
 | 
			
		||||
            headers << %{Content-Type: #{content_type}}
 | 
			
		||||
          else
 | 
			
		||||
            headers << %{Content-Disposition: form-data; name="#{attr}"}
 | 
			
		||||
          end
 | 
			
		||||
          parts.add(headers.join(CRLF) + CRLF + CRLF)
 | 
			
		||||
          parts.add(value)
 | 
			
		||||
          parts.add(CRLF)
 | 
			
		||||
        end
 | 
			
		||||
        parts.add("--#{boundary}--" + CRLF + CRLF) # empty epilogue
 | 
			
		||||
        parts
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def params_from_file(value)
 | 
			
		||||
        params = {}
 | 
			
		||||
        params['filename'] = File.basename(value.path || '')
 | 
			
		||||
        # Creation time is not available from File::Stat
 | 
			
		||||
        if value.respond_to?(:mtime)
 | 
			
		||||
          params['modification-date'] = value.mtime.rfc822
 | 
			
		||||
        end
 | 
			
		||||
        if value.respond_to?(:atime)
 | 
			
		||||
          params['read-date'] = value.atime.rfc822
 | 
			
		||||
        end
 | 
			
		||||
        params
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    class << self
 | 
			
		||||
      private :new
 | 
			
		||||
 | 
			
		||||
      # Creates a Message instance of 'CONNECT' request.
 | 
			
		||||
      # 'CONNECT' request does not have Body.
 | 
			
		||||
      # uri:: an URI that need to connect.  Only uri.host and uri.port are used.
 | 
			
		||||
      def new_connect_request(uri)
 | 
			
		||||
        m = new
 | 
			
		||||
        m.header.init_connect_request(uri)
 | 
			
		||||
        m.header.body_size = nil
 | 
			
		||||
        m
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Creates a Message instance of general request.
 | 
			
		||||
      # method:: HTTP method String.
 | 
			
		||||
      # uri:: an URI object which represents an URL of web resource.
 | 
			
		||||
      # query:: a Hash or an Array of query part of URL.
 | 
			
		||||
      #         e.g. { "a" => "b" } => 'http://host/part?a=b'
 | 
			
		||||
      #         Give an array to pass multiple value like
 | 
			
		||||
      #         [["a", "b"], ["a", "c"]] => 'http://host/part?a=b&a=c'
 | 
			
		||||
      # body:: a Hash or an Array of body part.
 | 
			
		||||
      #        e.g. { "a" => "b" } => 'a=b'.
 | 
			
		||||
      #        Give an array to pass multiple value like
 | 
			
		||||
      #        [["a", "b"], ["a", "c"]] => 'a=b&a=c'.
 | 
			
		||||
      # boundary:: When the boundary given, it is sent as
 | 
			
		||||
      #            a multipart/form-data using this boundary String.
 | 
			
		||||
      def new_request(method, uri, query = nil, body = nil, boundary = nil)
 | 
			
		||||
        m = new
 | 
			
		||||
        m.header.init_request(method, uri, query)
 | 
			
		||||
        m.body = Body.new
 | 
			
		||||
        m.body.init_request(body || '', boundary)
 | 
			
		||||
        if body
 | 
			
		||||
          m.header.body_size = m.body.size
 | 
			
		||||
          m.header.chunked = true if m.body.size.nil?
 | 
			
		||||
        else
 | 
			
		||||
          m.header.body_size = nil
 | 
			
		||||
        end
 | 
			
		||||
        m
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Creates a Message instance of response.
 | 
			
		||||
      # body:: a String or an IO of response message body.
 | 
			
		||||
      def new_response(body)
 | 
			
		||||
        m = new
 | 
			
		||||
        m.header.init_response(Status::OK)
 | 
			
		||||
        m.body = Body.new
 | 
			
		||||
        m.body.init_response(body)
 | 
			
		||||
        m.header.body_size = m.body.size || 0
 | 
			
		||||
        m
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      @@mime_type_handler = nil
 | 
			
		||||
 | 
			
		||||
      # Sets MIME type handler.
 | 
			
		||||
      #
 | 
			
		||||
      # handler must respond to :call with a single argument :path and returns
 | 
			
		||||
      # a MIME type String e.g. 'text/html'.
 | 
			
		||||
      # When the handler returns nil or an empty String,
 | 
			
		||||
      # 'application/octet-stream' is used.
 | 
			
		||||
      #
 | 
			
		||||
      # When you set nil to the handler, internal_mime_type is used instead.
 | 
			
		||||
      # The handler is nil by default.
 | 
			
		||||
      def mime_type_handler=(handler)
 | 
			
		||||
        @@mime_type_handler = handler
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Returns MIME type handler.
 | 
			
		||||
      def mime_type_handler
 | 
			
		||||
        @@mime_type_handler
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # For backward compatibility.
 | 
			
		||||
      alias set_mime_type_func mime_type_handler=
 | 
			
		||||
      alias get_mime_type_func mime_type_handler
 | 
			
		||||
 | 
			
		||||
      def mime_type(path) # :nodoc:
 | 
			
		||||
        if @@mime_type_handler
 | 
			
		||||
          res = @@mime_type_handler.call(path)
 | 
			
		||||
          if !res || res.to_s == ''
 | 
			
		||||
            return 'application/octet-stream'
 | 
			
		||||
          else
 | 
			
		||||
            return res
 | 
			
		||||
          end
 | 
			
		||||
        else
 | 
			
		||||
          internal_mime_type(path)
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Default MIME type handler.
 | 
			
		||||
      # See mime_type_handler=.
 | 
			
		||||
      def internal_mime_type(path)
 | 
			
		||||
        case path
 | 
			
		||||
        when /\.txt$/i
 | 
			
		||||
          'text/plain'
 | 
			
		||||
        when /\.(htm|html)$/i
 | 
			
		||||
          'text/html'
 | 
			
		||||
        when /\.doc$/i
 | 
			
		||||
          'application/msword'
 | 
			
		||||
        when /\.png$/i
 | 
			
		||||
          'image/png'
 | 
			
		||||
        when /\.gif$/i
 | 
			
		||||
          'image/gif'
 | 
			
		||||
        when /\.(jpg|jpeg)$/i
 | 
			
		||||
          'image/jpeg'
 | 
			
		||||
        else
 | 
			
		||||
          'application/octet-stream'
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Returns true if the given HTTP version allows keep alive connection.
 | 
			
		||||
      # version:: Float
 | 
			
		||||
      def keep_alive_enabled?(version)
 | 
			
		||||
        version >= 1.1
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Returns true if the given query (or body) has a multiple parameter.
 | 
			
		||||
      def multiparam_query?(query)
 | 
			
		||||
        query.is_a?(Array) or query.is_a?(Hash)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Returns true if the given object is a File.  In HTTPClient, a file is;
 | 
			
		||||
      # * must respond to :read for retrieving String chunks.
 | 
			
		||||
      # * must respond to :path and returns a path for Content-Disposition.
 | 
			
		||||
      # * must respond to :pos and :pos= to rewind for reading.
 | 
			
		||||
      #   Rewinding is only needed for following HTTP redirect.  Some IO impl
 | 
			
		||||
      #   defines :pos= but raises an Exception for pos= such as StringIO
 | 
			
		||||
      #   but there's no problem as far as using it for non-following methods
 | 
			
		||||
      #   (get/post/etc.)
 | 
			
		||||
      def file?(obj)
 | 
			
		||||
        obj.respond_to?(:read) and obj.respond_to?(:path) and
 | 
			
		||||
          obj.respond_to?(:pos) and obj.respond_to?(:pos=)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def create_query_part_str(query) # :nodoc:
 | 
			
		||||
        if multiparam_query?(query)
 | 
			
		||||
          escape_query(query)
 | 
			
		||||
        elsif query.respond_to?(:read)
 | 
			
		||||
          query = query.read
 | 
			
		||||
        else
 | 
			
		||||
          query.to_s
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def escape_query(query) # :nodoc:
 | 
			
		||||
        query.collect { |attr, value|
 | 
			
		||||
          if value.respond_to?(:read)
 | 
			
		||||
            value = value.read
 | 
			
		||||
          end
 | 
			
		||||
          escape(attr.to_s) << '=' << escape(value.to_s)
 | 
			
		||||
        }.join('&')
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # from CGI.escape
 | 
			
		||||
      def escape(str) # :nodoc:
 | 
			
		||||
        str.gsub(/([^ a-zA-Z0-9_.-]+)/n) {
 | 
			
		||||
          '%' + $1.unpack('H2' * $1.size).join('%').upcase
 | 
			
		||||
        }.tr(' ', '+')
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    # HTTP::Message::Headers:: message header.
 | 
			
		||||
    attr_accessor :header
 | 
			
		||||
 | 
			
		||||
    # HTTP::Message::Body:: message body.
 | 
			
		||||
    attr_reader :body
 | 
			
		||||
 | 
			
		||||
    # OpenSSL::X509::Certificate:: response only.  server certificate which is
 | 
			
		||||
    #                              used for retrieving the response.
 | 
			
		||||
    attr_accessor :peer_cert
 | 
			
		||||
 | 
			
		||||
    # Creates a Message.  This method should be used internally.
 | 
			
		||||
    # Use Message.new_connect_request, Message.new_request or
 | 
			
		||||
    # Message.new_response instead.
 | 
			
		||||
    def initialize # :nodoc:
 | 
			
		||||
      @header = Headers.new
 | 
			
		||||
      @body = @peer_cert = nil
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Dumps message (header and body) to given dev.
 | 
			
		||||
    # dev needs to respond to <<.
 | 
			
		||||
    def dump(dev = '')
 | 
			
		||||
      str = header.dump + CRLF
 | 
			
		||||
      if header.chunked
 | 
			
		||||
        dev = body.dump_chunked(str, dev)
 | 
			
		||||
      elsif body
 | 
			
		||||
        dev = body.dump(str, dev)
 | 
			
		||||
      else
 | 
			
		||||
        dev << str
 | 
			
		||||
      end
 | 
			
		||||
      dev
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Sets a new body.  header.body_size is updated with new body.size.
 | 
			
		||||
    def body=(body)
 | 
			
		||||
      @body = body
 | 
			
		||||
      @header.body_size = @body.size if @header
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Returns HTTP version in a HTTP header.  Float.
 | 
			
		||||
    def version
 | 
			
		||||
      @header.http_version
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Sets HTTP version in a HTTP header.  Float.
 | 
			
		||||
    def version=(version)
 | 
			
		||||
      @header.http_version = version
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Returns HTTP status code in response.  Integer.
 | 
			
		||||
    def status
 | 
			
		||||
      @header.status_code
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    alias code status
 | 
			
		||||
    alias status_code status
 | 
			
		||||
 | 
			
		||||
    # Sets HTTP status code of response.  Integer.
 | 
			
		||||
    # Reason phrase is updated, too.
 | 
			
		||||
    def status=(status)
 | 
			
		||||
      @header.status_code = status
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Returns  HTTP status reason phrase in response.  String.
 | 
			
		||||
    def reason
 | 
			
		||||
      @header.reason_phrase
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Sets  HTTP status reason phrase of response.  String.
 | 
			
		||||
    def reason=(reason)
 | 
			
		||||
      @header.reason_phrase = reason
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Sets 'Content-Type' header value.  Overrides if already exists.
 | 
			
		||||
    def contenttype
 | 
			
		||||
      @header.contenttype
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Returns 'Content-Type' header value.
 | 
			
		||||
    def contenttype=(contenttype)
 | 
			
		||||
      @header.contenttype = contenttype
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Returns a content of message body.  A String or an IO.
 | 
			
		||||
    def content
 | 
			
		||||
      @body.content
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										863
									
								
								vendor/gems/gems/httpclient-2.1.5.2/lib/httpclient/session.rb
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,863 @@
 | 
			
		|||
# HTTPClient - HTTP client library.
 | 
			
		||||
# Copyright (C) 2000-2009  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>.
 | 
			
		||||
#
 | 
			
		||||
# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
 | 
			
		||||
# redistribute it and/or modify it under the same terms of Ruby's license;
 | 
			
		||||
# either the dual license version in 2003, or any later version.
 | 
			
		||||
 | 
			
		||||
# httpclient/session.rb is based on http-access.rb in http-access/0.0.4.
 | 
			
		||||
# Some part of code in http-access.rb was recycled in httpclient.rb.
 | 
			
		||||
# Those part is copyrighted by Maehashi-san.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
require 'socket'
 | 
			
		||||
require 'thread'
 | 
			
		||||
require 'stringio'
 | 
			
		||||
 | 
			
		||||
require 'httpclient/timeout'
 | 
			
		||||
require 'httpclient/ssl_config'
 | 
			
		||||
require 'httpclient/http'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class HTTPClient
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  # Represents a Site: protocol scheme, host String and port Number.
 | 
			
		||||
  class Site
 | 
			
		||||
    # Protocol scheme.
 | 
			
		||||
    attr_accessor :scheme
 | 
			
		||||
    # Host String.
 | 
			
		||||
    attr_reader :host
 | 
			
		||||
    # Port number.
 | 
			
		||||
    attr_reader :port
 | 
			
		||||
 | 
			
		||||
    # Creates a new Site based on the given URI.
 | 
			
		||||
    def initialize(uri = nil)
 | 
			
		||||
      if uri
 | 
			
		||||
        @scheme = uri.scheme
 | 
			
		||||
        @host = uri.host
 | 
			
		||||
        @port = uri.port.to_i
 | 
			
		||||
      else
 | 
			
		||||
        @scheme = 'tcp'
 | 
			
		||||
        @host = '0.0.0.0'
 | 
			
		||||
        @port = 0
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Returns address String.
 | 
			
		||||
    def addr
 | 
			
		||||
      "#{@scheme}://#{@host}:#{@port.to_s}"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Returns true is scheme, host and port are '=='
 | 
			
		||||
    def ==(rhs)
 | 
			
		||||
      (@scheme == rhs.scheme) and (@host == rhs.host) and (@port == rhs.port)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Same as ==.
 | 
			
		||||
    def eql?(rhs)
 | 
			
		||||
      self == rhs
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def hash # :nodoc:
 | 
			
		||||
      [@scheme, @host, @port].hash
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def to_s # :nodoc:
 | 
			
		||||
      addr
 | 
			
		||||
    end
 | 
			
		||||
    
 | 
			
		||||
    # Returns true if scheme, host and port of the given URI matches with this.
 | 
			
		||||
    def match(uri)
 | 
			
		||||
      (@scheme == uri.scheme) and (@host == uri.host) and (@port == uri.port.to_i)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def inspect # :nodoc:
 | 
			
		||||
      sprintf("#<%s:0x%x %s>", self.class.name, __id__, addr)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  # Manages sessions for a HTTPClient instance.
 | 
			
		||||
  class SessionManager
 | 
			
		||||
    # Name of this client.  Used for 'User-Agent' header in HTTP request.
 | 
			
		||||
    attr_accessor :agent_name
 | 
			
		||||
    # Owner of this client.  Used for 'From' header in HTTP request.
 | 
			
		||||
    attr_accessor :from
 | 
			
		||||
 | 
			
		||||
    # Requested protocol version
 | 
			
		||||
    attr_accessor :protocol_version
 | 
			
		||||
    # Chunk size for chunked request
 | 
			
		||||
    attr_accessor :chunk_size
 | 
			
		||||
    # Device for dumping log for debugging
 | 
			
		||||
    attr_accessor :debug_dev
 | 
			
		||||
    # Boolean value for Socket#sync
 | 
			
		||||
    attr_accessor :socket_sync
 | 
			
		||||
 | 
			
		||||
    attr_accessor :connect_timeout
 | 
			
		||||
    # Maximum retry count.  0 for infinite.
 | 
			
		||||
    attr_accessor :connect_retry
 | 
			
		||||
    attr_accessor :send_timeout
 | 
			
		||||
    attr_accessor :receive_timeout
 | 
			
		||||
    attr_accessor :read_block_size
 | 
			
		||||
    attr_accessor :protocol_retry_count
 | 
			
		||||
 | 
			
		||||
    attr_accessor :ssl_config
 | 
			
		||||
 | 
			
		||||
    attr_reader :test_loopback_http_response
 | 
			
		||||
 | 
			
		||||
    def initialize(client)
 | 
			
		||||
      @client = client
 | 
			
		||||
      @proxy = client.proxy
 | 
			
		||||
 | 
			
		||||
      @agent_name = nil
 | 
			
		||||
      @from = nil
 | 
			
		||||
 | 
			
		||||
      @protocol_version = nil
 | 
			
		||||
      @debug_dev = client.debug_dev
 | 
			
		||||
      @socket_sync = true
 | 
			
		||||
      @chunk_size = 4096
 | 
			
		||||
 | 
			
		||||
      @connect_timeout = 60
 | 
			
		||||
      @connect_retry = 1
 | 
			
		||||
      @send_timeout = 120
 | 
			
		||||
      @receive_timeout = 60       # For each read_block_size bytes
 | 
			
		||||
      @read_block_size = 1024 * 16 # follows net/http change in 1.8.7
 | 
			
		||||
      @protocol_retry_count = 5
 | 
			
		||||
 | 
			
		||||
      @ssl_config = nil
 | 
			
		||||
      @test_loopback_http_response = []
 | 
			
		||||
 | 
			
		||||
      @sess_pool = []
 | 
			
		||||
      @sess_pool_mutex = Mutex.new
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def proxy=(proxy)
 | 
			
		||||
      if proxy.nil?
 | 
			
		||||
        @proxy = nil
 | 
			
		||||
      else
 | 
			
		||||
        @proxy = Site.new(proxy)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def query(req, via_proxy)
 | 
			
		||||
      req.body.chunk_size = @chunk_size
 | 
			
		||||
      sess = open(req.header.request_uri, via_proxy)
 | 
			
		||||
      begin
 | 
			
		||||
        sess.query(req)
 | 
			
		||||
      rescue
 | 
			
		||||
        sess.close
 | 
			
		||||
        raise
 | 
			
		||||
      end
 | 
			
		||||
      sess
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def reset(uri)
 | 
			
		||||
      site = Site.new(uri)
 | 
			
		||||
      close(site)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def reset_all
 | 
			
		||||
      close_all
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def keep(sess)
 | 
			
		||||
      add_cached_session(sess)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
  private
 | 
			
		||||
 | 
			
		||||
    def open(uri, via_proxy = false)
 | 
			
		||||
      sess = nil
 | 
			
		||||
      if cached = get_cached_session(uri)
 | 
			
		||||
        sess = cached
 | 
			
		||||
      else
 | 
			
		||||
        sess = Session.new(@client, Site.new(uri), @agent_name, @from)
 | 
			
		||||
        sess.proxy = via_proxy ? @proxy : nil
 | 
			
		||||
        sess.socket_sync = @socket_sync
 | 
			
		||||
        sess.requested_version = @protocol_version if @protocol_version
 | 
			
		||||
        sess.connect_timeout = @connect_timeout
 | 
			
		||||
        sess.connect_retry = @connect_retry
 | 
			
		||||
        sess.send_timeout = @send_timeout
 | 
			
		||||
        sess.receive_timeout = @receive_timeout
 | 
			
		||||
        sess.read_block_size = @read_block_size
 | 
			
		||||
        sess.protocol_retry_count = @protocol_retry_count
 | 
			
		||||
        sess.ssl_config = @ssl_config
 | 
			
		||||
        sess.debug_dev = @debug_dev
 | 
			
		||||
        sess.test_loopback_http_response = @test_loopback_http_response
 | 
			
		||||
      end
 | 
			
		||||
      sess
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def close_all
 | 
			
		||||
      @sess_pool_mutex.synchronize do
 | 
			
		||||
        @sess_pool.each do |sess|
 | 
			
		||||
          sess.close
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
      @sess_pool.clear
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def close(dest)
 | 
			
		||||
      if cached = get_cached_session(dest)
 | 
			
		||||
        cached.close
 | 
			
		||||
        true
 | 
			
		||||
      else
 | 
			
		||||
        false
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def get_cached_session(uri)
 | 
			
		||||
      cached = nil
 | 
			
		||||
      @sess_pool_mutex.synchronize do
 | 
			
		||||
        new_pool = []
 | 
			
		||||
        @sess_pool.each do |s|
 | 
			
		||||
          if s.dest.match(uri)
 | 
			
		||||
            cached = s
 | 
			
		||||
          else
 | 
			
		||||
            new_pool << s
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
        @sess_pool = new_pool
 | 
			
		||||
      end
 | 
			
		||||
      cached
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def add_cached_session(sess)
 | 
			
		||||
      @sess_pool_mutex.synchronize do
 | 
			
		||||
        @sess_pool << sess
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  # Wraps up OpenSSL::SSL::SSLSocket and offers debugging features.
 | 
			
		||||
  class SSLSocketWrap
 | 
			
		||||
    def initialize(socket, context, debug_dev = nil)
 | 
			
		||||
      unless SSLEnabled
 | 
			
		||||
        raise ConfigurationError.new('Ruby/OpenSSL module is required')
 | 
			
		||||
      end
 | 
			
		||||
      @context = context
 | 
			
		||||
      @socket = socket
 | 
			
		||||
      @ssl_socket = create_openssl_socket(@socket)
 | 
			
		||||
      @debug_dev = debug_dev
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def ssl_connect
 | 
			
		||||
      @ssl_socket.connect
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def post_connection_check(host)
 | 
			
		||||
      verify_mode = @context.verify_mode || OpenSSL::SSL::VERIFY_NONE
 | 
			
		||||
      if verify_mode == OpenSSL::SSL::VERIFY_NONE
 | 
			
		||||
        return
 | 
			
		||||
      elsif @ssl_socket.peer_cert.nil? and
 | 
			
		||||
        check_mask(verify_mode, OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT)
 | 
			
		||||
        raise OpenSSL::SSL::SSLError.new('no peer cert')
 | 
			
		||||
      end
 | 
			
		||||
      hostname = host.host
 | 
			
		||||
      if @ssl_socket.respond_to?(:post_connection_check) and RUBY_VERSION > "1.8.4"
 | 
			
		||||
        @ssl_socket.post_connection_check(hostname)
 | 
			
		||||
      else
 | 
			
		||||
        @context.post_connection_check(@ssl_socket.peer_cert, hostname)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def peer_cert
 | 
			
		||||
      @ssl_socket.peer_cert
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def close
 | 
			
		||||
      @ssl_socket.close
 | 
			
		||||
      @socket.close
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def closed?
 | 
			
		||||
      @socket.closed?
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def eof?
 | 
			
		||||
      @ssl_socket.eof?
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def gets(*args)
 | 
			
		||||
      str = @ssl_socket.gets(*args)
 | 
			
		||||
      debug(str)
 | 
			
		||||
      str
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def read(*args)
 | 
			
		||||
      str = @ssl_socket.read(*args)
 | 
			
		||||
      debug(str)
 | 
			
		||||
      str
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def readpartial(*args)
 | 
			
		||||
      str = @ssl_socket.readpartial(*args)
 | 
			
		||||
      debug(str)
 | 
			
		||||
      str
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def <<(str)
 | 
			
		||||
      rv = @ssl_socket.write(str)
 | 
			
		||||
      debug(str)
 | 
			
		||||
      rv
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def flush
 | 
			
		||||
      @ssl_socket.flush
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def sync
 | 
			
		||||
      @ssl_socket.sync
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def sync=(sync)
 | 
			
		||||
      @ssl_socket.sync = sync
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
  private
 | 
			
		||||
 | 
			
		||||
    def check_mask(value, mask)
 | 
			
		||||
      value & mask == mask
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def create_openssl_socket(socket)
 | 
			
		||||
      ssl_socket = nil
 | 
			
		||||
      if OpenSSL::SSL.const_defined?("SSLContext")
 | 
			
		||||
        ctx = OpenSSL::SSL::SSLContext.new
 | 
			
		||||
        @context.set_context(ctx)
 | 
			
		||||
        ssl_socket = OpenSSL::SSL::SSLSocket.new(socket, ctx)
 | 
			
		||||
      else
 | 
			
		||||
        ssl_socket = OpenSSL::SSL::SSLSocket.new(socket)
 | 
			
		||||
        @context.set_context(ssl_socket)
 | 
			
		||||
      end
 | 
			
		||||
      ssl_socket
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def debug(str)
 | 
			
		||||
      @debug_dev << str if @debug_dev && str
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  # Wraps up a Socket for method interception.
 | 
			
		||||
  module SocketWrap
 | 
			
		||||
    def initialize(socket, *args)
 | 
			
		||||
      super(*args)
 | 
			
		||||
      @socket = socket
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def close
 | 
			
		||||
      @socket.close
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def closed?
 | 
			
		||||
      @socket.closed?
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def eof?
 | 
			
		||||
      @socket.eof?
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def gets(*args)
 | 
			
		||||
      @socket.gets(*args)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def read(*args)
 | 
			
		||||
      @socket.read(*args)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def readpartial(*args)
 | 
			
		||||
      # StringIO doesn't support :readpartial
 | 
			
		||||
      if @socket.respond_to?(:readpartial)
 | 
			
		||||
        @socket.readpartial(*args)
 | 
			
		||||
      else
 | 
			
		||||
        @socket.read(*args)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def <<(str)
 | 
			
		||||
      @socket << str
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def flush
 | 
			
		||||
      @socket.flush
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def sync
 | 
			
		||||
      @socket.sync
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def sync=(sync)
 | 
			
		||||
      @socket.sync = sync
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  # Module for intercepting Socket methods and dumps in/out to given debugging
 | 
			
		||||
  # device.  debug_dev must respond to <<.
 | 
			
		||||
  module DebugSocket
 | 
			
		||||
    extend SocketWrap
 | 
			
		||||
 | 
			
		||||
    def debug_dev=(debug_dev)
 | 
			
		||||
      @debug_dev = debug_dev
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def close
 | 
			
		||||
      super
 | 
			
		||||
      debug("! CONNECTION CLOSED\n")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def gets(*args)
 | 
			
		||||
      str = super
 | 
			
		||||
      debug(str)
 | 
			
		||||
      str
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def read(*args)
 | 
			
		||||
      str = super
 | 
			
		||||
      debug(str)
 | 
			
		||||
      str
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def readpartial(*args)
 | 
			
		||||
      str = super
 | 
			
		||||
      debug(str)
 | 
			
		||||
      str
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def <<(str)
 | 
			
		||||
      super
 | 
			
		||||
      debug(str)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
  private
 | 
			
		||||
 | 
			
		||||
    def debug(str)
 | 
			
		||||
      @debug_dev << str if str && @debug_dev
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  # Dummy Socket for emulating loopback test.
 | 
			
		||||
  class LoopBackSocket
 | 
			
		||||
    include SocketWrap
 | 
			
		||||
 | 
			
		||||
    def initialize(host, port, response)
 | 
			
		||||
      super(response.is_a?(StringIO) ? response : StringIO.new(response))
 | 
			
		||||
      @host = host
 | 
			
		||||
      @port = port
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def <<(str)
 | 
			
		||||
      # ignored
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  # Manages a HTTP session with a Site.
 | 
			
		||||
  class Session
 | 
			
		||||
    include HTTPClient::Timeout
 | 
			
		||||
 | 
			
		||||
    # Destination site
 | 
			
		||||
    attr_reader :dest
 | 
			
		||||
    # Proxy site
 | 
			
		||||
    attr_accessor :proxy
 | 
			
		||||
    # Boolean value for Socket#sync
 | 
			
		||||
    attr_accessor :socket_sync
 | 
			
		||||
    # Requested protocol version
 | 
			
		||||
    attr_accessor :requested_version
 | 
			
		||||
    # Device for dumping log for debugging
 | 
			
		||||
    attr_accessor :debug_dev
 | 
			
		||||
 | 
			
		||||
    attr_accessor :connect_timeout
 | 
			
		||||
    attr_accessor :connect_retry
 | 
			
		||||
    attr_accessor :send_timeout
 | 
			
		||||
    attr_accessor :receive_timeout
 | 
			
		||||
    attr_accessor :read_block_size
 | 
			
		||||
    attr_accessor :protocol_retry_count
 | 
			
		||||
 | 
			
		||||
    attr_accessor :ssl_config
 | 
			
		||||
    attr_reader :ssl_peer_cert
 | 
			
		||||
    attr_accessor :test_loopback_http_response
 | 
			
		||||
 | 
			
		||||
    def initialize(client, dest, agent_name, from)
 | 
			
		||||
      @client = client
 | 
			
		||||
      @dest = dest
 | 
			
		||||
      @proxy = nil
 | 
			
		||||
      @socket_sync = true
 | 
			
		||||
      @requested_version = nil
 | 
			
		||||
 | 
			
		||||
      @debug_dev = nil
 | 
			
		||||
 | 
			
		||||
      @connect_timeout = nil
 | 
			
		||||
      @connect_retry = 1
 | 
			
		||||
      @send_timeout = nil
 | 
			
		||||
      @receive_timeout = nil
 | 
			
		||||
      @read_block_size = nil
 | 
			
		||||
      @protocol_retry_count = 5
 | 
			
		||||
 | 
			
		||||
      @ssl_config = nil
 | 
			
		||||
      @ssl_peer_cert = nil
 | 
			
		||||
 | 
			
		||||
      @test_loopback_http_response = nil
 | 
			
		||||
 | 
			
		||||
      @agent_name = agent_name
 | 
			
		||||
      @from = from
 | 
			
		||||
      @state = :INIT
 | 
			
		||||
 | 
			
		||||
      @requests = []
 | 
			
		||||
 | 
			
		||||
      @status = nil
 | 
			
		||||
      @reason = nil
 | 
			
		||||
      @headers = []
 | 
			
		||||
 | 
			
		||||
      @socket = nil
 | 
			
		||||
      @readbuf = nil
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Send a request to the server
 | 
			
		||||
    def query(req)
 | 
			
		||||
      connect if @state == :INIT
 | 
			
		||||
      req.header.request_via_proxy = !@proxy.nil?
 | 
			
		||||
      begin
 | 
			
		||||
        timeout(@send_timeout, SendTimeoutError) do
 | 
			
		||||
          set_header(req)
 | 
			
		||||
          req.dump(@socket)
 | 
			
		||||
          # flush the IO stream as IO::sync mode is false
 | 
			
		||||
          @socket.flush unless @socket_sync
 | 
			
		||||
        end
 | 
			
		||||
      rescue Errno::ECONNABORTED, Errno::ECONNRESET, Errno::EPIPE
 | 
			
		||||
        close
 | 
			
		||||
        raise KeepAliveDisconnected.new
 | 
			
		||||
      rescue HTTPClient::TimeoutError
 | 
			
		||||
        close
 | 
			
		||||
        raise
 | 
			
		||||
      rescue
 | 
			
		||||
        if SSLEnabled and $!.is_a?(OpenSSL::SSL::SSLError)
 | 
			
		||||
          raise KeepAliveDisconnected.new
 | 
			
		||||
        else
 | 
			
		||||
          raise
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      @state = :META if @state == :WAIT
 | 
			
		||||
      @next_connection = nil
 | 
			
		||||
      @requests.push(req)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def close
 | 
			
		||||
      if !@socket.nil? and !@socket.closed?
 | 
			
		||||
        # @socket.flush may block when it the socket is already closed by
 | 
			
		||||
        # foreign host and the client runs under MT-condition.
 | 
			
		||||
        @socket.close
 | 
			
		||||
      end
 | 
			
		||||
      @state = :INIT
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def closed?
 | 
			
		||||
      @state == :INIT
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def get_header
 | 
			
		||||
      begin
 | 
			
		||||
        if @state != :META
 | 
			
		||||
          raise RuntimeError.new("get_status must be called at the beginning of a session")
 | 
			
		||||
        end
 | 
			
		||||
        read_header
 | 
			
		||||
      rescue
 | 
			
		||||
        close
 | 
			
		||||
        raise
 | 
			
		||||
      end
 | 
			
		||||
      [@version, @status, @reason, @headers]
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def eof?
 | 
			
		||||
      if !@content_length.nil?
 | 
			
		||||
        @content_length == 0
 | 
			
		||||
      else
 | 
			
		||||
        @socket.closed? or @socket.eof?
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def get_body(&block)
 | 
			
		||||
      begin
 | 
			
		||||
        read_header if @state == :META
 | 
			
		||||
        return nil if @state != :DATA
 | 
			
		||||
        if @chunked
 | 
			
		||||
          read_body_chunked(&block)
 | 
			
		||||
        elsif @content_length
 | 
			
		||||
          read_body_length(&block)
 | 
			
		||||
        else
 | 
			
		||||
          read_body_rest(&block)
 | 
			
		||||
        end
 | 
			
		||||
      rescue
 | 
			
		||||
        close
 | 
			
		||||
        raise
 | 
			
		||||
      end
 | 
			
		||||
      if eof?
 | 
			
		||||
        if @next_connection
 | 
			
		||||
          @state = :WAIT
 | 
			
		||||
        else
 | 
			
		||||
          close
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
      nil
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
  private
 | 
			
		||||
 | 
			
		||||
    def set_header(req)
 | 
			
		||||
      if @requested_version
 | 
			
		||||
        if /^(?:HTTP\/|)(\d+.\d+)$/ =~ @requested_version
 | 
			
		||||
          req.version = $1.to_f
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
      if @agent_name
 | 
			
		||||
        req.header.set('User-Agent', "#{@agent_name} #{LIB_NAME}")
 | 
			
		||||
      end
 | 
			
		||||
      if @from
 | 
			
		||||
        req.header.set('From', @from)
 | 
			
		||||
      end
 | 
			
		||||
      req.header.set('Date', Time.now.httpdate)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Connect to the server
 | 
			
		||||
    def connect
 | 
			
		||||
      site = @proxy || @dest
 | 
			
		||||
      retry_number = 0
 | 
			
		||||
      begin
 | 
			
		||||
        timeout(@connect_timeout, ConnectTimeoutError) do
 | 
			
		||||
          @socket = create_socket(site)
 | 
			
		||||
          if @dest.scheme == 'https'
 | 
			
		||||
            if @socket.is_a?(LoopBackSocket)
 | 
			
		||||
              connect_ssl_proxy(@socket, URI.parse(@dest.to_s)) if @proxy
 | 
			
		||||
            else
 | 
			
		||||
              @socket = create_ssl_socket(@socket)
 | 
			
		||||
              connect_ssl_proxy(@socket, URI.parse(@dest.to_s)) if @proxy
 | 
			
		||||
              @socket.ssl_connect
 | 
			
		||||
              @socket.post_connection_check(@dest)
 | 
			
		||||
              @ssl_peer_cert = @socket.peer_cert
 | 
			
		||||
            end
 | 
			
		||||
          end
 | 
			
		||||
          # Use Ruby internal buffering instead of passing data immediately
 | 
			
		||||
          # to the underlying layer
 | 
			
		||||
          # => we need to to call explicitly flush on the socket
 | 
			
		||||
          @socket.sync = @socket_sync
 | 
			
		||||
        end
 | 
			
		||||
      rescue RetryableResponse
 | 
			
		||||
        retry_number += 1
 | 
			
		||||
        if retry_number < @protocol_retry_count
 | 
			
		||||
          retry
 | 
			
		||||
        end
 | 
			
		||||
        raise BadResponseError.new("connect to the server failed with status #{@status} #{@reason}")
 | 
			
		||||
      rescue TimeoutError
 | 
			
		||||
        if @connect_retry == 0
 | 
			
		||||
          retry
 | 
			
		||||
        else
 | 
			
		||||
          retry_number += 1
 | 
			
		||||
          retry if retry_number < @connect_retry
 | 
			
		||||
        end
 | 
			
		||||
        close
 | 
			
		||||
        raise
 | 
			
		||||
      end
 | 
			
		||||
      @state = :WAIT
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def create_socket(site)
 | 
			
		||||
      socket = nil
 | 
			
		||||
      begin
 | 
			
		||||
        @debug_dev << "! CONNECT TO #{site.host}:#{site.port}\n" if @debug_dev
 | 
			
		||||
        if str = @test_loopback_http_response.shift
 | 
			
		||||
          socket = LoopBackSocket.new(site.host, site.port, str)
 | 
			
		||||
        else
 | 
			
		||||
          socket = TCPSocket.new(site.host, site.port)
 | 
			
		||||
        end
 | 
			
		||||
        if @debug_dev
 | 
			
		||||
          @debug_dev << "! CONNECTION ESTABLISHED\n"
 | 
			
		||||
          socket.extend(DebugSocket)
 | 
			
		||||
          socket.debug_dev = @debug_dev
 | 
			
		||||
        end
 | 
			
		||||
      rescue SystemCallError => e
 | 
			
		||||
        e.message << " (#{site})"
 | 
			
		||||
        raise
 | 
			
		||||
      rescue SocketError => e
 | 
			
		||||
        e.message << " (#{site})"
 | 
			
		||||
        raise
 | 
			
		||||
      end
 | 
			
		||||
      socket
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # wrap socket with OpenSSL.
 | 
			
		||||
    def create_ssl_socket(raw_socket)
 | 
			
		||||
      SSLSocketWrap.new(raw_socket, @ssl_config, @debug_dev)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def connect_ssl_proxy(socket, uri)
 | 
			
		||||
      req = HTTP::Message.new_connect_request(uri)
 | 
			
		||||
      @client.request_filter.each do |filter|
 | 
			
		||||
        filter.filter_request(req)
 | 
			
		||||
      end
 | 
			
		||||
      set_header(req)
 | 
			
		||||
      req.dump(@socket)
 | 
			
		||||
      @socket.flush unless @socket_sync
 | 
			
		||||
      res = HTTP::Message.new_response('')
 | 
			
		||||
      parse_header
 | 
			
		||||
      res.version, res.status, res.reason = @version, @status, @reason
 | 
			
		||||
      @headers.each do |key, value|
 | 
			
		||||
        res.header.set(key, value)
 | 
			
		||||
      end
 | 
			
		||||
      commands = @client.request_filter.collect { |filter|
 | 
			
		||||
        filter.filter_response(req, res)
 | 
			
		||||
      }
 | 
			
		||||
      if commands.find { |command| command == :retry }
 | 
			
		||||
        raise RetryableResponse.new
 | 
			
		||||
      end
 | 
			
		||||
      unless @status == 200
 | 
			
		||||
        raise BadResponseError.new("connect to ssl proxy failed with status #{@status} #{@reason}", res)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Read status block.
 | 
			
		||||
    def read_header
 | 
			
		||||
      @content_length = nil
 | 
			
		||||
      @chunked = false
 | 
			
		||||
      @chunk_length = 0
 | 
			
		||||
      parse_header
 | 
			
		||||
 | 
			
		||||
      # Head of the request has been parsed.
 | 
			
		||||
      @state = :DATA
 | 
			
		||||
      req = @requests.shift
 | 
			
		||||
 | 
			
		||||
      if req.header.request_method == 'HEAD'
 | 
			
		||||
        @content_length = 0
 | 
			
		||||
        if @next_connection
 | 
			
		||||
          @state = :WAIT
 | 
			
		||||
        else
 | 
			
		||||
          close
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
      @next_connection = false unless @content_length
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    StatusParseRegexp = %r(\AHTTP/(\d+\.\d+)\s+(\d\d\d)\s*([^\r\n]+)?\r?\n\z)
 | 
			
		||||
    def parse_header
 | 
			
		||||
      timeout(@receive_timeout, ReceiveTimeoutError) do
 | 
			
		||||
        begin
 | 
			
		||||
          initial_line = @socket.gets("\n")
 | 
			
		||||
          if initial_line.nil?
 | 
			
		||||
            raise KeepAliveDisconnected.new
 | 
			
		||||
          end
 | 
			
		||||
          if StatusParseRegexp !~ initial_line
 | 
			
		||||
            @version = '0.9'
 | 
			
		||||
            @status = nil
 | 
			
		||||
            @reason = nil
 | 
			
		||||
            @next_connection = false
 | 
			
		||||
            @content_length = nil
 | 
			
		||||
            @readbuf = initial_line
 | 
			
		||||
            break
 | 
			
		||||
          end
 | 
			
		||||
          @version, @status, @reason = $1, $2.to_i, $3
 | 
			
		||||
          @next_connection = HTTP::Message.keep_alive_enabled?(@version.to_f)
 | 
			
		||||
          @headers = []
 | 
			
		||||
          while true
 | 
			
		||||
            line = @socket.gets("\n")
 | 
			
		||||
            unless line
 | 
			
		||||
              raise BadResponseError.new('unexpected EOF')
 | 
			
		||||
            end
 | 
			
		||||
            line.chomp!
 | 
			
		||||
            break if line.empty?
 | 
			
		||||
            key, value = line.split(/\s*:\s*/, 2)
 | 
			
		||||
            parse_keepalive_header(key, value)
 | 
			
		||||
            @headers << [key, value]
 | 
			
		||||
          end
 | 
			
		||||
        end while (@version == '1.1' && @status == 100)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def parse_keepalive_header(key, value)
 | 
			
		||||
      key = key.downcase
 | 
			
		||||
      if key == 'content-length'
 | 
			
		||||
        @content_length = value.to_i
 | 
			
		||||
      elsif key == 'transfer-encoding' and value.downcase == 'chunked'
 | 
			
		||||
        @chunked = true
 | 
			
		||||
        @chunk_length = 0
 | 
			
		||||
        @content_length = nil
 | 
			
		||||
      elsif key == 'connection' or key == 'proxy-connection'
 | 
			
		||||
        if value.downcase == 'keep-alive'
 | 
			
		||||
          @next_connection = true
 | 
			
		||||
        else
 | 
			
		||||
          @next_connection = false
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def read_body_length(&block)
 | 
			
		||||
      return nil if @content_length == 0
 | 
			
		||||
      buf = ''
 | 
			
		||||
      while true
 | 
			
		||||
        maxbytes = @read_block_size
 | 
			
		||||
        maxbytes = @content_length if maxbytes > @content_length
 | 
			
		||||
        timeout(@receive_timeout, ReceiveTimeoutError) do
 | 
			
		||||
          begin
 | 
			
		||||
            @socket.readpartial(maxbytes, buf)
 | 
			
		||||
          rescue EOFError
 | 
			
		||||
            buf = nil
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
        if buf && buf.length > 0
 | 
			
		||||
          @content_length -= buf.length
 | 
			
		||||
          yield buf
 | 
			
		||||
        else
 | 
			
		||||
          @content_length = 0
 | 
			
		||||
        end
 | 
			
		||||
        return if @content_length == 0
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    RS = "\r\n"
 | 
			
		||||
    def read_body_chunked(&block)
 | 
			
		||||
      buf = ''
 | 
			
		||||
      while true
 | 
			
		||||
        len = @socket.gets(RS)
 | 
			
		||||
        @chunk_length = len.hex
 | 
			
		||||
        if @chunk_length == 0
 | 
			
		||||
          @content_length = 0
 | 
			
		||||
          @socket.gets(RS)
 | 
			
		||||
          return
 | 
			
		||||
        end
 | 
			
		||||
        timeout(@receive_timeout, ReceiveTimeoutError) do
 | 
			
		||||
          @socket.read(@chunk_length + 2, buf)
 | 
			
		||||
        end
 | 
			
		||||
        unless buf.empty?
 | 
			
		||||
          yield buf.slice(0, @chunk_length)
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def read_body_rest
 | 
			
		||||
      if @readbuf and @readbuf.length > 0
 | 
			
		||||
        yield @readbuf
 | 
			
		||||
        @readbuf = nil
 | 
			
		||||
      end
 | 
			
		||||
      buf = ''
 | 
			
		||||
      while true
 | 
			
		||||
        timeout(@receive_timeout, ReceiveTimeoutError) do
 | 
			
		||||
          begin
 | 
			
		||||
            @socket.readpartial(@read_block_size, buf)
 | 
			
		||||
          rescue EOFError
 | 
			
		||||
            buf = nil
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
        if buf && buf.length > 0
 | 
			
		||||
          yield buf
 | 
			
		||||
        else
 | 
			
		||||
          return
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										417
									
								
								vendor/gems/gems/httpclient-2.1.5.2/lib/httpclient/ssl_config.rb
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,417 @@
 | 
			
		|||
# HTTPClient - HTTP client library.
 | 
			
		||||
# Copyright (C) 2000-2009  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>.
 | 
			
		||||
#
 | 
			
		||||
# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
 | 
			
		||||
# redistribute it and/or modify it under the same terms of Ruby's license;
 | 
			
		||||
# either the dual license version in 2003, or any later version.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class HTTPClient
 | 
			
		||||
 | 
			
		||||
  begin
 | 
			
		||||
    require 'openssl'
 | 
			
		||||
    SSLEnabled = true
 | 
			
		||||
  rescue LoadError
 | 
			
		||||
    SSLEnabled = false
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # Represents SSL configuration for HTTPClient instance.
 | 
			
		||||
  # The implementation depends on OpenSSL.
 | 
			
		||||
  #
 | 
			
		||||
  # == Trust Anchor Control
 | 
			
		||||
  #
 | 
			
		||||
  # SSLConfig loads 'httpclient/cacert.p7s' as a trust anchor
 | 
			
		||||
  # (trusted certificate(s)) with set_trust_ca in initialization time.
 | 
			
		||||
  # This means that HTTPClient instance trusts some CA certificates by default,
 | 
			
		||||
  # like Web browsers.  'httpclient/cacert.p7s' is created by the author and
 | 
			
		||||
  # included in released package.
 | 
			
		||||
  #
 | 
			
		||||
  # 'cacert.p7s' is automatically generated from JDK 1.6.
 | 
			
		||||
  #
 | 
			
		||||
  # You may want to change trust anchor by yourself.  Call clear_cert_store
 | 
			
		||||
  # then set_trust_ca for that purpose.
 | 
			
		||||
  class SSLConfig
 | 
			
		||||
    include OpenSSL if SSLEnabled
 | 
			
		||||
 | 
			
		||||
    # OpenSSL::X509::Certificate:: certificate for SSL client authenticateion.
 | 
			
		||||
    # nil by default. (no client authenticateion)
 | 
			
		||||
    attr_reader :client_cert
 | 
			
		||||
    # OpenSSL::PKey::PKey:: private key for SSL client authentication.
 | 
			
		||||
    # nil by default. (no client authenticateion)
 | 
			
		||||
    attr_reader :client_key
 | 
			
		||||
 | 
			
		||||
    # A number which represents OpenSSL's verify mode.  Default value is
 | 
			
		||||
    # OpenSSL::SSL::VERIFY_PEER | OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT.
 | 
			
		||||
    attr_reader :verify_mode
 | 
			
		||||
    # A number of verify depth.  Certification path which length is longer than
 | 
			
		||||
    # this depth is not allowed.
 | 
			
		||||
    attr_reader :verify_depth
 | 
			
		||||
    # A callback handler for custom certificate verification.  nil by default.
 | 
			
		||||
    # If the handler is set, handler.call is invoked just after general
 | 
			
		||||
    # OpenSSL's verification.  handler.call is invoked with 2 arguments,
 | 
			
		||||
    # ok and ctx; ok is a result of general OpenSSL's verification.  ctx is a
 | 
			
		||||
    # OpenSSL::X509::StoreContext.
 | 
			
		||||
    attr_reader :verify_callback
 | 
			
		||||
    # SSL timeout in sec.  nil by default.
 | 
			
		||||
    attr_reader :timeout
 | 
			
		||||
    # A number of OpenSSL's SSL options.  Default value is
 | 
			
		||||
    # OpenSSL::SSL::OP_ALL | OpenSSL::SSL::OP_NO_SSLv2
 | 
			
		||||
    attr_reader :options
 | 
			
		||||
    # A String of OpenSSL's cipher configuration.  Default value is
 | 
			
		||||
    # ALL:!ADH:!LOW:!EXP:!MD5:+SSLv2:@STRENGTH
 | 
			
		||||
    # See ciphers(1) man in OpenSSL for more detail.
 | 
			
		||||
    attr_reader :ciphers
 | 
			
		||||
 | 
			
		||||
    # OpenSSL::X509::X509::Store used for verification.  You can reset the
 | 
			
		||||
    # store with clear_cert_store and set the new store with cert_store=.
 | 
			
		||||
    attr_reader :cert_store # don't use if you don't know what it is.
 | 
			
		||||
 | 
			
		||||
    # For server side configuration.  Ignore this.
 | 
			
		||||
    attr_reader :client_ca # :nodoc:
 | 
			
		||||
 | 
			
		||||
    # Creates a SSLConfig.
 | 
			
		||||
    def initialize(client)
 | 
			
		||||
      return unless SSLEnabled
 | 
			
		||||
      @client = client
 | 
			
		||||
      @cert_store = X509::Store.new
 | 
			
		||||
      @client_cert = @client_key = @client_ca = nil
 | 
			
		||||
      @verify_mode = SSL::VERIFY_PEER | SSL::VERIFY_FAIL_IF_NO_PEER_CERT
 | 
			
		||||
      @verify_depth = nil
 | 
			
		||||
      @verify_callback = nil
 | 
			
		||||
      @dest = nil
 | 
			
		||||
      @timeout = nil
 | 
			
		||||
      @options = defined?(SSL::OP_ALL) ? SSL::OP_ALL | SSL::OP_NO_SSLv2 : nil
 | 
			
		||||
      @ciphers = "ALL:!ADH:!LOW:!EXP:!MD5:+SSLv2:@STRENGTH"
 | 
			
		||||
      load_cacerts
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Sets certificate (OpenSSL::X509::Certificate) for SSL client
 | 
			
		||||
    # authentication.
 | 
			
		||||
    # client_key and client_cert must be a pair.
 | 
			
		||||
    #
 | 
			
		||||
    # Calling this method resets all existing sessions.
 | 
			
		||||
    def client_cert=(client_cert)
 | 
			
		||||
      @client_cert = client_cert
 | 
			
		||||
      change_notify
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Sets private key (OpenSSL::PKey::PKey) for SSL client authentication.
 | 
			
		||||
    # client_key and client_cert must be a pair.
 | 
			
		||||
    #
 | 
			
		||||
    # Calling this method resets all existing sessions.
 | 
			
		||||
    def client_key=(client_key)
 | 
			
		||||
      @client_key = client_key
 | 
			
		||||
      change_notify
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Sets certificate and private key for SSL client authentication.
 | 
			
		||||
    # cert_file:: must be a filename of PEM/DER formatted file.
 | 
			
		||||
    # key_file:: must be a filename of PEM/DER formatted file.  Key must be an
 | 
			
		||||
    #            RSA key.  If you want to use other PKey algorithm,
 | 
			
		||||
    #            use client_key=.
 | 
			
		||||
    #
 | 
			
		||||
    # Calling this method resets all existing sessions.
 | 
			
		||||
    def set_client_cert_file(cert_file, key_file)
 | 
			
		||||
      @client_cert = X509::Certificate.new(File.open(cert_file).read)
 | 
			
		||||
      @client_key = PKey::RSA.new(File.open(key_file).read)
 | 
			
		||||
      change_notify
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Drops current certificate store (OpenSSL::X509::Store) for SSL and create
 | 
			
		||||
    # new one for the next session.
 | 
			
		||||
    #
 | 
			
		||||
    # Calling this method resets all existing sessions.
 | 
			
		||||
    def clear_cert_store
 | 
			
		||||
      @cert_store = X509::Store.new
 | 
			
		||||
      change_notify
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Sets new certificate store (OpenSSL::X509::Store).
 | 
			
		||||
    # don't use if you don't know what it is.
 | 
			
		||||
    #
 | 
			
		||||
    # Calling this method resets all existing sessions.
 | 
			
		||||
    def cert_store=(cert_store)
 | 
			
		||||
      @cert_store = cert_store
 | 
			
		||||
      change_notify
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Sets trust anchor certificate(s) for verification.
 | 
			
		||||
    # trust_ca_file_or_hashed_dir:: a filename of a PEM/DER formatted
 | 
			
		||||
    #                               OpenSSL::X509::Certificate or
 | 
			
		||||
    #                               a 'c-rehash'eddirectory name which stores
 | 
			
		||||
    #                               trusted certificate files.
 | 
			
		||||
    #
 | 
			
		||||
    # Calling this method resets all existing sessions.
 | 
			
		||||
    def set_trust_ca(trust_ca_file_or_hashed_dir)
 | 
			
		||||
      if FileTest.directory?(trust_ca_file_or_hashed_dir)
 | 
			
		||||
        @cert_store.add_path(trust_ca_file_or_hashed_dir)
 | 
			
		||||
      else
 | 
			
		||||
        @cert_store.add_file(trust_ca_file_or_hashed_dir)
 | 
			
		||||
      end
 | 
			
		||||
      change_notify
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Adds CRL for verification.
 | 
			
		||||
    # crl:: a OpenSSL::X509::CRL or a filename of a PEM/DER formatted
 | 
			
		||||
    #       OpenSSL::X509::CRL.
 | 
			
		||||
    #
 | 
			
		||||
    # Calling this method resets all existing sessions.
 | 
			
		||||
    def set_crl(crl)
 | 
			
		||||
      unless crl.is_a?(X509::CRL)
 | 
			
		||||
        crl = X509::CRL.new(File.open(crl).read)
 | 
			
		||||
      end
 | 
			
		||||
      @cert_store.add_crl(crl)
 | 
			
		||||
      @cert_store.flags = X509::V_FLAG_CRL_CHECK | X509::V_FLAG_CRL_CHECK_ALL
 | 
			
		||||
      change_notify
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Sets verify mode of OpenSSL.  New value must be a combination of
 | 
			
		||||
    # constants OpenSSL::SSL::VERIFY_*
 | 
			
		||||
    #
 | 
			
		||||
    # Calling this method resets all existing sessions.
 | 
			
		||||
    def verify_mode=(verify_mode)
 | 
			
		||||
      @verify_mode = verify_mode
 | 
			
		||||
      change_notify
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Sets verify depth.  New value must be a number.
 | 
			
		||||
    #
 | 
			
		||||
    # Calling this method resets all existing sessions.
 | 
			
		||||
    def verify_depth=(verify_depth)
 | 
			
		||||
      @verify_depth = verify_depth
 | 
			
		||||
      change_notify
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Sets callback handler for custom certificate verification.
 | 
			
		||||
    # See verify_callback.
 | 
			
		||||
    #
 | 
			
		||||
    # Calling this method resets all existing sessions.
 | 
			
		||||
    def verify_callback=(verify_callback)
 | 
			
		||||
      @verify_callback = verify_callback
 | 
			
		||||
      change_notify
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Sets SSL timeout in sec.
 | 
			
		||||
    #
 | 
			
		||||
    # Calling this method resets all existing sessions.
 | 
			
		||||
    def timeout=(timeout)
 | 
			
		||||
      @timeout = timeout
 | 
			
		||||
      change_notify
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Sets SSL options.  New value must be a combination of # constants
 | 
			
		||||
    # OpenSSL::SSL::OP_*
 | 
			
		||||
    #
 | 
			
		||||
    # Calling this method resets all existing sessions.
 | 
			
		||||
    def options=(options)
 | 
			
		||||
      @options = options
 | 
			
		||||
      change_notify
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Sets cipher configuration.  New value must be a String.
 | 
			
		||||
    #
 | 
			
		||||
    # Calling this method resets all existing sessions.
 | 
			
		||||
    def ciphers=(ciphers)
 | 
			
		||||
      @ciphers = ciphers
 | 
			
		||||
      change_notify
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def client_ca=(client_ca) # :nodoc:
 | 
			
		||||
      @client_ca = client_ca
 | 
			
		||||
      change_notify
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # interfaces for SSLSocketWrap.
 | 
			
		||||
    def set_context(ctx) # :nodoc:
 | 
			
		||||
      # Verification: Use Store#verify_callback instead of SSLContext#verify*?
 | 
			
		||||
      ctx.cert_store = @cert_store
 | 
			
		||||
      ctx.verify_mode = @verify_mode
 | 
			
		||||
      ctx.verify_depth = @verify_depth if @verify_depth
 | 
			
		||||
      ctx.verify_callback = @verify_callback || method(:default_verify_callback)
 | 
			
		||||
      # SSL config
 | 
			
		||||
      ctx.cert = @client_cert
 | 
			
		||||
      ctx.key = @client_key
 | 
			
		||||
      ctx.client_ca = @client_ca
 | 
			
		||||
      ctx.timeout = @timeout
 | 
			
		||||
      ctx.options = @options
 | 
			
		||||
      ctx.ciphers = @ciphers
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # post connection check proc for ruby < 1.8.5.
 | 
			
		||||
    # this definition must match with the one in ext/openssl/lib/openssl/ssl.rb
 | 
			
		||||
    def post_connection_check(peer_cert, hostname) # :nodoc:
 | 
			
		||||
      check_common_name = true
 | 
			
		||||
      cert = peer_cert
 | 
			
		||||
      cert.extensions.each{|ext|
 | 
			
		||||
        next if ext.oid != "subjectAltName"
 | 
			
		||||
        ext.value.split(/,\s+/).each{|general_name|
 | 
			
		||||
          if /\ADNS:(.*)/ =~ general_name
 | 
			
		||||
            check_common_name = false
 | 
			
		||||
            reg = Regexp.escape($1).gsub(/\\\*/, "[^.]+")
 | 
			
		||||
            return true if /\A#{reg}\z/i =~ hostname
 | 
			
		||||
          elsif /\AIP Address:(.*)/ =~ general_name
 | 
			
		||||
            check_common_name = false
 | 
			
		||||
            return true if $1 == hostname
 | 
			
		||||
          end
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      if check_common_name
 | 
			
		||||
        cert.subject.to_a.each{|oid, value|
 | 
			
		||||
          if oid == "CN"
 | 
			
		||||
            reg = Regexp.escape(value).gsub(/\\\*/, "[^.]+")
 | 
			
		||||
            return true if /\A#{reg}\z/i =~ hostname
 | 
			
		||||
          end
 | 
			
		||||
        }
 | 
			
		||||
      end
 | 
			
		||||
      raise SSL::SSLError, "hostname was not match with the server certificate"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Default callback for verification: only dumps error.
 | 
			
		||||
    def default_verify_callback(is_ok, ctx)
 | 
			
		||||
      if $DEBUG
 | 
			
		||||
        puts "#{ is_ok ? 'ok' : 'ng' }: #{ctx.current_cert.subject}"
 | 
			
		||||
      end
 | 
			
		||||
      if !is_ok
 | 
			
		||||
        depth = ctx.error_depth
 | 
			
		||||
        code = ctx.error
 | 
			
		||||
        msg = ctx.error_string
 | 
			
		||||
        STDERR.puts "at depth #{depth} - #{code}: #{msg}"
 | 
			
		||||
      end
 | 
			
		||||
      is_ok
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Sample callback method:  CAUTION: does not check CRL/ARL.
 | 
			
		||||
    def sample_verify_callback(is_ok, ctx)
 | 
			
		||||
      unless is_ok
 | 
			
		||||
        depth = ctx.error_depth
 | 
			
		||||
        code = ctx.error
 | 
			
		||||
        msg = ctx.error_string
 | 
			
		||||
        STDERR.puts "at depth #{depth} - #{code}: #{msg}" if $DEBUG
 | 
			
		||||
        return false
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      cert = ctx.current_cert
 | 
			
		||||
      self_signed = false
 | 
			
		||||
      ca = false
 | 
			
		||||
      pathlen = nil
 | 
			
		||||
      server_auth = true
 | 
			
		||||
      self_signed = (cert.subject.cmp(cert.issuer) == 0)
 | 
			
		||||
 | 
			
		||||
      # Check extensions whatever its criticality is. (sample)
 | 
			
		||||
      cert.extensions.each do |ex|
 | 
			
		||||
        case ex.oid
 | 
			
		||||
        when 'basicConstraints'
 | 
			
		||||
          /CA:(TRUE|FALSE), pathlen:(\d+)/ =~ ex.value
 | 
			
		||||
          ca = ($1 == 'TRUE')
 | 
			
		||||
          pathlen = $2.to_i
 | 
			
		||||
        when 'keyUsage'
 | 
			
		||||
          usage = ex.value.split(/\s*,\s*/)
 | 
			
		||||
          ca = usage.include?('Certificate Sign')
 | 
			
		||||
          server_auth = usage.include?('Key Encipherment')
 | 
			
		||||
        when 'extendedKeyUsage'
 | 
			
		||||
          usage = ex.value.split(/\s*,\s*/)
 | 
			
		||||
          server_auth = usage.include?('Netscape Server Gated Crypto')
 | 
			
		||||
        when 'nsCertType'
 | 
			
		||||
          usage = ex.value.split(/\s*,\s*/)
 | 
			
		||||
          ca = usage.include?('SSL CA')
 | 
			
		||||
          server_auth = usage.include?('SSL Server')
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      if self_signed
 | 
			
		||||
        STDERR.puts 'self signing CA' if $DEBUG
 | 
			
		||||
        return true
 | 
			
		||||
      elsif ca
 | 
			
		||||
        STDERR.puts 'middle level CA' if $DEBUG
 | 
			
		||||
        return true
 | 
			
		||||
      elsif server_auth
 | 
			
		||||
        STDERR.puts 'for server authentication' if $DEBUG
 | 
			
		||||
        return true
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      return false
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
  private
 | 
			
		||||
 | 
			
		||||
    def change_notify
 | 
			
		||||
      @client.reset_all
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def load_cacerts
 | 
			
		||||
      [
 | 
			
		||||
        [DIST_CERT, 'cacert.p7s'],
 | 
			
		||||
        [DIST_CERT_SHA1, 'cacert_sha1.p7s']
 | 
			
		||||
      ].each do |cert_str, ca_file|
 | 
			
		||||
        file = File.join(File.dirname(__FILE__), ca_file)
 | 
			
		||||
        if File.exist?(file)
 | 
			
		||||
          p7 = PKCS7.read_smime(File.open(file) { |f| f.read })
 | 
			
		||||
          selfcert = X509::Certificate.new(cert_str)
 | 
			
		||||
          store = X509::Store.new
 | 
			
		||||
          store.add_cert(selfcert)
 | 
			
		||||
          if (p7.verify(nil, store, p7.data, 0))
 | 
			
		||||
            set_trust_ca(file)
 | 
			
		||||
            return
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
      STDERR.puts("cacerts loading failed")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    DIST_CERT =<<__DIST_CERT__
 | 
			
		||||
-----BEGIN CERTIFICATE-----
 | 
			
		||||
MIID/TCCAuWgAwIBAgIBATANBgkqhkiG9w0BAQ0FADBLMQswCQYDVQQGEwJKUDER
 | 
			
		||||
MA8GA1UECgwIY3Rvci5vcmcxFDASBgNVBAsMC0RldmVsb3BtZW50MRMwEQYDVQQD
 | 
			
		||||
DApodHRwY2xpZW50MB4XDTA5MDUyMTEyMzkwNVoXDTM3MTIzMTIzNTk1OVowSzEL
 | 
			
		||||
MAkGA1UEBhMCSlAxETAPBgNVBAoMCGN0b3Iub3JnMRQwEgYDVQQLDAtEZXZlbG9w
 | 
			
		||||
bWVudDETMBEGA1UEAwwKaHR0cGNsaWVudDCCASIwDQYJKoZIhvcNAQEBBQADggEP
 | 
			
		||||
ADCCAQoCggEBAM2PlkdTH97zvIHoPIMj87wnNvpqIQUD7L/hlysO0XBsmR/XZUeU
 | 
			
		||||
ZKB10JQqMXviWpTnU9KU6xGTx3EI4wfd2dpLwH/d4d7K4LngW1kY7kJlZeJhakno
 | 
			
		||||
GzQ40RSI9WkQ0R9KOE888f7OkTBafcL8UyWFVIMhQBw2d9iNl4Jc69QojayCDoSX
 | 
			
		||||
XbbEP0n8yi7HwIU3RFuX6DtMpOx4/1K7Z002ccOGJ3J9kHgeDQSQtF42cQYC7qj2
 | 
			
		||||
67I/OQgnB7ycxTCP0E7bdXQg+zqsngrhaoNn/+I+CoO7nD4t4uQ+B4agALh4PPxs
 | 
			
		||||
bQD9MCL+VurNGLYv0HVd+ZlLblpddC9PLTsCAwEAAaOB6zCB6DAPBgNVHRMBAf8E
 | 
			
		||||
BTADAQH/MDEGCWCGSAGG+EIBDQQkFiJSdWJ5L09wZW5TU0wgR2VuZXJhdGVkIENl
 | 
			
		||||
cnRpZmljYXRlMB0GA1UdDgQWBBRAnB6XlMoOcm7HVAw+JWxY205PHTAOBgNVHQ8B
 | 
			
		||||
Af8EBAMCAQYwcwYDVR0jBGwwaoAUQJwel5TKDnJux1QMPiVsWNtOTx2hT6RNMEsx
 | 
			
		||||
CzAJBgNVBAYTAkpQMREwDwYDVQQKDAhjdG9yLm9yZzEUMBIGA1UECwwLRGV2ZWxv
 | 
			
		||||
cG1lbnQxEzARBgNVBAMMCmh0dHBjbGllbnSCAQEwDQYJKoZIhvcNAQENBQADggEB
 | 
			
		||||
ABVFepybD5XqsBnOn/oDHvK0xAPMF4Ap4Ht1yMQLObg8paVhANSdqIevPlCr/mPL
 | 
			
		||||
DRjcy+J1fCnE6lCfsfLdTgAjirqt8pm92NccxmJ8hTmMd3LWC1n+eYWaolqTCVRM
 | 
			
		||||
Bpe8UY9enyXrFoudHlr9epr18E6As6VrCSfpXFZkD9WHVSWpzkB3qATu5qcDCzCH
 | 
			
		||||
bI0755Mdm/1hKJCD4l69h3J3OhRIEUPJfHnPvM5wtiyC2dcE9itwE/wdVzBJeIBX
 | 
			
		||||
JQm+Qj+K8qXcRTzZZGIBjw2n46xJgW6YncNCHU/WWfNCYwdkngHS/aN8IbEjhCwf
 | 
			
		||||
viXFisVrDN/+pZZGMf67ZaY=
 | 
			
		||||
-----END CERTIFICATE-----
 | 
			
		||||
__DIST_CERT__
 | 
			
		||||
 | 
			
		||||
    DIST_CERT_SHA1 =<<__DIST_CERT__
 | 
			
		||||
-----BEGIN CERTIFICATE-----
 | 
			
		||||
MIID/TCCAuWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJKUDER
 | 
			
		||||
MA8GA1UECgwIY3Rvci5vcmcxFDASBgNVBAsMC0RldmVsb3BtZW50MRMwEQYDVQQD
 | 
			
		||||
DApodHRwY2xpZW50MB4XDTA5MDYyNTE0MjUzN1oXDTEwMTIzMTIzNTk1OVowSzEL
 | 
			
		||||
MAkGA1UEBhMCSlAxETAPBgNVBAoMCGN0b3Iub3JnMRQwEgYDVQQLDAtEZXZlbG9w
 | 
			
		||||
bWVudDETMBEGA1UEAwwKaHR0cGNsaWVudDCCASIwDQYJKoZIhvcNAQEBBQADggEP
 | 
			
		||||
ADCCAQoCggEBAM2PlkdTH97zvIHoPIMj87wnNvpqIQUD7L/hlysO0XBsmR/XZUeU
 | 
			
		||||
ZKB10JQqMXviWpTnU9KU6xGTx3EI4wfd2dpLwH/d4d7K4LngW1kY7kJlZeJhakno
 | 
			
		||||
GzQ40RSI9WkQ0R9KOE888f7OkTBafcL8UyWFVIMhQBw2d9iNl4Jc69QojayCDoSX
 | 
			
		||||
XbbEP0n8yi7HwIU3RFuX6DtMpOx4/1K7Z002ccOGJ3J9kHgeDQSQtF42cQYC7qj2
 | 
			
		||||
67I/OQgnB7ycxTCP0E7bdXQg+zqsngrhaoNn/+I+CoO7nD4t4uQ+B4agALh4PPxs
 | 
			
		||||
bQD9MCL+VurNGLYv0HVd+ZlLblpddC9PLTsCAwEAAaOB6zCB6DAPBgNVHRMBAf8E
 | 
			
		||||
BTADAQH/MDEGCWCGSAGG+EIBDQQkFiJSdWJ5L09wZW5TU0wgR2VuZXJhdGVkIENl
 | 
			
		||||
cnRpZmljYXRlMB0GA1UdDgQWBBRAnB6XlMoOcm7HVAw+JWxY205PHTAOBgNVHQ8B
 | 
			
		||||
Af8EBAMCAQYwcwYDVR0jBGwwaoAUQJwel5TKDnJux1QMPiVsWNtOTx2hT6RNMEsx
 | 
			
		||||
CzAJBgNVBAYTAkpQMREwDwYDVQQKDAhjdG9yLm9yZzEUMBIGA1UECwwLRGV2ZWxv
 | 
			
		||||
cG1lbnQxEzARBgNVBAMMCmh0dHBjbGllbnSCAQIwDQYJKoZIhvcNAQEFBQADggEB
 | 
			
		||||
AGKhgByl/ur6SBFFKJcISJONFRaxf2ji0l6ut9XO1H2BSOSRjUbsFDWdWZG+D24Q
 | 
			
		||||
JKKseSWPWAC5uHq00sBWkvmtip+duESPeDEdumdBhdiUUgGamW2Ew2y4yAdAVDeG
 | 
			
		||||
t1p2fs8SylQN6AMTG/+R+MGHxhvg+UELYLcvAjjcDW2VhDQaJ1eFEfcMW1zRtvvh
 | 
			
		||||
LJmVErouwFKyAjwhbF6sNxmToSnbO1ciWwIILMsOBNHMETCp+SzkRDIRWIkm6m+q
 | 
			
		||||
RwRyYoHysODGvnu8VXS1hGRr2GIxeBga7dAGa2VLE/iUQ0d4lEskYU+6C4ZLyAWF
 | 
			
		||||
O89dvLNRzpL10MaWCYVREks=
 | 
			
		||||
-----END CERTIFICATE-----
 | 
			
		||||
__DIST_CERT__
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										136
									
								
								vendor/gems/gems/httpclient-2.1.5.2/lib/httpclient/timeout.rb
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,136 @@
 | 
			
		|||
# HTTPClient - HTTP client library.
 | 
			
		||||
# Copyright (C) 2000-2009  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>.
 | 
			
		||||
#
 | 
			
		||||
# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
 | 
			
		||||
# redistribute it and/or modify it under the same terms of Ruby's license;
 | 
			
		||||
# either the dual license version in 2003, or any later version.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
require 'timeout'
 | 
			
		||||
require 'thread'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class HTTPClient
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  # Replaces timeout.rb to avoid Thread creation and scheduling overhead.
 | 
			
		||||
  #
 | 
			
		||||
  # You should check another timeout replace in WEBrick.
 | 
			
		||||
  # See lib/webrick/utils.rb in ruby/1.9.
 | 
			
		||||
  #
 | 
			
		||||
  # About this implementation:
 | 
			
		||||
  # * Do not create Thread for each timeout() call.  Just create 1 Thread for
 | 
			
		||||
  #   timeout scheduler.
 | 
			
		||||
  # * Do not wakeup the scheduler thread so often.  Let scheduler thread sleep
 | 
			
		||||
  #   until the nearest period.
 | 
			
		||||
  class TimeoutScheduler
 | 
			
		||||
 | 
			
		||||
    # Represents timeout period.
 | 
			
		||||
    class Period
 | 
			
		||||
      attr_reader :thread, :time
 | 
			
		||||
 | 
			
		||||
      # Creates new Period.
 | 
			
		||||
      def initialize(thread, time, ex)
 | 
			
		||||
        @thread, @time, @ex = thread, time, ex
 | 
			
		||||
        @lock = Mutex.new
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Raises if thread exists and alive.
 | 
			
		||||
      def raise(message)
 | 
			
		||||
        @lock.synchronize do
 | 
			
		||||
          if @thread and @thread.alive?
 | 
			
		||||
            @thread.raise(@ex, message)
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Cancel this Period.  Mutex is needed to avoid too-late exception.
 | 
			
		||||
      def cancel
 | 
			
		||||
        @lock.synchronize do
 | 
			
		||||
          @thread = nil
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Creates new TimeoutScheduler.
 | 
			
		||||
    def initialize
 | 
			
		||||
      @pool = {}
 | 
			
		||||
      @next = nil
 | 
			
		||||
      @thread = start_timer_thread
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Registers new timeout period.
 | 
			
		||||
    def register(thread, sec, ex)
 | 
			
		||||
      period = Period.new(thread, Time.now + sec, ex || ::Timeout::Error)
 | 
			
		||||
      @pool[period] = true
 | 
			
		||||
      if @next.nil? or period.time < @next
 | 
			
		||||
        begin
 | 
			
		||||
          @thread.wakeup
 | 
			
		||||
        rescue ThreadError
 | 
			
		||||
          # Thread may be dead by fork.
 | 
			
		||||
          @thread = start_timer_thread
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
      period
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Cancels the given period.
 | 
			
		||||
    def cancel(period)
 | 
			
		||||
      @pool.delete(period)
 | 
			
		||||
      period.cancel
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
  private
 | 
			
		||||
 | 
			
		||||
    def start_timer_thread
 | 
			
		||||
      thread = Thread.new {
 | 
			
		||||
        while true
 | 
			
		||||
          if @pool.empty?
 | 
			
		||||
            @next = nil
 | 
			
		||||
            sleep
 | 
			
		||||
          else
 | 
			
		||||
            min, = @pool.min { |a, b| a[0].time <=> b[0].time }
 | 
			
		||||
            @next = min.time
 | 
			
		||||
            sec = @next - Time.now
 | 
			
		||||
            if sec > 0
 | 
			
		||||
              sleep(sec)
 | 
			
		||||
            end
 | 
			
		||||
          end
 | 
			
		||||
          now = Time.now
 | 
			
		||||
          @pool.keys.each do |period|
 | 
			
		||||
            if period.time < now
 | 
			
		||||
              period.raise('execution expired')
 | 
			
		||||
              cancel(period)
 | 
			
		||||
            end
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      }
 | 
			
		||||
      Thread.pass while thread.status != 'sleep'
 | 
			
		||||
      thread
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  class << self
 | 
			
		||||
    # CAUTION: caller must aware of race condition.
 | 
			
		||||
    def timeout_scheduler
 | 
			
		||||
      @timeout_scheduler ||= TimeoutScheduler.new
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
  timeout_scheduler # initialize at first time.
 | 
			
		||||
 | 
			
		||||
  module Timeout
 | 
			
		||||
    def timeout(sec, ex = nil, &block)
 | 
			
		||||
      return yield if sec == nil or sec.zero?
 | 
			
		||||
      scheduler = nil
 | 
			
		||||
      begin
 | 
			
		||||
        scheduler = HTTPClient.timeout_scheduler
 | 
			
		||||
        period = scheduler.register(Thread.current, sec, ex)
 | 
			
		||||
        yield(sec)
 | 
			
		||||
      ensure
 | 
			
		||||
        scheduler.cancel(period) if scheduler and period
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										86
									
								
								vendor/gems/gems/httpclient-2.1.5.2/lib/httpclient/util.rb
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,86 @@
 | 
			
		|||
# HTTPClient - HTTP client library.
 | 
			
		||||
# Copyright (C) 2000-2009  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>.
 | 
			
		||||
#
 | 
			
		||||
# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
 | 
			
		||||
# redistribute it and/or modify it under the same terms of Ruby's license;
 | 
			
		||||
# either the dual license version in 2003, or any later version.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
require 'uri'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class HTTPClient
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  # A module for common function.
 | 
			
		||||
  module Util
 | 
			
		||||
    # Keyword argument helper.
 | 
			
		||||
    # args:: given arguments.
 | 
			
		||||
    # *field:: a list of arguments to be extracted.
 | 
			
		||||
    #
 | 
			
		||||
    # You can extract 3 arguments (a, b, c) with:
 | 
			
		||||
    #
 | 
			
		||||
    #   include Util
 | 
			
		||||
    #   def my_method(*args)
 | 
			
		||||
    #     a, b, c = keyword_argument(args, :a, :b, :c)
 | 
			
		||||
    #     ...
 | 
			
		||||
    #   end
 | 
			
		||||
    #   my_method(1, 2, 3)
 | 
			
		||||
    #   my_method(:b => 2, :a = 1)
 | 
			
		||||
    #
 | 
			
		||||
    # instead of;
 | 
			
		||||
    #
 | 
			
		||||
    #   def my_method(a, b, c)
 | 
			
		||||
    #     ...
 | 
			
		||||
    #   end
 | 
			
		||||
    #
 | 
			
		||||
    def keyword_argument(args, *field)
 | 
			
		||||
      if args.size == 1 and args[0].is_a?(Hash)
 | 
			
		||||
        args[0].values_at(*field)
 | 
			
		||||
      else
 | 
			
		||||
        args
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Gets an URI instance.
 | 
			
		||||
    def urify(uri)
 | 
			
		||||
      if uri.nil?
 | 
			
		||||
        nil
 | 
			
		||||
      elsif uri.is_a?(URI)
 | 
			
		||||
        uri
 | 
			
		||||
      else
 | 
			
		||||
        URI.parse(uri.to_s)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Returns true if the given 2 URIs have a part_of relationship.
 | 
			
		||||
    # * the same scheme
 | 
			
		||||
    # * the same host String (no host resolution or IP-addr conversion)
 | 
			
		||||
    # * the same port number
 | 
			
		||||
    # * target URI's path starts with base URI's path.
 | 
			
		||||
    def uri_part_of(uri, part)
 | 
			
		||||
      ((uri.scheme == part.scheme) and
 | 
			
		||||
       (uri.host == part.host) and
 | 
			
		||||
       (uri.port == part.port) and
 | 
			
		||||
       uri.path.upcase.index(part.path.upcase) == 0)
 | 
			
		||||
    end
 | 
			
		||||
    module_function :uri_part_of
 | 
			
		||||
 | 
			
		||||
    # Returns parent directory URI of the given URI.
 | 
			
		||||
    def uri_dirname(uri)
 | 
			
		||||
      uri = uri.clone
 | 
			
		||||
      uri.path = uri.path.sub(/\/[^\/]*\z/, '/')
 | 
			
		||||
      uri
 | 
			
		||||
    end
 | 
			
		||||
    module_function :uri_dirname
 | 
			
		||||
 | 
			
		||||
    # Finds a value of a Hash.
 | 
			
		||||
    def hash_find_value(hash, &block)
 | 
			
		||||
      v = hash.find(&block)
 | 
			
		||||
      v ? v[1] : nil
 | 
			
		||||
    end
 | 
			
		||||
    module_function :hash_find_value
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										908
									
								
								vendor/gems/gems/httpclient-2.1.5.2/lib/tags
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,908 @@
 | 
			
		|||
::HTTP	httpclient/http.rb	/^module HTTP/
 | 
			
		||||
::HTTP::Message	httpclient/http.rb	/^  class Message/
 | 
			
		||||
::HTTP::Message#HTTP::Message.new	httpclient/http.rb	/^    def initialize/
 | 
			
		||||
::HTTP::Message#body	httpclient/http.rb	/^    attr_reader :body/
 | 
			
		||||
::HTTP::Message#body=	httpclient/http.rb	/^    def body=/
 | 
			
		||||
::HTTP::Message#code	httpclient/http.rb	/^    alias code/
 | 
			
		||||
::HTTP::Message#content	httpclient/http.rb	/^    def content/
 | 
			
		||||
::HTTP::Message#contenttype	httpclient/http.rb	/^    def contenttype/
 | 
			
		||||
::HTTP::Message#contenttype=	httpclient/http.rb	/^    def contenttype=/
 | 
			
		||||
::HTTP::Message#dump	httpclient/http.rb	/^    def dump/
 | 
			
		||||
::HTTP::Message#header	httpclient/http.rb	/^    attr_accessor :header/
 | 
			
		||||
::HTTP::Message#peer_cert	httpclient/http.rb	/^    attr_accessor :peer_cert/
 | 
			
		||||
::HTTP::Message#reason	httpclient/http.rb	/^    def reason/
 | 
			
		||||
::HTTP::Message#reason=	httpclient/http.rb	/^    def reason=/
 | 
			
		||||
::HTTP::Message#status	httpclient/http.rb	/^    def status/
 | 
			
		||||
::HTTP::Message#status=	httpclient/http.rb	/^    def status=/
 | 
			
		||||
::HTTP::Message#status_code	httpclient/http.rb	/^    alias status_code/
 | 
			
		||||
::HTTP::Message#version	httpclient/http.rb	/^    def version/
 | 
			
		||||
::HTTP::Message#version=	httpclient/http.rb	/^    def version=/
 | 
			
		||||
::HTTP::Message.create_query_part_str	httpclient/http.rb	/^      def create_query_part_str/
 | 
			
		||||
::HTTP::Message.escape	httpclient/http.rb	/^      def escape/
 | 
			
		||||
::HTTP::Message.escape_query	httpclient/http.rb	/^      def escape_query/
 | 
			
		||||
::HTTP::Message.file?	httpclient/http.rb	/^      def file?/
 | 
			
		||||
::HTTP::Message.get_mime_type_func	httpclient/http.rb	/^      alias get_mime_type_func/
 | 
			
		||||
::HTTP::Message.internal_mime_type	httpclient/http.rb	/^      def internal_mime_type/
 | 
			
		||||
::HTTP::Message.keep_alive_enabled?	httpclient/http.rb	/^      def keep_alive_enabled?/
 | 
			
		||||
::HTTP::Message.mime_type	httpclient/http.rb	/^      def mime_type/
 | 
			
		||||
::HTTP::Message.mime_type_handler	httpclient/http.rb	/^      def mime_type_handler/
 | 
			
		||||
::HTTP::Message.mime_type_handler=	httpclient/http.rb	/^      def mime_type_handler=/
 | 
			
		||||
::HTTP::Message.multiparam_query?	httpclient/http.rb	/^      def multiparam_query?/
 | 
			
		||||
::HTTP::Message.new_connect_request	httpclient/http.rb	/^      def new_connect_request/
 | 
			
		||||
::HTTP::Message.new_request	httpclient/http.rb	/^      def new_request/
 | 
			
		||||
::HTTP::Message.new_response	httpclient/http.rb	/^      def new_response/
 | 
			
		||||
::HTTP::Message.set_mime_type_func	httpclient/http.rb	/^      alias set_mime_type_func/
 | 
			
		||||
::HTTP::Message::Body	httpclient/http.rb	/^    class Body/
 | 
			
		||||
::HTTP::Message::Body#HTTP::Message::Body.new	httpclient/http.rb	/^      def initialize/
 | 
			
		||||
::HTTP::Message::Body#build_query_multipart_str	httpclient/http.rb	/^      def build_query_multipart_str/
 | 
			
		||||
::HTTP::Message::Body#chunk_size	httpclient/http.rb	/^      attr_accessor :chunk_size/
 | 
			
		||||
::HTTP::Message::Body#content	httpclient/http.rb	/^      def content/
 | 
			
		||||
::HTTP::Message::Body#dump	httpclient/http.rb	/^      def dump/
 | 
			
		||||
::HTTP::Message::Body#dump_chunk	httpclient/http.rb	/^      def dump_chunk/
 | 
			
		||||
::HTTP::Message::Body#dump_chunk_size	httpclient/http.rb	/^      def dump_chunk_size/
 | 
			
		||||
::HTTP::Message::Body#dump_chunked	httpclient/http.rb	/^      def dump_chunked/
 | 
			
		||||
::HTTP::Message::Body#dump_chunks	httpclient/http.rb	/^      def dump_chunks/
 | 
			
		||||
::HTTP::Message::Body#dump_last_chunk	httpclient/http.rb	/^      def dump_last_chunk/
 | 
			
		||||
::HTTP::Message::Body#init_request	httpclient/http.rb	/^      def init_request/
 | 
			
		||||
::HTTP::Message::Body#init_response	httpclient/http.rb	/^      def init_response/
 | 
			
		||||
::HTTP::Message::Body#params_from_file	httpclient/http.rb	/^      def params_from_file/
 | 
			
		||||
::HTTP::Message::Body#remember_pos	httpclient/http.rb	/^      def remember_pos/
 | 
			
		||||
::HTTP::Message::Body#reset_pos	httpclient/http.rb	/^      def reset_pos/
 | 
			
		||||
::HTTP::Message::Body#set_content	httpclient/http.rb	/^      def set_content/
 | 
			
		||||
::HTTP::Message::Body#size	httpclient/http.rb	/^      attr_reader :size/
 | 
			
		||||
::HTTP::Message::Body::Parts	httpclient/http.rb	/^      class Parts/
 | 
			
		||||
::HTTP::Message::Body::Parts#HTTP::Message::Body::Parts.new	httpclient/http.rb	/^        def initialize/
 | 
			
		||||
::HTTP::Message::Body::Parts#add	httpclient/http.rb	/^        def add/
 | 
			
		||||
::HTTP::Message::Body::Parts#parts	httpclient/http.rb	/^        def parts/
 | 
			
		||||
::HTTP::Message::Body::Parts#size	httpclient/http.rb	/^        attr_reader :size/
 | 
			
		||||
::HTTP::Message::Headers	httpclient/http.rb	/^    class Headers/
 | 
			
		||||
::HTTP::Message::Headers#HTTP::Message::Headers.new	httpclient/http.rb	/^      def initialize/
 | 
			
		||||
::HTTP::Message::Headers#[]	httpclient/http.rb	/^      def []/
 | 
			
		||||
::HTTP::Message::Headers#[]=	httpclient/http.rb	/^      def []=/
 | 
			
		||||
::HTTP::Message::Headers#add	httpclient/http.rb	/^      def add/
 | 
			
		||||
::HTTP::Message::Headers#all	httpclient/http.rb	/^      def all/
 | 
			
		||||
::HTTP::Message::Headers#body_charset	httpclient/http.rb	/^      attr_accessor :body_charset # :nodoc:/
 | 
			
		||||
::HTTP::Message::Headers#body_date	httpclient/http.rb	/^      attr_accessor :body_date # :nodoc:/
 | 
			
		||||
::HTTP::Message::Headers#body_size	httpclient/http.rb	/^      attr_reader :body_size/
 | 
			
		||||
::HTTP::Message::Headers#body_size=	httpclient/http.rb	/^      def body_size=/
 | 
			
		||||
::HTTP::Message::Headers#body_type	httpclient/http.rb	/^      attr_accessor :body_type # :nodoc:/
 | 
			
		||||
::HTTP::Message::Headers#charset_label	httpclient/http.rb	/^      def charset_label/
 | 
			
		||||
::HTTP::Message::Headers#chunked	httpclient/http.rb	/^      attr_accessor :chunked/
 | 
			
		||||
::HTTP::Message::Headers#contenttype	httpclient/http.rb	/^      def contenttype/
 | 
			
		||||
::HTTP::Message::Headers#contenttype=	httpclient/http.rb	/^      def contenttype=/
 | 
			
		||||
::HTTP::Message::Headers#create_query_uri	httpclient/http.rb	/^      def create_query_uri/
 | 
			
		||||
::HTTP::Message::Headers#delete	httpclient/http.rb	/^      def delete/
 | 
			
		||||
::HTTP::Message::Headers#dump	httpclient/http.rb	/^      def dump/
 | 
			
		||||
::HTTP::Message::Headers#get	httpclient/http.rb	/^      def get/
 | 
			
		||||
::HTTP::Message::Headers#http_version	httpclient/http.rb	/^      attr_accessor :http_version/
 | 
			
		||||
::HTTP::Message::Headers#init_connect_request	httpclient/http.rb	/^      def init_connect_request/
 | 
			
		||||
::HTTP::Message::Headers#init_request	httpclient/http.rb	/^      def init_request/
 | 
			
		||||
::HTTP::Message::Headers#init_response	httpclient/http.rb	/^      def init_response/
 | 
			
		||||
::HTTP::Message::Headers#reason_phrase	httpclient/http.rb	/^      attr_accessor :reason_phrase/
 | 
			
		||||
::HTTP::Message::Headers#request_line	httpclient/http.rb	/^      def request_line/
 | 
			
		||||
::HTTP::Message::Headers#request_method	httpclient/http.rb	/^      attr_reader :request_method/
 | 
			
		||||
::HTTP::Message::Headers#request_query	httpclient/http.rb	/^      attr_accessor :request_query/
 | 
			
		||||
::HTTP::Message::Headers#request_uri	httpclient/http.rb	/^      attr_accessor :request_uri/
 | 
			
		||||
::HTTP::Message::Headers#request_via_proxy	httpclient/http.rb	/^      attr_accessor :request_via_proxy/
 | 
			
		||||
::HTTP::Message::Headers#response_status_line	httpclient/http.rb	/^      def response_status_line/
 | 
			
		||||
::HTTP::Message::Headers#set	httpclient/http.rb	/^      def set/
 | 
			
		||||
::HTTP::Message::Headers#set_header	httpclient/http.rb	/^      def set_header/
 | 
			
		||||
::HTTP::Message::Headers#set_request_header	httpclient/http.rb	/^      def set_request_header/
 | 
			
		||||
::HTTP::Message::Headers#set_response_header	httpclient/http.rb	/^      def set_response_header/
 | 
			
		||||
::HTTP::Message::Headers#status_code	httpclient/http.rb	/^      attr_reader :status_code/
 | 
			
		||||
::HTTP::Message::Headers#status_code=	httpclient/http.rb	/^      def status_code=/
 | 
			
		||||
::HTTP::Status	httpclient/http.rb	/^  module Status/
 | 
			
		||||
::HTTP::Status.redirect?	httpclient/http.rb	/^    def self.redirect?/
 | 
			
		||||
::HTTP::Status.successful?	httpclient/http.rb	/^    def self.successful?/
 | 
			
		||||
::HTTPClient	httpclient.rb	/^class HTTPClient/
 | 
			
		||||
::HTTPClient	httpclient/auth.rb	/^class HTTPClient/
 | 
			
		||||
::HTTPClient	httpclient/connection.rb	/^class HTTPClient/
 | 
			
		||||
::HTTPClient	httpclient/session.rb	/^class HTTPClient/
 | 
			
		||||
::HTTPClient	httpclient/ssl_config.rb	/^class HTTPClient/
 | 
			
		||||
::HTTPClient	httpclient/timeout.rb	/^class HTTPClient/
 | 
			
		||||
::HTTPClient	httpclient/util.rb	/^class HTTPClient/
 | 
			
		||||
::HTTPClient#HTTPClient.new	httpclient.rb	/^  def initialize/
 | 
			
		||||
::HTTPClient#cookie_manager	httpclient.rb	/^  attr_accessor :cookie_manager/
 | 
			
		||||
::HTTPClient#create_boundary	httpclient.rb	/^  def create_boundary/
 | 
			
		||||
::HTTPClient#create_request	httpclient.rb	/^  def create_request/
 | 
			
		||||
::HTTPClient#debug_dev	httpclient.rb	/^  def debug_dev/
 | 
			
		||||
::HTTPClient#debug_dev=	httpclient.rb	/^  def debug_dev=/
 | 
			
		||||
::HTTPClient#default_redirect_uri_callback	httpclient.rb	/^  def default_redirect_uri_callback/
 | 
			
		||||
::HTTPClient#delete	httpclient.rb	/^  def delete/
 | 
			
		||||
::HTTPClient#delete_async	httpclient.rb	/^  def delete_async/
 | 
			
		||||
::HTTPClient#do_get_block	httpclient.rb	/^  def do_get_block/
 | 
			
		||||
::HTTPClient#do_get_header	httpclient.rb	/^  def do_get_header/
 | 
			
		||||
::HTTPClient#do_get_stream	httpclient.rb	/^  def do_get_stream/
 | 
			
		||||
::HTTPClient#do_request	httpclient.rb	/^  def do_request/
 | 
			
		||||
::HTTPClient#do_request_async	httpclient.rb	/^  def do_request_async/
 | 
			
		||||
::HTTPClient#dump_dummy_request_response	httpclient.rb	/^  def dump_dummy_request_response/
 | 
			
		||||
::HTTPClient#file_in_form_data?	httpclient.rb	/^  def file_in_form_data?/
 | 
			
		||||
::HTTPClient#follow_redirect	httpclient.rb	/^  def follow_redirect/
 | 
			
		||||
::HTTPClient#follow_redirect_count	httpclient.rb	/^  attr_accessor :follow_redirect_count/
 | 
			
		||||
::HTTPClient#get	httpclient.rb	/^  def get/
 | 
			
		||||
::HTTPClient#get_async	httpclient.rb	/^  def get_async/
 | 
			
		||||
::HTTPClient#get_content	httpclient.rb	/^  def get_content/
 | 
			
		||||
::HTTPClient#getenv	httpclient.rb	/^  def getenv/
 | 
			
		||||
::HTTPClient#head	httpclient.rb	/^  def head/
 | 
			
		||||
::HTTPClient#head_async	httpclient.rb	/^  def head_async/
 | 
			
		||||
::HTTPClient#https?	httpclient.rb	/^  def https?/
 | 
			
		||||
::HTTPClient#load_environment	httpclient.rb	/^  def load_environment/
 | 
			
		||||
::HTTPClient#no_proxy	httpclient.rb	/^  def no_proxy/
 | 
			
		||||
::HTTPClient#no_proxy=	httpclient.rb	/^  def no_proxy=/
 | 
			
		||||
::HTTPClient#no_proxy?	httpclient.rb	/^  def no_proxy?/
 | 
			
		||||
::HTTPClient#options	httpclient.rb	/^  def options/
 | 
			
		||||
::HTTPClient#options_async	httpclient.rb	/^  def options_async/
 | 
			
		||||
::HTTPClient#override_header	httpclient.rb	/^  def override_header/
 | 
			
		||||
::HTTPClient#post	httpclient.rb	/^  def post/
 | 
			
		||||
::HTTPClient#post_async	httpclient.rb	/^  def post_async/
 | 
			
		||||
::HTTPClient#post_content	httpclient.rb	/^  def post_content/
 | 
			
		||||
::HTTPClient#propfind	httpclient.rb	/^  def propfind/
 | 
			
		||||
::HTTPClient#propfind_async	httpclient.rb	/^  def propfind_async/
 | 
			
		||||
::HTTPClient#proppatch	httpclient.rb	/^  def proppatch/
 | 
			
		||||
::HTTPClient#proppatch_async	httpclient.rb	/^  def proppatch_async/
 | 
			
		||||
::HTTPClient#protect_keep_alive_disconnected	httpclient.rb	/^  def protect_keep_alive_disconnected/
 | 
			
		||||
::HTTPClient#proxy	httpclient.rb	/^  def proxy/
 | 
			
		||||
::HTTPClient#proxy=	httpclient.rb	/^  def proxy=/
 | 
			
		||||
::HTTPClient#proxy_auth	httpclient.rb	/^  attr_reader :proxy_auth/
 | 
			
		||||
::HTTPClient#put	httpclient.rb	/^  def put/
 | 
			
		||||
::HTTPClient#put_async	httpclient.rb	/^  def put_async/
 | 
			
		||||
::HTTPClient#redirect_uri_callback=	httpclient.rb	/^  def redirect_uri_callback=/
 | 
			
		||||
::HTTPClient#request	httpclient.rb	/^  def request/
 | 
			
		||||
::HTTPClient#request_async	httpclient.rb	/^  def request_async/
 | 
			
		||||
::HTTPClient#request_filter	httpclient.rb	/^  attr_reader :request_filter/
 | 
			
		||||
::HTTPClient#reset	httpclient.rb	/^  def reset/
 | 
			
		||||
::HTTPClient#reset_all	httpclient.rb	/^  def reset_all/
 | 
			
		||||
::HTTPClient#save_cookie_store	httpclient.rb	/^  def save_cookie_store/
 | 
			
		||||
::HTTPClient#set_auth	httpclient.rb	/^  def set_auth/
 | 
			
		||||
::HTTPClient#set_basic_auth	httpclient.rb	/^  def set_basic_auth/
 | 
			
		||||
::HTTPClient#set_cookie_store	httpclient.rb	/^  def set_cookie_store/
 | 
			
		||||
::HTTPClient#set_proxy_auth	httpclient.rb	/^  def set_proxy_auth/
 | 
			
		||||
::HTTPClient#ssl_config	httpclient.rb	/^  attr_reader :ssl_config/
 | 
			
		||||
::HTTPClient#strict_redirect_uri_callback	httpclient.rb	/^  def strict_redirect_uri_callback/
 | 
			
		||||
::HTTPClient#test_loopback_response	httpclient.rb	/^  attr_reader :test_loopback_response/
 | 
			
		||||
::HTTPClient#trace	httpclient.rb	/^  def trace/
 | 
			
		||||
::HTTPClient#trace_async	httpclient.rb	/^  def trace_async/
 | 
			
		||||
::HTTPClient#www_auth	httpclient.rb	/^  attr_reader :www_auth/
 | 
			
		||||
::HTTPClient.attr_proxy	httpclient.rb	/^    def attr_proxy/
 | 
			
		||||
::HTTPClient.timeout_scheduler	httpclient/timeout.rb	/^    def timeout_scheduler/
 | 
			
		||||
::HTTPClient::AuthFilterBase	httpclient/auth.rb	/^  class AuthFilterBase/
 | 
			
		||||
::HTTPClient::AuthFilterBase#parse_authentication_header	httpclient/auth.rb	/^    def parse_authentication_header/
 | 
			
		||||
::HTTPClient::AuthFilterBase#parse_challenge_header	httpclient/auth.rb	/^    def parse_challenge_header/
 | 
			
		||||
::HTTPClient::BadResponseError	httpclient.rb	/^  class BadResponseError/
 | 
			
		||||
::HTTPClient::BadResponseError#HTTPClient::BadResponseError.new	httpclient.rb	/^    def initialize/
 | 
			
		||||
::HTTPClient::BadResponseError#res	httpclient.rb	/^    attr_reader :res/
 | 
			
		||||
::HTTPClient::BasicAuth	httpclient/auth.rb	/^  class BasicAuth/
 | 
			
		||||
::HTTPClient::BasicAuth#HTTPClient::BasicAuth.new	httpclient/auth.rb	/^    def initialize/
 | 
			
		||||
::HTTPClient::BasicAuth#challenge	httpclient/auth.rb	/^    def challenge/
 | 
			
		||||
::HTTPClient::BasicAuth#get	httpclient/auth.rb	/^    def get/
 | 
			
		||||
::HTTPClient::BasicAuth#reset_challenge	httpclient/auth.rb	/^    def reset_challenge/
 | 
			
		||||
::HTTPClient::BasicAuth#scheme	httpclient/auth.rb	/^    attr_reader :scheme/
 | 
			
		||||
::HTTPClient::BasicAuth#set	httpclient/auth.rb	/^    def set/
 | 
			
		||||
::HTTPClient::ConfigurationError	httpclient.rb	/^  class ConfigurationError/
 | 
			
		||||
::HTTPClient::ConnectTimeoutError	httpclient.rb	/^  class ConnectTimeoutError/
 | 
			
		||||
::HTTPClient::Connection	httpclient/connection.rb	/^  class Connection/
 | 
			
		||||
::HTTPClient::Connection#HTTPClient::Connection.new	httpclient/connection.rb	/^    def initialize/
 | 
			
		||||
::HTTPClient::Connection#async_thread	httpclient/connection.rb	/^    attr_accessor :async_thread/
 | 
			
		||||
::HTTPClient::Connection#finished?	httpclient/connection.rb	/^    def finished?/
 | 
			
		||||
::HTTPClient::Connection#join	httpclient/connection.rb	/^    def join/
 | 
			
		||||
::HTTPClient::Connection#pop	httpclient/connection.rb	/^    def pop/
 | 
			
		||||
::HTTPClient::Connection#push	httpclient/connection.rb	/^    def push/
 | 
			
		||||
::HTTPClient::DebugSocket	httpclient/session.rb	/^  module DebugSocket/
 | 
			
		||||
::HTTPClient::DebugSocket#<<	httpclient/session.rb	/^    def <</
 | 
			
		||||
::HTTPClient::DebugSocket#close	httpclient/session.rb	/^    def close/
 | 
			
		||||
::HTTPClient::DebugSocket#debug	httpclient/session.rb	/^    def debug/
 | 
			
		||||
::HTTPClient::DebugSocket#debug_dev=	httpclient/session.rb	/^    def debug_dev=/
 | 
			
		||||
::HTTPClient::DebugSocket#gets	httpclient/session.rb	/^    def gets/
 | 
			
		||||
::HTTPClient::DebugSocket#read	httpclient/session.rb	/^    def read/
 | 
			
		||||
::HTTPClient::DebugSocket#readpartial	httpclient/session.rb	/^    def readpartial/
 | 
			
		||||
::HTTPClient::DigestAuth	httpclient/auth.rb	/^  class DigestAuth/
 | 
			
		||||
::HTTPClient::DigestAuth#HTTPClient::DigestAuth.new	httpclient/auth.rb	/^    def initialize/
 | 
			
		||||
::HTTPClient::DigestAuth#calc_cred	httpclient/auth.rb	/^    def calc_cred/
 | 
			
		||||
::HTTPClient::DigestAuth#challenge	httpclient/auth.rb	/^    def challenge/
 | 
			
		||||
::HTTPClient::DigestAuth#get	httpclient/auth.rb	/^    def get/
 | 
			
		||||
::HTTPClient::DigestAuth#parse_challenge_param	httpclient/auth.rb	/^    def parse_challenge_param/
 | 
			
		||||
::HTTPClient::DigestAuth#reset_challenge	httpclient/auth.rb	/^    def reset_challenge/
 | 
			
		||||
::HTTPClient::DigestAuth#scheme	httpclient/auth.rb	/^    attr_reader :scheme/
 | 
			
		||||
::HTTPClient::DigestAuth#set	httpclient/auth.rb	/^    def set/
 | 
			
		||||
::HTTPClient::KeepAliveDisconnected	httpclient.rb	/^  class KeepAliveDisconnected/
 | 
			
		||||
::HTTPClient::LoopBackSocket	httpclient/session.rb	/^  class LoopBackSocket/
 | 
			
		||||
::HTTPClient::LoopBackSocket#<<	httpclient/session.rb	/^    def <</
 | 
			
		||||
::HTTPClient::LoopBackSocket#HTTPClient::LoopBackSocket.new	httpclient/session.rb	/^    def initialize/
 | 
			
		||||
::HTTPClient::NegotiateAuth	httpclient/auth.rb	/^  class NegotiateAuth/
 | 
			
		||||
::HTTPClient::NegotiateAuth#HTTPClient::NegotiateAuth.new	httpclient/auth.rb	/^    def initialize/
 | 
			
		||||
::HTTPClient::NegotiateAuth#challenge	httpclient/auth.rb	/^    def challenge/
 | 
			
		||||
::HTTPClient::NegotiateAuth#get	httpclient/auth.rb	/^    def get/
 | 
			
		||||
::HTTPClient::NegotiateAuth#ntlm_opt	httpclient/auth.rb	/^    attr_reader :ntlm_opt/
 | 
			
		||||
::HTTPClient::NegotiateAuth#reset_challenge	httpclient/auth.rb	/^    def reset_challenge/
 | 
			
		||||
::HTTPClient::NegotiateAuth#scheme	httpclient/auth.rb	/^    attr_reader :scheme/
 | 
			
		||||
::HTTPClient::NegotiateAuth#set	httpclient/auth.rb	/^    def set/
 | 
			
		||||
::HTTPClient::ProxyAuth	httpclient/auth.rb	/^  class ProxyAuth/
 | 
			
		||||
::HTTPClient::ProxyAuth#HTTPClient::ProxyAuth.new	httpclient/auth.rb	/^    def initialize/
 | 
			
		||||
::HTTPClient::ProxyAuth#basic_auth	httpclient/auth.rb	/^    attr_reader :basic_auth/
 | 
			
		||||
::HTTPClient::ProxyAuth#filter_request	httpclient/auth.rb	/^    def filter_request/
 | 
			
		||||
::HTTPClient::ProxyAuth#filter_response	httpclient/auth.rb	/^    def filter_response/
 | 
			
		||||
::HTTPClient::ProxyAuth#negotiate_auth	httpclient/auth.rb	/^    attr_reader :negotiate_auth/
 | 
			
		||||
::HTTPClient::ProxyAuth#reset_challenge	httpclient/auth.rb	/^    def reset_challenge/
 | 
			
		||||
::HTTPClient::ProxyAuth#set_auth	httpclient/auth.rb	/^    def set_auth/
 | 
			
		||||
::HTTPClient::ProxyAuth#sspi_negotiate_auth	httpclient/auth.rb	/^    attr_reader :sspi_negotiate_auth/
 | 
			
		||||
::HTTPClient::ReceiveTimeoutError	httpclient.rb	/^  class ReceiveTimeoutError/
 | 
			
		||||
::HTTPClient::RetryableResponse	httpclient.rb	/^  class RetryableResponse/
 | 
			
		||||
::HTTPClient::SSLConfig	httpclient/ssl_config.rb	/^  class SSLConfig/
 | 
			
		||||
::HTTPClient::SSLConfig#HTTPClient::SSLConfig.new	httpclient/ssl_config.rb	/^    def initialize/
 | 
			
		||||
::HTTPClient::SSLConfig#cert_store	httpclient/ssl_config.rb	/^    attr_reader :cert_store # don't use if you don't know what it is./
 | 
			
		||||
::HTTPClient::SSLConfig#cert_store=	httpclient/ssl_config.rb	/^    def cert_store=/
 | 
			
		||||
::HTTPClient::SSLConfig#change_notify	httpclient/ssl_config.rb	/^    def change_notify/
 | 
			
		||||
::HTTPClient::SSLConfig#ciphers	httpclient/ssl_config.rb	/^    attr_reader :ciphers/
 | 
			
		||||
::HTTPClient::SSLConfig#ciphers=	httpclient/ssl_config.rb	/^    def ciphers=/
 | 
			
		||||
::HTTPClient::SSLConfig#clear_cert_store	httpclient/ssl_config.rb	/^    def clear_cert_store/
 | 
			
		||||
::HTTPClient::SSLConfig#client_ca	httpclient/ssl_config.rb	/^    attr_reader :client_ca # :nodoc:/
 | 
			
		||||
::HTTPClient::SSLConfig#client_ca=	httpclient/ssl_config.rb	/^    def client_ca=/
 | 
			
		||||
::HTTPClient::SSLConfig#client_cert	httpclient/ssl_config.rb	/^    attr_reader :client_cert/
 | 
			
		||||
::HTTPClient::SSLConfig#client_cert=	httpclient/ssl_config.rb	/^    def client_cert=/
 | 
			
		||||
::HTTPClient::SSLConfig#client_key	httpclient/ssl_config.rb	/^    attr_reader :client_key/
 | 
			
		||||
::HTTPClient::SSLConfig#client_key=	httpclient/ssl_config.rb	/^    def client_key=/
 | 
			
		||||
::HTTPClient::SSLConfig#default_verify_callback	httpclient/ssl_config.rb	/^    def default_verify_callback/
 | 
			
		||||
::HTTPClient::SSLConfig#load_cacerts	httpclient/ssl_config.rb	/^    def load_cacerts/
 | 
			
		||||
::HTTPClient::SSLConfig#options	httpclient/ssl_config.rb	/^    attr_reader :options/
 | 
			
		||||
::HTTPClient::SSLConfig#options=	httpclient/ssl_config.rb	/^    def options=/
 | 
			
		||||
::HTTPClient::SSLConfig#post_connection_check	httpclient/ssl_config.rb	/^    def post_connection_check/
 | 
			
		||||
::HTTPClient::SSLConfig#sample_verify_callback	httpclient/ssl_config.rb	/^    def sample_verify_callback/
 | 
			
		||||
::HTTPClient::SSLConfig#set_client_cert_file	httpclient/ssl_config.rb	/^    def set_client_cert_file/
 | 
			
		||||
::HTTPClient::SSLConfig#set_context	httpclient/ssl_config.rb	/^    def set_context/
 | 
			
		||||
::HTTPClient::SSLConfig#set_crl	httpclient/ssl_config.rb	/^    def set_crl/
 | 
			
		||||
::HTTPClient::SSLConfig#set_trust_ca	httpclient/ssl_config.rb	/^    def set_trust_ca/
 | 
			
		||||
::HTTPClient::SSLConfig#timeout	httpclient/ssl_config.rb	/^    attr_reader :timeout/
 | 
			
		||||
::HTTPClient::SSLConfig#timeout=	httpclient/ssl_config.rb	/^    def timeout=/
 | 
			
		||||
::HTTPClient::SSLConfig#verify_callback	httpclient/ssl_config.rb	/^    attr_reader :verify_callback/
 | 
			
		||||
::HTTPClient::SSLConfig#verify_callback=	httpclient/ssl_config.rb	/^    def verify_callback=/
 | 
			
		||||
::HTTPClient::SSLConfig#verify_depth	httpclient/ssl_config.rb	/^    attr_reader :verify_depth/
 | 
			
		||||
::HTTPClient::SSLConfig#verify_depth=	httpclient/ssl_config.rb	/^    def verify_depth=/
 | 
			
		||||
::HTTPClient::SSLConfig#verify_mode	httpclient/ssl_config.rb	/^    attr_reader :verify_mode/
 | 
			
		||||
::HTTPClient::SSLConfig#verify_mode=	httpclient/ssl_config.rb	/^    def verify_mode=/
 | 
			
		||||
::HTTPClient::SSLSocketWrap	httpclient/session.rb	/^  class SSLSocketWrap/
 | 
			
		||||
::HTTPClient::SSLSocketWrap#<<	httpclient/session.rb	/^    def <</
 | 
			
		||||
::HTTPClient::SSLSocketWrap#HTTPClient::SSLSocketWrap.new	httpclient/session.rb	/^    def initialize/
 | 
			
		||||
::HTTPClient::SSLSocketWrap#check_mask	httpclient/session.rb	/^    def check_mask/
 | 
			
		||||
::HTTPClient::SSLSocketWrap#close	httpclient/session.rb	/^    def close/
 | 
			
		||||
::HTTPClient::SSLSocketWrap#closed?	httpclient/session.rb	/^    def closed?/
 | 
			
		||||
::HTTPClient::SSLSocketWrap#create_openssl_socket	httpclient/session.rb	/^    def create_openssl_socket/
 | 
			
		||||
::HTTPClient::SSLSocketWrap#debug	httpclient/session.rb	/^    def debug/
 | 
			
		||||
::HTTPClient::SSLSocketWrap#eof?	httpclient/session.rb	/^    def eof?/
 | 
			
		||||
::HTTPClient::SSLSocketWrap#flush	httpclient/session.rb	/^    def flush/
 | 
			
		||||
::HTTPClient::SSLSocketWrap#gets	httpclient/session.rb	/^    def gets/
 | 
			
		||||
::HTTPClient::SSLSocketWrap#peer_cert	httpclient/session.rb	/^    def peer_cert/
 | 
			
		||||
::HTTPClient::SSLSocketWrap#post_connection_check	httpclient/session.rb	/^    def post_connection_check/
 | 
			
		||||
::HTTPClient::SSLSocketWrap#read	httpclient/session.rb	/^    def read/
 | 
			
		||||
::HTTPClient::SSLSocketWrap#readpartial	httpclient/session.rb	/^    def readpartial/
 | 
			
		||||
::HTTPClient::SSLSocketWrap#ssl_connect	httpclient/session.rb	/^    def ssl_connect/
 | 
			
		||||
::HTTPClient::SSLSocketWrap#sync	httpclient/session.rb	/^    def sync/
 | 
			
		||||
::HTTPClient::SSLSocketWrap#sync=	httpclient/session.rb	/^    def sync=/
 | 
			
		||||
::HTTPClient::SSPINegotiateAuth	httpclient/auth.rb	/^  class SSPINegotiateAuth/
 | 
			
		||||
::HTTPClient::SSPINegotiateAuth#HTTPClient::SSPINegotiateAuth.new	httpclient/auth.rb	/^    def initialize/
 | 
			
		||||
::HTTPClient::SSPINegotiateAuth#challenge	httpclient/auth.rb	/^    def challenge/
 | 
			
		||||
::HTTPClient::SSPINegotiateAuth#get	httpclient/auth.rb	/^    def get/
 | 
			
		||||
::HTTPClient::SSPINegotiateAuth#reset_challenge	httpclient/auth.rb	/^    def reset_challenge/
 | 
			
		||||
::HTTPClient::SSPINegotiateAuth#scheme	httpclient/auth.rb	/^    attr_reader :scheme/
 | 
			
		||||
::HTTPClient::SSPINegotiateAuth#set	httpclient/auth.rb	/^    def set/
 | 
			
		||||
::HTTPClient::SendTimeoutError	httpclient.rb	/^  class SendTimeoutError/
 | 
			
		||||
::HTTPClient::Session	httpclient.rb	/^  class Session/
 | 
			
		||||
::HTTPClient::Session	httpclient/session.rb	/^  class Session/
 | 
			
		||||
::HTTPClient::Session#HTTPClient::Session.new	httpclient/session.rb	/^    def initialize/
 | 
			
		||||
::HTTPClient::Session#close	httpclient/session.rb	/^    def close/
 | 
			
		||||
::HTTPClient::Session#closed?	httpclient/session.rb	/^    def closed?/
 | 
			
		||||
::HTTPClient::Session#connect	httpclient/session.rb	/^    def connect/
 | 
			
		||||
::HTTPClient::Session#connect_retry	httpclient/session.rb	/^    attr_accessor :connect_retry/
 | 
			
		||||
::HTTPClient::Session#connect_ssl_proxy	httpclient/session.rb	/^    def connect_ssl_proxy/
 | 
			
		||||
::HTTPClient::Session#connect_timeout	httpclient/session.rb	/^    attr_accessor :connect_timeout/
 | 
			
		||||
::HTTPClient::Session#create_socket	httpclient/session.rb	/^    def create_socket/
 | 
			
		||||
::HTTPClient::Session#create_ssl_socket	httpclient/session.rb	/^    def create_ssl_socket/
 | 
			
		||||
::HTTPClient::Session#debug_dev	httpclient/session.rb	/^    attr_accessor :debug_dev/
 | 
			
		||||
::HTTPClient::Session#dest	httpclient/session.rb	/^    attr_reader :dest/
 | 
			
		||||
::HTTPClient::Session#eof?	httpclient/session.rb	/^    def eof?/
 | 
			
		||||
::HTTPClient::Session#get_body	httpclient/session.rb	/^    def get_body/
 | 
			
		||||
::HTTPClient::Session#get_header	httpclient/session.rb	/^    def get_header/
 | 
			
		||||
::HTTPClient::Session#parse_header	httpclient/session.rb	/^    def parse_header/
 | 
			
		||||
::HTTPClient::Session#parse_keepalive_header	httpclient/session.rb	/^    def parse_keepalive_header/
 | 
			
		||||
::HTTPClient::Session#protocol_retry_count	httpclient/session.rb	/^    attr_accessor :protocol_retry_count/
 | 
			
		||||
::HTTPClient::Session#proxy	httpclient/session.rb	/^    attr_accessor :proxy/
 | 
			
		||||
::HTTPClient::Session#query	httpclient/session.rb	/^    def query/
 | 
			
		||||
::HTTPClient::Session#read_block_size	httpclient/session.rb	/^    attr_accessor :read_block_size/
 | 
			
		||||
::HTTPClient::Session#read_body_chunked	httpclient/session.rb	/^    def read_body_chunked/
 | 
			
		||||
::HTTPClient::Session#read_body_length	httpclient/session.rb	/^    def read_body_length/
 | 
			
		||||
::HTTPClient::Session#read_body_rest	httpclient/session.rb	/^    def read_body_rest/
 | 
			
		||||
::HTTPClient::Session#read_header	httpclient/session.rb	/^    def read_header/
 | 
			
		||||
::HTTPClient::Session#receive_timeout	httpclient/session.rb	/^    attr_accessor :receive_timeout/
 | 
			
		||||
::HTTPClient::Session#requested_version	httpclient/session.rb	/^    attr_accessor :requested_version/
 | 
			
		||||
::HTTPClient::Session#send_timeout	httpclient/session.rb	/^    attr_accessor :send_timeout/
 | 
			
		||||
::HTTPClient::Session#set_header	httpclient/session.rb	/^    def set_header/
 | 
			
		||||
::HTTPClient::Session#socket_sync	httpclient/session.rb	/^    attr_accessor :socket_sync/
 | 
			
		||||
::HTTPClient::Session#ssl_config	httpclient/session.rb	/^    attr_accessor :ssl_config/
 | 
			
		||||
::HTTPClient::Session#ssl_peer_cert	httpclient/session.rb	/^    attr_reader :ssl_peer_cert/
 | 
			
		||||
::HTTPClient::Session#test_loopback_http_response	httpclient/session.rb	/^    attr_accessor :test_loopback_http_response/
 | 
			
		||||
::HTTPClient::SessionManager	httpclient/session.rb	/^  class SessionManager/
 | 
			
		||||
::HTTPClient::SessionManager#HTTPClient::SessionManager.new	httpclient/session.rb	/^    def initialize/
 | 
			
		||||
::HTTPClient::SessionManager#add_cached_session	httpclient/session.rb	/^    def add_cached_session/
 | 
			
		||||
::HTTPClient::SessionManager#agent_name	httpclient/session.rb	/^    attr_accessor :agent_name/
 | 
			
		||||
::HTTPClient::SessionManager#chunk_size	httpclient/session.rb	/^    attr_accessor :chunk_size/
 | 
			
		||||
::HTTPClient::SessionManager#close	httpclient/session.rb	/^    def close/
 | 
			
		||||
::HTTPClient::SessionManager#close_all	httpclient/session.rb	/^    def close_all/
 | 
			
		||||
::HTTPClient::SessionManager#connect_retry	httpclient/session.rb	/^    attr_accessor :connect_retry/
 | 
			
		||||
::HTTPClient::SessionManager#connect_timeout	httpclient/session.rb	/^    attr_accessor :connect_timeout/
 | 
			
		||||
::HTTPClient::SessionManager#debug_dev	httpclient/session.rb	/^    attr_accessor :debug_dev/
 | 
			
		||||
::HTTPClient::SessionManager#from	httpclient/session.rb	/^    attr_accessor :from/
 | 
			
		||||
::HTTPClient::SessionManager#get_cached_session	httpclient/session.rb	/^    def get_cached_session/
 | 
			
		||||
::HTTPClient::SessionManager#keep	httpclient/session.rb	/^    def keep/
 | 
			
		||||
::HTTPClient::SessionManager#open	httpclient/session.rb	/^    def open/
 | 
			
		||||
::HTTPClient::SessionManager#protocol_retry_count	httpclient/session.rb	/^    attr_accessor :protocol_retry_count/
 | 
			
		||||
::HTTPClient::SessionManager#protocol_version	httpclient/session.rb	/^    attr_accessor :protocol_version/
 | 
			
		||||
::HTTPClient::SessionManager#proxy=	httpclient/session.rb	/^    def proxy=/
 | 
			
		||||
::HTTPClient::SessionManager#query	httpclient/session.rb	/^    def query/
 | 
			
		||||
::HTTPClient::SessionManager#read_block_size	httpclient/session.rb	/^    attr_accessor :read_block_size/
 | 
			
		||||
::HTTPClient::SessionManager#receive_timeout	httpclient/session.rb	/^    attr_accessor :receive_timeout/
 | 
			
		||||
::HTTPClient::SessionManager#reset	httpclient/session.rb	/^    def reset/
 | 
			
		||||
::HTTPClient::SessionManager#reset_all	httpclient/session.rb	/^    def reset_all/
 | 
			
		||||
::HTTPClient::SessionManager#send_timeout	httpclient/session.rb	/^    attr_accessor :send_timeout/
 | 
			
		||||
::HTTPClient::SessionManager#socket_sync	httpclient/session.rb	/^    attr_accessor :socket_sync/
 | 
			
		||||
::HTTPClient::SessionManager#ssl_config	httpclient/session.rb	/^    attr_accessor :ssl_config/
 | 
			
		||||
::HTTPClient::SessionManager#test_loopback_http_response	httpclient/session.rb	/^    attr_reader :test_loopback_http_response/
 | 
			
		||||
::HTTPClient::Site	httpclient/session.rb	/^  class Site/
 | 
			
		||||
::HTTPClient::Site#==	httpclient/session.rb	/^    def ==/
 | 
			
		||||
::HTTPClient::Site#HTTPClient::Site.new	httpclient/session.rb	/^    def initialize/
 | 
			
		||||
::HTTPClient::Site#addr	httpclient/session.rb	/^    def addr/
 | 
			
		||||
::HTTPClient::Site#eql?	httpclient/session.rb	/^    def eql?/
 | 
			
		||||
::HTTPClient::Site#hash	httpclient/session.rb	/^    def hash/
 | 
			
		||||
::HTTPClient::Site#host	httpclient/session.rb	/^    attr_reader :host/
 | 
			
		||||
::HTTPClient::Site#inspect	httpclient/session.rb	/^    def inspect/
 | 
			
		||||
::HTTPClient::Site#match	httpclient/session.rb	/^    def match/
 | 
			
		||||
::HTTPClient::Site#port	httpclient/session.rb	/^    attr_reader :port/
 | 
			
		||||
::HTTPClient::Site#scheme	httpclient/session.rb	/^    attr_accessor :scheme/
 | 
			
		||||
::HTTPClient::Site#to_s	httpclient/session.rb	/^    def to_s/
 | 
			
		||||
::HTTPClient::SocketWrap	httpclient/session.rb	/^  module SocketWrap/
 | 
			
		||||
::HTTPClient::SocketWrap#<<	httpclient/session.rb	/^    def <</
 | 
			
		||||
::HTTPClient::SocketWrap#HTTPClient::SocketWrap.new	httpclient/session.rb	/^    def initialize/
 | 
			
		||||
::HTTPClient::SocketWrap#close	httpclient/session.rb	/^    def close/
 | 
			
		||||
::HTTPClient::SocketWrap#closed?	httpclient/session.rb	/^    def closed?/
 | 
			
		||||
::HTTPClient::SocketWrap#eof?	httpclient/session.rb	/^    def eof?/
 | 
			
		||||
::HTTPClient::SocketWrap#flush	httpclient/session.rb	/^    def flush/
 | 
			
		||||
::HTTPClient::SocketWrap#gets	httpclient/session.rb	/^    def gets/
 | 
			
		||||
::HTTPClient::SocketWrap#read	httpclient/session.rb	/^    def read/
 | 
			
		||||
::HTTPClient::SocketWrap#readpartial	httpclient/session.rb	/^    def readpartial/
 | 
			
		||||
::HTTPClient::SocketWrap#sync	httpclient/session.rb	/^    def sync/
 | 
			
		||||
::HTTPClient::SocketWrap#sync=	httpclient/session.rb	/^    def sync=/
 | 
			
		||||
::HTTPClient::Timeout	httpclient/timeout.rb	/^  module Timeout/
 | 
			
		||||
::HTTPClient::Timeout#timeout	httpclient/timeout.rb	/^    def timeout/
 | 
			
		||||
::HTTPClient::TimeoutError	httpclient.rb	/^  class TimeoutError/
 | 
			
		||||
::HTTPClient::TimeoutScheduler	httpclient/timeout.rb	/^  class TimeoutScheduler/
 | 
			
		||||
::HTTPClient::TimeoutScheduler#HTTPClient::TimeoutScheduler.new	httpclient/timeout.rb	/^    def initialize/
 | 
			
		||||
::HTTPClient::TimeoutScheduler#cancel	httpclient/timeout.rb	/^    def cancel/
 | 
			
		||||
::HTTPClient::TimeoutScheduler#register	httpclient/timeout.rb	/^    def register/
 | 
			
		||||
::HTTPClient::TimeoutScheduler#start_timer_thread	httpclient/timeout.rb	/^    def start_timer_thread/
 | 
			
		||||
::HTTPClient::TimeoutScheduler::Period	httpclient/timeout.rb	/^    class Period/
 | 
			
		||||
::HTTPClient::TimeoutScheduler::Period#HTTPClient::TimeoutScheduler::Period.new	httpclient/timeout.rb	/^      def initialize/
 | 
			
		||||
::HTTPClient::TimeoutScheduler::Period#cancel	httpclient/timeout.rb	/^      def cancel/
 | 
			
		||||
::HTTPClient::TimeoutScheduler::Period#raise	httpclient/timeout.rb	/^      def raise/
 | 
			
		||||
::HTTPClient::TimeoutScheduler::Period#thread	httpclient/timeout.rb	/^      attr_reader :thread, :time/
 | 
			
		||||
::HTTPClient::TimeoutScheduler::Period#time	httpclient/timeout.rb	/^      attr_reader :thread, :time/
 | 
			
		||||
::HTTPClient::Util	httpclient/util.rb	/^  module Util/
 | 
			
		||||
::HTTPClient::Util#hash_find_value	httpclient/util.rb	/^    def hash_find_value/
 | 
			
		||||
::HTTPClient::Util#keyword_argument	httpclient/util.rb	/^    def keyword_argument/
 | 
			
		||||
::HTTPClient::Util#uri_dirname	httpclient/util.rb	/^    def uri_dirname/
 | 
			
		||||
::HTTPClient::Util#uri_part_of	httpclient/util.rb	/^    def uri_part_of/
 | 
			
		||||
::HTTPClient::Util#urify	httpclient/util.rb	/^    def urify/
 | 
			
		||||
::HTTPClient::WWWAuth	httpclient/auth.rb	/^  class WWWAuth/
 | 
			
		||||
::HTTPClient::WWWAuth#HTTPClient::WWWAuth.new	httpclient/auth.rb	/^    def initialize/
 | 
			
		||||
::HTTPClient::WWWAuth#basic_auth	httpclient/auth.rb	/^    attr_reader :basic_auth/
 | 
			
		||||
::HTTPClient::WWWAuth#digest_auth	httpclient/auth.rb	/^    attr_reader :digest_auth/
 | 
			
		||||
::HTTPClient::WWWAuth#filter_request	httpclient/auth.rb	/^    def filter_request/
 | 
			
		||||
::HTTPClient::WWWAuth#filter_response	httpclient/auth.rb	/^    def filter_response/
 | 
			
		||||
::HTTPClient::WWWAuth#negotiate_auth	httpclient/auth.rb	/^    attr_reader :negotiate_auth/
 | 
			
		||||
::HTTPClient::WWWAuth#reset_challenge	httpclient/auth.rb	/^    def reset_challenge/
 | 
			
		||||
::HTTPClient::WWWAuth#set_auth	httpclient/auth.rb	/^    def set_auth/
 | 
			
		||||
::WebAgent	httpclient/cookie.rb	/^class WebAgent/
 | 
			
		||||
::WebAgent::Cookie	httpclient/cookie.rb	/^  class Cookie/
 | 
			
		||||
::WebAgent::Cookie#WebAgent::Cookie.new	httpclient/cookie.rb	/^    def initialize/
 | 
			
		||||
::WebAgent::Cookie#discard	httpclient/cookie.rb	/^    attr_writer :use, :secure, :discard, :domain_orig, :path_orig, :override/
 | 
			
		||||
::WebAgent::Cookie#discard?	httpclient/cookie.rb	/^    def discard?/
 | 
			
		||||
::WebAgent::Cookie#domain	httpclient/cookie.rb	/^    attr_accessor :domain, :path/
 | 
			
		||||
::WebAgent::Cookie#domain_orig	httpclient/cookie.rb	/^    attr_writer :use, :secure, :discard, :domain_orig, :path_orig, :override/
 | 
			
		||||
::WebAgent::Cookie#domain_orig?	httpclient/cookie.rb	/^    def domain_orig?/
 | 
			
		||||
::WebAgent::Cookie#expires	httpclient/cookie.rb	/^    attr_accessor :expires      ## for Netscape Cookie/
 | 
			
		||||
::WebAgent::Cookie#flag	httpclient/cookie.rb	/^    def flag/
 | 
			
		||||
::WebAgent::Cookie#join_quotedstr	httpclient/cookie.rb	/^    def join_quotedstr/
 | 
			
		||||
::WebAgent::Cookie#match?	httpclient/cookie.rb	/^    def match?/
 | 
			
		||||
::WebAgent::Cookie#name	httpclient/cookie.rb	/^    attr_accessor :name, :value/
 | 
			
		||||
::WebAgent::Cookie#normalize_cookie_value	httpclient/cookie.rb	/^    def normalize_cookie_value/
 | 
			
		||||
::WebAgent::Cookie#override	httpclient/cookie.rb	/^    attr_writer :use, :secure, :discard, :domain_orig, :path_orig, :override/
 | 
			
		||||
::WebAgent::Cookie#override?	httpclient/cookie.rb	/^    def override?/
 | 
			
		||||
::WebAgent::Cookie#parse	httpclient/cookie.rb	/^    def parse/
 | 
			
		||||
::WebAgent::Cookie#path	httpclient/cookie.rb	/^    attr_accessor :domain, :path/
 | 
			
		||||
::WebAgent::Cookie#path_orig	httpclient/cookie.rb	/^    attr_writer :use, :secure, :discard, :domain_orig, :path_orig, :override/
 | 
			
		||||
::WebAgent::Cookie#path_orig?	httpclient/cookie.rb	/^    def path_orig?/
 | 
			
		||||
::WebAgent::Cookie#secure	httpclient/cookie.rb	/^    attr_writer :use, :secure, :discard, :domain_orig, :path_orig, :override/
 | 
			
		||||
::WebAgent::Cookie#secure?	httpclient/cookie.rb	/^    def secure?/
 | 
			
		||||
::WebAgent::Cookie#set_flag	httpclient/cookie.rb	/^    def set_flag/
 | 
			
		||||
::WebAgent::Cookie#url	httpclient/cookie.rb	/^    attr_accessor :url/
 | 
			
		||||
::WebAgent::Cookie#use	httpclient/cookie.rb	/^    attr_writer :use, :secure, :discard, :domain_orig, :path_orig, :override/
 | 
			
		||||
::WebAgent::Cookie#use?	httpclient/cookie.rb	/^    def use?/
 | 
			
		||||
::WebAgent::Cookie#value	httpclient/cookie.rb	/^    attr_accessor :name, :value/
 | 
			
		||||
::WebAgent::CookieManager	httpclient/cookie.rb	/^  class CookieManager/
 | 
			
		||||
::WebAgent::CookieManager#WebAgent::CookieManager.new	httpclient/cookie.rb	/^    def initialize/
 | 
			
		||||
::WebAgent::CookieManager#accept_domains	httpclient/cookie.rb	/^    attr_accessor :accept_domains, :reject_domains/
 | 
			
		||||
::WebAgent::CookieManager#add	httpclient/cookie.rb	/^    def add/
 | 
			
		||||
::WebAgent::CookieManager#check_cookie_accept_domain	httpclient/cookie.rb	/^    def check_cookie_accept_domain/
 | 
			
		||||
::WebAgent::CookieManager#check_expired_cookies	httpclient/cookie.rb	/^    def check_expired_cookies/
 | 
			
		||||
::WebAgent::CookieManager#cookie_error	httpclient/cookie.rb	/^    def cookie_error/
 | 
			
		||||
::WebAgent::CookieManager#cookies	httpclient/cookie.rb	/^    attr_reader :cookies/
 | 
			
		||||
::WebAgent::CookieManager#cookies=	httpclient/cookie.rb	/^    def cookies=/
 | 
			
		||||
::WebAgent::CookieManager#cookies_file	httpclient/cookie.rb	/^    attr_accessor :cookies_file/
 | 
			
		||||
::WebAgent::CookieManager#find	httpclient/cookie.rb	/^    def find/
 | 
			
		||||
::WebAgent::CookieManager#find_cookie_info	httpclient/cookie.rb	/^    def find_cookie_info/
 | 
			
		||||
::WebAgent::CookieManager#load_cookies	httpclient/cookie.rb	/^    def load_cookies/
 | 
			
		||||
::WebAgent::CookieManager#make_cookie_str	httpclient/cookie.rb	/^    def make_cookie_str/
 | 
			
		||||
::WebAgent::CookieManager#netscape_rule	httpclient/cookie.rb	/^    attr_accessor :netscape_rule/
 | 
			
		||||
::WebAgent::CookieManager#parse	httpclient/cookie.rb	/^    def parse/
 | 
			
		||||
::WebAgent::CookieManager#reject_domains	httpclient/cookie.rb	/^    attr_accessor :accept_domains, :reject_domains/
 | 
			
		||||
::WebAgent::CookieManager#save_all_cookies	httpclient/cookie.rb	/^    def save_all_cookies/
 | 
			
		||||
::WebAgent::CookieManager#save_cookies	httpclient/cookie.rb	/^    def save_cookies/
 | 
			
		||||
::WebAgent::CookieManager::Error	httpclient/cookie.rb	/^    class Error/
 | 
			
		||||
::WebAgent::CookieManager::ErrorOverrideOK	httpclient/cookie.rb	/^    class ErrorOverrideOK/
 | 
			
		||||
::WebAgent::CookieManager::SpecialError	httpclient/cookie.rb	/^    class SpecialError/
 | 
			
		||||
::WebAgent::CookieUtils	httpclient/cookie.rb	/^  module CookieUtils/
 | 
			
		||||
::WebAgent::CookieUtils#domain_match	httpclient/cookie.rb	/^    def domain_match/
 | 
			
		||||
::WebAgent::CookieUtils#head_match?	httpclient/cookie.rb	/^    def head_match?/
 | 
			
		||||
::WebAgent::CookieUtils#tail_match?	httpclient/cookie.rb	/^    def tail_match?/
 | 
			
		||||
::WebAgent::CookieUtils#total_dot_num	httpclient/cookie.rb	/^    def total_dot_num/
 | 
			
		||||
<<	httpclient/session.rb	/^    def <</
 | 
			
		||||
<<	httpclient/session.rb	/^    def <</
 | 
			
		||||
<<	httpclient/session.rb	/^    def <</
 | 
			
		||||
<<	httpclient/session.rb	/^    def <</
 | 
			
		||||
==	httpclient/session.rb	/^    def ==/
 | 
			
		||||
AuthFilterBase	httpclient/auth.rb	/^  class AuthFilterBase/
 | 
			
		||||
BadResponseError	httpclient.rb	/^  class BadResponseError/
 | 
			
		||||
BasicAuth	httpclient/auth.rb	/^  class BasicAuth/
 | 
			
		||||
Body	httpclient/http.rb	/^    class Body/
 | 
			
		||||
ConfigurationError	httpclient.rb	/^  class ConfigurationError/
 | 
			
		||||
ConnectTimeoutError	httpclient.rb	/^  class ConnectTimeoutError/
 | 
			
		||||
Connection	httpclient/connection.rb	/^  class Connection/
 | 
			
		||||
Cookie	httpclient/cookie.rb	/^  class Cookie/
 | 
			
		||||
CookieManager	httpclient/cookie.rb	/^  class CookieManager/
 | 
			
		||||
CookieUtils	httpclient/cookie.rb	/^  module CookieUtils/
 | 
			
		||||
DebugSocket	httpclient/session.rb	/^  module DebugSocket/
 | 
			
		||||
DigestAuth	httpclient/auth.rb	/^  class DigestAuth/
 | 
			
		||||
Error	httpclient/cookie.rb	/^    class Error/
 | 
			
		||||
ErrorOverrideOK	httpclient/cookie.rb	/^    class ErrorOverrideOK/
 | 
			
		||||
HTTP	httpclient/http.rb	/^module HTTP/
 | 
			
		||||
HTTP::Message.new	httpclient/http.rb	/^    def initialize/
 | 
			
		||||
HTTP::Message::Body.new	httpclient/http.rb	/^      def initialize/
 | 
			
		||||
HTTP::Message::Body::Parts.new	httpclient/http.rb	/^        def initialize/
 | 
			
		||||
HTTP::Message::Headers.new	httpclient/http.rb	/^      def initialize/
 | 
			
		||||
HTTPClient	httpclient.rb	/^class HTTPClient/
 | 
			
		||||
HTTPClient	httpclient/auth.rb	/^class HTTPClient/
 | 
			
		||||
HTTPClient	httpclient/connection.rb	/^class HTTPClient/
 | 
			
		||||
HTTPClient	httpclient/session.rb	/^class HTTPClient/
 | 
			
		||||
HTTPClient	httpclient/ssl_config.rb	/^class HTTPClient/
 | 
			
		||||
HTTPClient	httpclient/timeout.rb	/^class HTTPClient/
 | 
			
		||||
HTTPClient	httpclient/util.rb	/^class HTTPClient/
 | 
			
		||||
HTTPClient.new	httpclient.rb	/^  def initialize/
 | 
			
		||||
HTTPClient::BadResponseError.new	httpclient.rb	/^    def initialize/
 | 
			
		||||
HTTPClient::BasicAuth.new	httpclient/auth.rb	/^    def initialize/
 | 
			
		||||
HTTPClient::Connection.new	httpclient/connection.rb	/^    def initialize/
 | 
			
		||||
HTTPClient::DigestAuth.new	httpclient/auth.rb	/^    def initialize/
 | 
			
		||||
HTTPClient::LoopBackSocket.new	httpclient/session.rb	/^    def initialize/
 | 
			
		||||
HTTPClient::NegotiateAuth.new	httpclient/auth.rb	/^    def initialize/
 | 
			
		||||
HTTPClient::ProxyAuth.new	httpclient/auth.rb	/^    def initialize/
 | 
			
		||||
HTTPClient::SSLConfig.new	httpclient/ssl_config.rb	/^    def initialize/
 | 
			
		||||
HTTPClient::SSLSocketWrap.new	httpclient/session.rb	/^    def initialize/
 | 
			
		||||
HTTPClient::SSPINegotiateAuth.new	httpclient/auth.rb	/^    def initialize/
 | 
			
		||||
HTTPClient::Session.new	httpclient/session.rb	/^    def initialize/
 | 
			
		||||
HTTPClient::SessionManager.new	httpclient/session.rb	/^    def initialize/
 | 
			
		||||
HTTPClient::Site.new	httpclient/session.rb	/^    def initialize/
 | 
			
		||||
HTTPClient::SocketWrap.new	httpclient/session.rb	/^    def initialize/
 | 
			
		||||
HTTPClient::TimeoutScheduler.new	httpclient/timeout.rb	/^    def initialize/
 | 
			
		||||
HTTPClient::TimeoutScheduler::Period.new	httpclient/timeout.rb	/^      def initialize/
 | 
			
		||||
HTTPClient::WWWAuth.new	httpclient/auth.rb	/^    def initialize/
 | 
			
		||||
Headers	httpclient/http.rb	/^    class Headers/
 | 
			
		||||
KeepAliveDisconnected	httpclient.rb	/^  class KeepAliveDisconnected/
 | 
			
		||||
LoopBackSocket	httpclient/session.rb	/^  class LoopBackSocket/
 | 
			
		||||
Message	httpclient/http.rb	/^  class Message/
 | 
			
		||||
NegotiateAuth	httpclient/auth.rb	/^  class NegotiateAuth/
 | 
			
		||||
Parts	httpclient/http.rb	/^      class Parts/
 | 
			
		||||
Period	httpclient/timeout.rb	/^    class Period/
 | 
			
		||||
ProxyAuth	httpclient/auth.rb	/^  class ProxyAuth/
 | 
			
		||||
ReceiveTimeoutError	httpclient.rb	/^  class ReceiveTimeoutError/
 | 
			
		||||
RetryableResponse	httpclient.rb	/^  class RetryableResponse/
 | 
			
		||||
SSLConfig	httpclient/ssl_config.rb	/^  class SSLConfig/
 | 
			
		||||
SSLSocketWrap	httpclient/session.rb	/^  class SSLSocketWrap/
 | 
			
		||||
SSPINegotiateAuth	httpclient/auth.rb	/^  class SSPINegotiateAuth/
 | 
			
		||||
SendTimeoutError	httpclient.rb	/^  class SendTimeoutError/
 | 
			
		||||
Session	httpclient.rb	/^  class Session/
 | 
			
		||||
Session	httpclient/session.rb	/^  class Session/
 | 
			
		||||
SessionManager	httpclient/session.rb	/^  class SessionManager/
 | 
			
		||||
Site	httpclient/session.rb	/^  class Site/
 | 
			
		||||
SocketWrap	httpclient/session.rb	/^  module SocketWrap/
 | 
			
		||||
SpecialError	httpclient/cookie.rb	/^    class SpecialError/
 | 
			
		||||
Status	httpclient/http.rb	/^  module Status/
 | 
			
		||||
Timeout	httpclient/timeout.rb	/^  module Timeout/
 | 
			
		||||
TimeoutError	httpclient.rb	/^  class TimeoutError/
 | 
			
		||||
TimeoutScheduler	httpclient/timeout.rb	/^  class TimeoutScheduler/
 | 
			
		||||
Util	httpclient/util.rb	/^  module Util/
 | 
			
		||||
WWWAuth	httpclient/auth.rb	/^  class WWWAuth/
 | 
			
		||||
WebAgent	httpclient/cookie.rb	/^class WebAgent/
 | 
			
		||||
WebAgent::Cookie.new	httpclient/cookie.rb	/^    def initialize/
 | 
			
		||||
WebAgent::CookieManager.new	httpclient/cookie.rb	/^    def initialize/
 | 
			
		||||
[]	httpclient/http.rb	/^      def []/
 | 
			
		||||
[]=	httpclient/http.rb	/^      def []=/
 | 
			
		||||
accept_domains	httpclient/cookie.rb	/^    attr_accessor :accept_domains, :reject_domains/
 | 
			
		||||
add	httpclient/cookie.rb	/^    def add/
 | 
			
		||||
add	httpclient/http.rb	/^        def add/
 | 
			
		||||
add	httpclient/http.rb	/^      def add/
 | 
			
		||||
add_cached_session	httpclient/session.rb	/^    def add_cached_session/
 | 
			
		||||
addr	httpclient/session.rb	/^    def addr/
 | 
			
		||||
agent_name	httpclient/session.rb	/^    attr_accessor :agent_name/
 | 
			
		||||
all	httpclient/http.rb	/^      def all/
 | 
			
		||||
async_thread	httpclient/connection.rb	/^    attr_accessor :async_thread/
 | 
			
		||||
attr_proxy	httpclient.rb	/^    def attr_proxy/
 | 
			
		||||
basic_auth	httpclient/auth.rb	/^    attr_reader :basic_auth/
 | 
			
		||||
basic_auth	httpclient/auth.rb	/^    attr_reader :basic_auth/
 | 
			
		||||
body	httpclient/http.rb	/^    attr_reader :body/
 | 
			
		||||
body=	httpclient/http.rb	/^    def body=/
 | 
			
		||||
body_charset	httpclient/http.rb	/^      attr_accessor :body_charset # :nodoc:/
 | 
			
		||||
body_date	httpclient/http.rb	/^      attr_accessor :body_date # :nodoc:/
 | 
			
		||||
body_size	httpclient/http.rb	/^      attr_reader :body_size/
 | 
			
		||||
body_size=	httpclient/http.rb	/^      def body_size=/
 | 
			
		||||
body_type	httpclient/http.rb	/^      attr_accessor :body_type # :nodoc:/
 | 
			
		||||
build_query_multipart_str	httpclient/http.rb	/^      def build_query_multipart_str/
 | 
			
		||||
calc_cred	httpclient/auth.rb	/^    def calc_cred/
 | 
			
		||||
cancel	httpclient/timeout.rb	/^      def cancel/
 | 
			
		||||
cancel	httpclient/timeout.rb	/^    def cancel/
 | 
			
		||||
cert_store	httpclient/ssl_config.rb	/^    attr_reader :cert_store # don't use if you don't know what it is./
 | 
			
		||||
cert_store=	httpclient/ssl_config.rb	/^    def cert_store=/
 | 
			
		||||
challenge	httpclient/auth.rb	/^    def challenge/
 | 
			
		||||
challenge	httpclient/auth.rb	/^    def challenge/
 | 
			
		||||
challenge	httpclient/auth.rb	/^    def challenge/
 | 
			
		||||
challenge	httpclient/auth.rb	/^    def challenge/
 | 
			
		||||
change_notify	httpclient/ssl_config.rb	/^    def change_notify/
 | 
			
		||||
charset_label	httpclient/http.rb	/^      def charset_label/
 | 
			
		||||
check_cookie_accept_domain	httpclient/cookie.rb	/^    def check_cookie_accept_domain/
 | 
			
		||||
check_expired_cookies	httpclient/cookie.rb	/^    def check_expired_cookies/
 | 
			
		||||
check_mask	httpclient/session.rb	/^    def check_mask/
 | 
			
		||||
chunk_size	httpclient/http.rb	/^      attr_accessor :chunk_size/
 | 
			
		||||
chunk_size	httpclient/session.rb	/^    attr_accessor :chunk_size/
 | 
			
		||||
chunked	httpclient/http.rb	/^      attr_accessor :chunked/
 | 
			
		||||
ciphers	httpclient/ssl_config.rb	/^    attr_reader :ciphers/
 | 
			
		||||
ciphers=	httpclient/ssl_config.rb	/^    def ciphers=/
 | 
			
		||||
clear_cert_store	httpclient/ssl_config.rb	/^    def clear_cert_store/
 | 
			
		||||
client_ca	httpclient/ssl_config.rb	/^    attr_reader :client_ca # :nodoc:/
 | 
			
		||||
client_ca=	httpclient/ssl_config.rb	/^    def client_ca=/
 | 
			
		||||
client_cert	httpclient/ssl_config.rb	/^    attr_reader :client_cert/
 | 
			
		||||
client_cert=	httpclient/ssl_config.rb	/^    def client_cert=/
 | 
			
		||||
client_key	httpclient/ssl_config.rb	/^    attr_reader :client_key/
 | 
			
		||||
client_key=	httpclient/ssl_config.rb	/^    def client_key=/
 | 
			
		||||
close	httpclient/session.rb	/^    def close/
 | 
			
		||||
close	httpclient/session.rb	/^    def close/
 | 
			
		||||
close	httpclient/session.rb	/^    def close/
 | 
			
		||||
close	httpclient/session.rb	/^    def close/
 | 
			
		||||
close	httpclient/session.rb	/^    def close/
 | 
			
		||||
close_all	httpclient/session.rb	/^    def close_all/
 | 
			
		||||
closed?	httpclient/session.rb	/^    def closed?/
 | 
			
		||||
closed?	httpclient/session.rb	/^    def closed?/
 | 
			
		||||
closed?	httpclient/session.rb	/^    def closed?/
 | 
			
		||||
code	httpclient/http.rb	/^    alias code/
 | 
			
		||||
connect	httpclient/session.rb	/^    def connect/
 | 
			
		||||
connect_retry	httpclient/session.rb	/^    attr_accessor :connect_retry/
 | 
			
		||||
connect_retry	httpclient/session.rb	/^    attr_accessor :connect_retry/
 | 
			
		||||
connect_ssl_proxy	httpclient/session.rb	/^    def connect_ssl_proxy/
 | 
			
		||||
connect_timeout	httpclient/session.rb	/^    attr_accessor :connect_timeout/
 | 
			
		||||
connect_timeout	httpclient/session.rb	/^    attr_accessor :connect_timeout/
 | 
			
		||||
content	httpclient/http.rb	/^      def content/
 | 
			
		||||
content	httpclient/http.rb	/^    def content/
 | 
			
		||||
contenttype	httpclient/http.rb	/^      def contenttype/
 | 
			
		||||
contenttype	httpclient/http.rb	/^    def contenttype/
 | 
			
		||||
contenttype=	httpclient/http.rb	/^      def contenttype=/
 | 
			
		||||
contenttype=	httpclient/http.rb	/^    def contenttype=/
 | 
			
		||||
cookie_error	httpclient/cookie.rb	/^    def cookie_error/
 | 
			
		||||
cookie_manager	httpclient.rb	/^  attr_accessor :cookie_manager/
 | 
			
		||||
cookies	httpclient/cookie.rb	/^    attr_reader :cookies/
 | 
			
		||||
cookies=	httpclient/cookie.rb	/^    def cookies=/
 | 
			
		||||
cookies_file	httpclient/cookie.rb	/^    attr_accessor :cookies_file/
 | 
			
		||||
create_boundary	httpclient.rb	/^  def create_boundary/
 | 
			
		||||
create_openssl_socket	httpclient/session.rb	/^    def create_openssl_socket/
 | 
			
		||||
create_query_part_str	httpclient/http.rb	/^      def create_query_part_str/
 | 
			
		||||
create_query_uri	httpclient/http.rb	/^      def create_query_uri/
 | 
			
		||||
create_request	httpclient.rb	/^  def create_request/
 | 
			
		||||
create_socket	httpclient/session.rb	/^    def create_socket/
 | 
			
		||||
create_ssl_socket	httpclient/session.rb	/^    def create_ssl_socket/
 | 
			
		||||
debug	httpclient/session.rb	/^    def debug/
 | 
			
		||||
debug	httpclient/session.rb	/^    def debug/
 | 
			
		||||
debug_dev	httpclient.rb	/^  def debug_dev/
 | 
			
		||||
debug_dev	httpclient/session.rb	/^    attr_accessor :debug_dev/
 | 
			
		||||
debug_dev	httpclient/session.rb	/^    attr_accessor :debug_dev/
 | 
			
		||||
debug_dev=	httpclient.rb	/^  def debug_dev=/
 | 
			
		||||
debug_dev=	httpclient/session.rb	/^    def debug_dev=/
 | 
			
		||||
default_redirect_uri_callback	httpclient.rb	/^  def default_redirect_uri_callback/
 | 
			
		||||
default_verify_callback	httpclient/ssl_config.rb	/^    def default_verify_callback/
 | 
			
		||||
delete	httpclient.rb	/^  def delete/
 | 
			
		||||
delete	httpclient/http.rb	/^      def delete/
 | 
			
		||||
delete_async	httpclient.rb	/^  def delete_async/
 | 
			
		||||
dest	httpclient/session.rb	/^    attr_reader :dest/
 | 
			
		||||
digest_auth	httpclient/auth.rb	/^    attr_reader :digest_auth/
 | 
			
		||||
discard	httpclient/cookie.rb	/^    attr_writer :use, :secure, :discard, :domain_orig, :path_orig, :override/
 | 
			
		||||
discard?	httpclient/cookie.rb	/^    def discard?/
 | 
			
		||||
do_get_block	httpclient.rb	/^  def do_get_block/
 | 
			
		||||
do_get_header	httpclient.rb	/^  def do_get_header/
 | 
			
		||||
do_get_stream	httpclient.rb	/^  def do_get_stream/
 | 
			
		||||
do_request	httpclient.rb	/^  def do_request/
 | 
			
		||||
do_request_async	httpclient.rb	/^  def do_request_async/
 | 
			
		||||
domain	httpclient/cookie.rb	/^    attr_accessor :domain, :path/
 | 
			
		||||
domain_match	httpclient/cookie.rb	/^    def domain_match/
 | 
			
		||||
domain_orig	httpclient/cookie.rb	/^    attr_writer :use, :secure, :discard, :domain_orig, :path_orig, :override/
 | 
			
		||||
domain_orig?	httpclient/cookie.rb	/^    def domain_orig?/
 | 
			
		||||
dump	httpclient/http.rb	/^      def dump/
 | 
			
		||||
dump	httpclient/http.rb	/^      def dump/
 | 
			
		||||
dump	httpclient/http.rb	/^    def dump/
 | 
			
		||||
dump_chunk	httpclient/http.rb	/^      def dump_chunk/
 | 
			
		||||
dump_chunk_size	httpclient/http.rb	/^      def dump_chunk_size/
 | 
			
		||||
dump_chunked	httpclient/http.rb	/^      def dump_chunked/
 | 
			
		||||
dump_chunks	httpclient/http.rb	/^      def dump_chunks/
 | 
			
		||||
dump_dummy_request_response	httpclient.rb	/^  def dump_dummy_request_response/
 | 
			
		||||
dump_last_chunk	httpclient/http.rb	/^      def dump_last_chunk/
 | 
			
		||||
eof?	httpclient/session.rb	/^    def eof?/
 | 
			
		||||
eof?	httpclient/session.rb	/^    def eof?/
 | 
			
		||||
eof?	httpclient/session.rb	/^    def eof?/
 | 
			
		||||
eql?	httpclient/session.rb	/^    def eql?/
 | 
			
		||||
escape	httpclient/http.rb	/^      def escape/
 | 
			
		||||
escape_query	httpclient/http.rb	/^      def escape_query/
 | 
			
		||||
expires	httpclient/cookie.rb	/^    attr_accessor :expires      ## for Netscape Cookie/
 | 
			
		||||
file?	httpclient/http.rb	/^      def file?/
 | 
			
		||||
file_in_form_data?	httpclient.rb	/^  def file_in_form_data?/
 | 
			
		||||
filter_request	httpclient/auth.rb	/^    def filter_request/
 | 
			
		||||
filter_request	httpclient/auth.rb	/^    def filter_request/
 | 
			
		||||
filter_response	httpclient/auth.rb	/^    def filter_response/
 | 
			
		||||
filter_response	httpclient/auth.rb	/^    def filter_response/
 | 
			
		||||
find	httpclient/cookie.rb	/^    def find/
 | 
			
		||||
find_cookie_info	httpclient/cookie.rb	/^    def find_cookie_info/
 | 
			
		||||
finished?	httpclient/connection.rb	/^    def finished?/
 | 
			
		||||
flag	httpclient/cookie.rb	/^    def flag/
 | 
			
		||||
flush	httpclient/session.rb	/^    def flush/
 | 
			
		||||
flush	httpclient/session.rb	/^    def flush/
 | 
			
		||||
follow_redirect	httpclient.rb	/^  def follow_redirect/
 | 
			
		||||
follow_redirect_count	httpclient.rb	/^  attr_accessor :follow_redirect_count/
 | 
			
		||||
from	httpclient/session.rb	/^    attr_accessor :from/
 | 
			
		||||
get	httpclient.rb	/^  def get/
 | 
			
		||||
get	httpclient/auth.rb	/^    def get/
 | 
			
		||||
get	httpclient/auth.rb	/^    def get/
 | 
			
		||||
get	httpclient/auth.rb	/^    def get/
 | 
			
		||||
get	httpclient/auth.rb	/^    def get/
 | 
			
		||||
get	httpclient/http.rb	/^      def get/
 | 
			
		||||
get_async	httpclient.rb	/^  def get_async/
 | 
			
		||||
get_body	httpclient/session.rb	/^    def get_body/
 | 
			
		||||
get_cached_session	httpclient/session.rb	/^    def get_cached_session/
 | 
			
		||||
get_content	httpclient.rb	/^  def get_content/
 | 
			
		||||
get_header	httpclient/session.rb	/^    def get_header/
 | 
			
		||||
get_mime_type_func	httpclient/http.rb	/^      alias get_mime_type_func/
 | 
			
		||||
getenv	httpclient.rb	/^  def getenv/
 | 
			
		||||
gets	httpclient/session.rb	/^    def gets/
 | 
			
		||||
gets	httpclient/session.rb	/^    def gets/
 | 
			
		||||
gets	httpclient/session.rb	/^    def gets/
 | 
			
		||||
hash	httpclient/session.rb	/^    def hash/
 | 
			
		||||
hash_find_value	httpclient/util.rb	/^    def hash_find_value/
 | 
			
		||||
head	httpclient.rb	/^  def head/
 | 
			
		||||
head_async	httpclient.rb	/^  def head_async/
 | 
			
		||||
head_match?	httpclient/cookie.rb	/^    def head_match?/
 | 
			
		||||
header	httpclient/http.rb	/^    attr_accessor :header/
 | 
			
		||||
host	httpclient/session.rb	/^    attr_reader :host/
 | 
			
		||||
http_version	httpclient/http.rb	/^      attr_accessor :http_version/
 | 
			
		||||
https?	httpclient.rb	/^  def https?/
 | 
			
		||||
init_connect_request	httpclient/http.rb	/^      def init_connect_request/
 | 
			
		||||
init_request	httpclient/http.rb	/^      def init_request/
 | 
			
		||||
init_request	httpclient/http.rb	/^      def init_request/
 | 
			
		||||
init_response	httpclient/http.rb	/^      def init_response/
 | 
			
		||||
init_response	httpclient/http.rb	/^      def init_response/
 | 
			
		||||
inspect	httpclient/session.rb	/^    def inspect/
 | 
			
		||||
internal_mime_type	httpclient/http.rb	/^      def internal_mime_type/
 | 
			
		||||
join	httpclient/connection.rb	/^    def join/
 | 
			
		||||
join_quotedstr	httpclient/cookie.rb	/^    def join_quotedstr/
 | 
			
		||||
keep	httpclient/session.rb	/^    def keep/
 | 
			
		||||
keep_alive_enabled?	httpclient/http.rb	/^      def keep_alive_enabled?/
 | 
			
		||||
keyword_argument	httpclient/util.rb	/^    def keyword_argument/
 | 
			
		||||
load_cacerts	httpclient/ssl_config.rb	/^    def load_cacerts/
 | 
			
		||||
load_cookies	httpclient/cookie.rb	/^    def load_cookies/
 | 
			
		||||
load_environment	httpclient.rb	/^  def load_environment/
 | 
			
		||||
make_cookie_str	httpclient/cookie.rb	/^    def make_cookie_str/
 | 
			
		||||
match	httpclient/session.rb	/^    def match/
 | 
			
		||||
match?	httpclient/cookie.rb	/^    def match?/
 | 
			
		||||
mime_type	httpclient/http.rb	/^      def mime_type/
 | 
			
		||||
mime_type_handler	httpclient/http.rb	/^      def mime_type_handler/
 | 
			
		||||
mime_type_handler=	httpclient/http.rb	/^      def mime_type_handler=/
 | 
			
		||||
multiparam_query?	httpclient/http.rb	/^      def multiparam_query?/
 | 
			
		||||
name	httpclient/cookie.rb	/^    attr_accessor :name, :value/
 | 
			
		||||
negotiate_auth	httpclient/auth.rb	/^    attr_reader :negotiate_auth/
 | 
			
		||||
negotiate_auth	httpclient/auth.rb	/^    attr_reader :negotiate_auth/
 | 
			
		||||
netscape_rule	httpclient/cookie.rb	/^    attr_accessor :netscape_rule/
 | 
			
		||||
new_connect_request	httpclient/http.rb	/^      def new_connect_request/
 | 
			
		||||
new_request	httpclient/http.rb	/^      def new_request/
 | 
			
		||||
new_response	httpclient/http.rb	/^      def new_response/
 | 
			
		||||
no_proxy	httpclient.rb	/^  def no_proxy/
 | 
			
		||||
no_proxy=	httpclient.rb	/^  def no_proxy=/
 | 
			
		||||
no_proxy?	httpclient.rb	/^  def no_proxy?/
 | 
			
		||||
normalize_cookie_value	httpclient/cookie.rb	/^    def normalize_cookie_value/
 | 
			
		||||
ntlm_opt	httpclient/auth.rb	/^    attr_reader :ntlm_opt/
 | 
			
		||||
open	httpclient/session.rb	/^    def open/
 | 
			
		||||
options	httpclient.rb	/^  def options/
 | 
			
		||||
options	httpclient/ssl_config.rb	/^    attr_reader :options/
 | 
			
		||||
options=	httpclient/ssl_config.rb	/^    def options=/
 | 
			
		||||
options_async	httpclient.rb	/^  def options_async/
 | 
			
		||||
override	httpclient/cookie.rb	/^    attr_writer :use, :secure, :discard, :domain_orig, :path_orig, :override/
 | 
			
		||||
override?	httpclient/cookie.rb	/^    def override?/
 | 
			
		||||
override_header	httpclient.rb	/^  def override_header/
 | 
			
		||||
params_from_file	httpclient/http.rb	/^      def params_from_file/
 | 
			
		||||
parse	httpclient/cookie.rb	/^    def parse/
 | 
			
		||||
parse	httpclient/cookie.rb	/^    def parse/
 | 
			
		||||
parse_authentication_header	httpclient/auth.rb	/^    def parse_authentication_header/
 | 
			
		||||
parse_challenge_header	httpclient/auth.rb	/^    def parse_challenge_header/
 | 
			
		||||
parse_challenge_param	httpclient/auth.rb	/^    def parse_challenge_param/
 | 
			
		||||
parse_header	httpclient/session.rb	/^    def parse_header/
 | 
			
		||||
parse_keepalive_header	httpclient/session.rb	/^    def parse_keepalive_header/
 | 
			
		||||
parts	httpclient/http.rb	/^        def parts/
 | 
			
		||||
path	httpclient/cookie.rb	/^    attr_accessor :domain, :path/
 | 
			
		||||
path_orig	httpclient/cookie.rb	/^    attr_writer :use, :secure, :discard, :domain_orig, :path_orig, :override/
 | 
			
		||||
path_orig?	httpclient/cookie.rb	/^    def path_orig?/
 | 
			
		||||
peer_cert	httpclient/http.rb	/^    attr_accessor :peer_cert/
 | 
			
		||||
peer_cert	httpclient/session.rb	/^    def peer_cert/
 | 
			
		||||
pop	httpclient/connection.rb	/^    def pop/
 | 
			
		||||
port	httpclient/session.rb	/^    attr_reader :port/
 | 
			
		||||
post	httpclient.rb	/^  def post/
 | 
			
		||||
post_async	httpclient.rb	/^  def post_async/
 | 
			
		||||
post_connection_check	httpclient/session.rb	/^    def post_connection_check/
 | 
			
		||||
post_connection_check	httpclient/ssl_config.rb	/^    def post_connection_check/
 | 
			
		||||
post_content	httpclient.rb	/^  def post_content/
 | 
			
		||||
propfind	httpclient.rb	/^  def propfind/
 | 
			
		||||
propfind_async	httpclient.rb	/^  def propfind_async/
 | 
			
		||||
proppatch	httpclient.rb	/^  def proppatch/
 | 
			
		||||
proppatch_async	httpclient.rb	/^  def proppatch_async/
 | 
			
		||||
protect_keep_alive_disconnected	httpclient.rb	/^  def protect_keep_alive_disconnected/
 | 
			
		||||
protocol_retry_count	httpclient/session.rb	/^    attr_accessor :protocol_retry_count/
 | 
			
		||||
protocol_retry_count	httpclient/session.rb	/^    attr_accessor :protocol_retry_count/
 | 
			
		||||
protocol_version	httpclient/session.rb	/^    attr_accessor :protocol_version/
 | 
			
		||||
proxy	httpclient.rb	/^  def proxy/
 | 
			
		||||
proxy	httpclient/session.rb	/^    attr_accessor :proxy/
 | 
			
		||||
proxy=	httpclient.rb	/^  def proxy=/
 | 
			
		||||
proxy=	httpclient/session.rb	/^    def proxy=/
 | 
			
		||||
proxy_auth	httpclient.rb	/^  attr_reader :proxy_auth/
 | 
			
		||||
push	httpclient/connection.rb	/^    def push/
 | 
			
		||||
put	httpclient.rb	/^  def put/
 | 
			
		||||
put_async	httpclient.rb	/^  def put_async/
 | 
			
		||||
query	httpclient/session.rb	/^    def query/
 | 
			
		||||
query	httpclient/session.rb	/^    def query/
 | 
			
		||||
raise	httpclient/timeout.rb	/^      def raise/
 | 
			
		||||
read	httpclient/session.rb	/^    def read/
 | 
			
		||||
read	httpclient/session.rb	/^    def read/
 | 
			
		||||
read	httpclient/session.rb	/^    def read/
 | 
			
		||||
read_block_size	httpclient/session.rb	/^    attr_accessor :read_block_size/
 | 
			
		||||
read_block_size	httpclient/session.rb	/^    attr_accessor :read_block_size/
 | 
			
		||||
read_body_chunked	httpclient/session.rb	/^    def read_body_chunked/
 | 
			
		||||
read_body_length	httpclient/session.rb	/^    def read_body_length/
 | 
			
		||||
read_body_rest	httpclient/session.rb	/^    def read_body_rest/
 | 
			
		||||
read_header	httpclient/session.rb	/^    def read_header/
 | 
			
		||||
readpartial	httpclient/session.rb	/^    def readpartial/
 | 
			
		||||
readpartial	httpclient/session.rb	/^    def readpartial/
 | 
			
		||||
readpartial	httpclient/session.rb	/^    def readpartial/
 | 
			
		||||
reason	httpclient/http.rb	/^    def reason/
 | 
			
		||||
reason=	httpclient/http.rb	/^    def reason=/
 | 
			
		||||
reason_phrase	httpclient/http.rb	/^      attr_accessor :reason_phrase/
 | 
			
		||||
receive_timeout	httpclient/session.rb	/^    attr_accessor :receive_timeout/
 | 
			
		||||
receive_timeout	httpclient/session.rb	/^    attr_accessor :receive_timeout/
 | 
			
		||||
redirect?	httpclient/http.rb	/^    def self.redirect?/
 | 
			
		||||
redirect_uri_callback=	httpclient.rb	/^  def redirect_uri_callback=/
 | 
			
		||||
register	httpclient/timeout.rb	/^    def register/
 | 
			
		||||
reject_domains	httpclient/cookie.rb	/^    attr_accessor :accept_domains, :reject_domains/
 | 
			
		||||
remember_pos	httpclient/http.rb	/^      def remember_pos/
 | 
			
		||||
request	httpclient.rb	/^  def request/
 | 
			
		||||
request_async	httpclient.rb	/^  def request_async/
 | 
			
		||||
request_filter	httpclient.rb	/^  attr_reader :request_filter/
 | 
			
		||||
request_line	httpclient/http.rb	/^      def request_line/
 | 
			
		||||
request_method	httpclient/http.rb	/^      attr_reader :request_method/
 | 
			
		||||
request_query	httpclient/http.rb	/^      attr_accessor :request_query/
 | 
			
		||||
request_uri	httpclient/http.rb	/^      attr_accessor :request_uri/
 | 
			
		||||
request_via_proxy	httpclient/http.rb	/^      attr_accessor :request_via_proxy/
 | 
			
		||||
requested_version	httpclient/session.rb	/^    attr_accessor :requested_version/
 | 
			
		||||
res	httpclient.rb	/^    attr_reader :res/
 | 
			
		||||
reset	httpclient.rb	/^  def reset/
 | 
			
		||||
reset	httpclient/session.rb	/^    def reset/
 | 
			
		||||
reset_all	httpclient.rb	/^  def reset_all/
 | 
			
		||||
reset_all	httpclient/session.rb	/^    def reset_all/
 | 
			
		||||
reset_challenge	httpclient/auth.rb	/^    def reset_challenge/
 | 
			
		||||
reset_challenge	httpclient/auth.rb	/^    def reset_challenge/
 | 
			
		||||
reset_challenge	httpclient/auth.rb	/^    def reset_challenge/
 | 
			
		||||
reset_challenge	httpclient/auth.rb	/^    def reset_challenge/
 | 
			
		||||
reset_challenge	httpclient/auth.rb	/^    def reset_challenge/
 | 
			
		||||
reset_challenge	httpclient/auth.rb	/^    def reset_challenge/
 | 
			
		||||
reset_pos	httpclient/http.rb	/^      def reset_pos/
 | 
			
		||||
response_status_line	httpclient/http.rb	/^      def response_status_line/
 | 
			
		||||
sample_verify_callback	httpclient/ssl_config.rb	/^    def sample_verify_callback/
 | 
			
		||||
save_all_cookies	httpclient/cookie.rb	/^    def save_all_cookies/
 | 
			
		||||
save_cookie_store	httpclient.rb	/^  def save_cookie_store/
 | 
			
		||||
save_cookies	httpclient/cookie.rb	/^    def save_cookies/
 | 
			
		||||
scheme	httpclient/auth.rb	/^    attr_reader :scheme/
 | 
			
		||||
scheme	httpclient/auth.rb	/^    attr_reader :scheme/
 | 
			
		||||
scheme	httpclient/auth.rb	/^    attr_reader :scheme/
 | 
			
		||||
scheme	httpclient/auth.rb	/^    attr_reader :scheme/
 | 
			
		||||
scheme	httpclient/session.rb	/^    attr_accessor :scheme/
 | 
			
		||||
secure	httpclient/cookie.rb	/^    attr_writer :use, :secure, :discard, :domain_orig, :path_orig, :override/
 | 
			
		||||
secure?	httpclient/cookie.rb	/^    def secure?/
 | 
			
		||||
send_timeout	httpclient/session.rb	/^    attr_accessor :send_timeout/
 | 
			
		||||
send_timeout	httpclient/session.rb	/^    attr_accessor :send_timeout/
 | 
			
		||||
set	httpclient/auth.rb	/^    def set/
 | 
			
		||||
set	httpclient/auth.rb	/^    def set/
 | 
			
		||||
set	httpclient/auth.rb	/^    def set/
 | 
			
		||||
set	httpclient/auth.rb	/^    def set/
 | 
			
		||||
set	httpclient/http.rb	/^      def set/
 | 
			
		||||
set_auth	httpclient.rb	/^  def set_auth/
 | 
			
		||||
set_auth	httpclient/auth.rb	/^    def set_auth/
 | 
			
		||||
set_auth	httpclient/auth.rb	/^    def set_auth/
 | 
			
		||||
set_basic_auth	httpclient.rb	/^  def set_basic_auth/
 | 
			
		||||
set_client_cert_file	httpclient/ssl_config.rb	/^    def set_client_cert_file/
 | 
			
		||||
set_content	httpclient/http.rb	/^      def set_content/
 | 
			
		||||
set_context	httpclient/ssl_config.rb	/^    def set_context/
 | 
			
		||||
set_cookie_store	httpclient.rb	/^  def set_cookie_store/
 | 
			
		||||
set_crl	httpclient/ssl_config.rb	/^    def set_crl/
 | 
			
		||||
set_flag	httpclient/cookie.rb	/^    def set_flag/
 | 
			
		||||
set_header	httpclient/http.rb	/^      def set_header/
 | 
			
		||||
set_header	httpclient/session.rb	/^    def set_header/
 | 
			
		||||
set_mime_type_func	httpclient/http.rb	/^      alias set_mime_type_func/
 | 
			
		||||
set_proxy_auth	httpclient.rb	/^  def set_proxy_auth/
 | 
			
		||||
set_request_header	httpclient/http.rb	/^      def set_request_header/
 | 
			
		||||
set_response_header	httpclient/http.rb	/^      def set_response_header/
 | 
			
		||||
set_trust_ca	httpclient/ssl_config.rb	/^    def set_trust_ca/
 | 
			
		||||
size	httpclient/http.rb	/^        attr_reader :size/
 | 
			
		||||
size	httpclient/http.rb	/^      attr_reader :size/
 | 
			
		||||
socket_sync	httpclient/session.rb	/^    attr_accessor :socket_sync/
 | 
			
		||||
socket_sync	httpclient/session.rb	/^    attr_accessor :socket_sync/
 | 
			
		||||
ssl_config	httpclient.rb	/^  attr_reader :ssl_config/
 | 
			
		||||
ssl_config	httpclient/session.rb	/^    attr_accessor :ssl_config/
 | 
			
		||||
ssl_config	httpclient/session.rb	/^    attr_accessor :ssl_config/
 | 
			
		||||
ssl_connect	httpclient/session.rb	/^    def ssl_connect/
 | 
			
		||||
ssl_peer_cert	httpclient/session.rb	/^    attr_reader :ssl_peer_cert/
 | 
			
		||||
sspi_negotiate_auth	httpclient/auth.rb	/^    attr_reader :sspi_negotiate_auth/
 | 
			
		||||
start_timer_thread	httpclient/timeout.rb	/^    def start_timer_thread/
 | 
			
		||||
status	httpclient/http.rb	/^    def status/
 | 
			
		||||
status=	httpclient/http.rb	/^    def status=/
 | 
			
		||||
status_code	httpclient/http.rb	/^      attr_reader :status_code/
 | 
			
		||||
status_code	httpclient/http.rb	/^    alias status_code/
 | 
			
		||||
status_code=	httpclient/http.rb	/^      def status_code=/
 | 
			
		||||
strict_redirect_uri_callback	httpclient.rb	/^  def strict_redirect_uri_callback/
 | 
			
		||||
successful?	httpclient/http.rb	/^    def self.successful?/
 | 
			
		||||
sync	httpclient/session.rb	/^    def sync/
 | 
			
		||||
sync	httpclient/session.rb	/^    def sync/
 | 
			
		||||
sync=	httpclient/session.rb	/^    def sync=/
 | 
			
		||||
sync=	httpclient/session.rb	/^    def sync=/
 | 
			
		||||
tail_match?	httpclient/cookie.rb	/^    def tail_match?/
 | 
			
		||||
test_loopback_http_response	httpclient/session.rb	/^    attr_accessor :test_loopback_http_response/
 | 
			
		||||
test_loopback_http_response	httpclient/session.rb	/^    attr_reader :test_loopback_http_response/
 | 
			
		||||
test_loopback_response	httpclient.rb	/^  attr_reader :test_loopback_response/
 | 
			
		||||
thread	httpclient/timeout.rb	/^      attr_reader :thread, :time/
 | 
			
		||||
time	httpclient/timeout.rb	/^      attr_reader :thread, :time/
 | 
			
		||||
timeout	httpclient/ssl_config.rb	/^    attr_reader :timeout/
 | 
			
		||||
timeout	httpclient/timeout.rb	/^    def timeout/
 | 
			
		||||
timeout=	httpclient/ssl_config.rb	/^    def timeout=/
 | 
			
		||||
timeout_scheduler	httpclient/timeout.rb	/^    def timeout_scheduler/
 | 
			
		||||
to_s	httpclient/session.rb	/^    def to_s/
 | 
			
		||||
total_dot_num	httpclient/cookie.rb	/^    def total_dot_num/
 | 
			
		||||
trace	httpclient.rb	/^  def trace/
 | 
			
		||||
trace_async	httpclient.rb	/^  def trace_async/
 | 
			
		||||
uri_dirname	httpclient/util.rb	/^    def uri_dirname/
 | 
			
		||||
uri_part_of	httpclient/util.rb	/^    def uri_part_of/
 | 
			
		||||
urify	httpclient/util.rb	/^    def urify/
 | 
			
		||||
url	httpclient/cookie.rb	/^    attr_accessor :url/
 | 
			
		||||
use	httpclient/cookie.rb	/^    attr_writer :use, :secure, :discard, :domain_orig, :path_orig, :override/
 | 
			
		||||
use?	httpclient/cookie.rb	/^    def use?/
 | 
			
		||||
value	httpclient/cookie.rb	/^    attr_accessor :name, :value/
 | 
			
		||||
verify_callback	httpclient/ssl_config.rb	/^    attr_reader :verify_callback/
 | 
			
		||||
verify_callback=	httpclient/ssl_config.rb	/^    def verify_callback=/
 | 
			
		||||
verify_depth	httpclient/ssl_config.rb	/^    attr_reader :verify_depth/
 | 
			
		||||
verify_depth=	httpclient/ssl_config.rb	/^    def verify_depth=/
 | 
			
		||||
verify_mode	httpclient/ssl_config.rb	/^    attr_reader :verify_mode/
 | 
			
		||||
verify_mode=	httpclient/ssl_config.rb	/^    def verify_mode=/
 | 
			
		||||
version	httpclient/http.rb	/^    def version/
 | 
			
		||||
version=	httpclient/http.rb	/^    def version=/
 | 
			
		||||
www_auth	httpclient.rb	/^  attr_reader :www_auth/
 | 
			
		||||
							
								
								
									
										2
									
								
								vendor/gems/gems/smusher-0.4.2/.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,2 @@
 | 
			
		|||
Manifest
 | 
			
		||||
pkg
 | 
			
		||||
							
								
								
									
										73
									
								
								vendor/gems/gems/smusher-0.4.2/README.markdown
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,73 @@
 | 
			
		|||
Problem
 | 
			
		||||
=======
 | 
			
		||||
 - Images are too large because they are not optimized
 | 
			
		||||
 - Users & your bandwidth is wasted for useless metadata
 | 
			
		||||
 - local image optimization requires tons of programs / libaries / knowledge
 | 
			
		||||
 | 
			
		||||
Solution
 | 
			
		||||
========
 | 
			
		||||
 - *LOSSLESS* size reduction (10-97% size reduction) in the cloud
 | 
			
		||||
 - optmizes all images(jpg+png+[gif]) from a given folder
 | 
			
		||||
 | 
			
		||||
Install
 | 
			
		||||
=======
 | 
			
		||||
    install ruby + rubygems
 | 
			
		||||
    sudo gem install smusher
 | 
			
		||||
 | 
			
		||||
Usage
 | 
			
		||||
=====
 | 
			
		||||
Optimize a single image or a whole folder in the cloud.
 | 
			
		||||
 | 
			
		||||
converting gif-s to png-s:
 | 
			
		||||
 | 
			
		||||
 - called with a folder gif-s will not be converted
 | 
			
		||||
 - called on a single .gif or wildcard, image(s) will be converted if optimizeable
 | 
			
		||||
 | 
			
		||||
Usage:
 | 
			
		||||
    smusher /apps/x/public/images [options]
 | 
			
		||||
    smusher /apps/x/public/images/x.png [options]
 | 
			
		||||
    smusher /apps/x/public/images/*.png [options]
 | 
			
		||||
 | 
			
		||||
Options are:
 | 
			
		||||
    -q, --quiet                      no output
 | 
			
		||||
    -c, --convert-gifs               convert all .gif`s in the given folder
 | 
			
		||||
    --service PunyPng                use PunyPng for image optimizing, instead of SmushIt
 | 
			
		||||
    -v, --version                    display current version
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Protection
 | 
			
		||||
==========
 | 
			
		||||
Any image that returns a failure code, is larger than before,
 | 
			
		||||
or is empty will not be saved.
 | 
			
		||||
 | 
			
		||||
Example
 | 
			
		||||
======
 | 
			
		||||
    smusher /apps/ts/public/images
 | 
			
		||||
      smushing /apps/rs/public/images/social/facebook_icon.png
 | 
			
		||||
      2887 -> 132                              = 4%
 | 
			
		||||
 | 
			
		||||
      smushing /apps/rs/public/images/social/myspace_icon.png
 | 
			
		||||
      3136 -> 282                              = 8%
 | 
			
		||||
 | 
			
		||||
      smushing /apps/rs/public/images/dvd/dvd_1.png
 | 
			
		||||
      5045 -> 4                                = 0%
 | 
			
		||||
      reverted!
 | 
			
		||||
      ...
 | 
			
		||||
 | 
			
		||||
TODO
 | 
			
		||||
====
 | 
			
		||||
 - only optimize 'new' images -> save time when doing on each deploy
 | 
			
		||||
 - convert gifs to png, even if the new size is the same, for consistency (atm only those which get smaller are converted)
 | 
			
		||||
 | 
			
		||||
ALTERNATIVES
 | 
			
		||||
============
 | 
			
		||||
If you want to lossless reduce images and minify css + js, try [reduce](http://github.com/grosser/reduce).
 | 
			
		||||
 | 
			
		||||
Authors
 | 
			
		||||
======
 | 
			
		||||
###Contributors
 | 
			
		||||
 - [retr0h](http://geminstallthat.wordpress.com/)
 | 
			
		||||
 | 
			
		||||
[Michael Grosser](http://pragmatig.wordpress.com)  
 | 
			
		||||
grosser.michael@gmail.com  
 | 
			
		||||
Hereby placed under public domain, do what you want, just do not hold me accountable...
 | 
			
		||||
							
								
								
									
										31
									
								
								vendor/gems/gems/smusher-0.4.2/Rakefile
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,31 @@
 | 
			
		|||
desc "Run all specs in spec directory"
 | 
			
		||||
task :default do |t|
 | 
			
		||||
  require 'spec'
 | 
			
		||||
  options = "--colour --format progress --loadby --reverse"
 | 
			
		||||
  files = FileList['spec/**/*_spec.rb']
 | 
			
		||||
  system("spec #{options} #{files}")
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
begin
 | 
			
		||||
  require 'jeweler'
 | 
			
		||||
  project_name = 'smusher'
 | 
			
		||||
  Jeweler::Tasks.new do |gem|
 | 
			
		||||
    gem.name = project_name
 | 
			
		||||
    gem.summary = "Automatic Lossless Reduction Of All Your Images"
 | 
			
		||||
    gem.email = "grosser.michael@gmail.com"
 | 
			
		||||
    gem.homepage = "http://github.com/grosser/#{project_name}"
 | 
			
		||||
    gem.authors = ["Michael Grosser"]
 | 
			
		||||
    %w[rake json httpclient].each{|d| gem.add_dependency d}
 | 
			
		||||
    gem.rubyforge_project = 'smusher'
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # fake task so that rubyforge:release works
 | 
			
		||||
  task :rdoc do
 | 
			
		||||
    `mkdir rdoc`
 | 
			
		||||
    `echo documentation is at http://github.com/grosser/#{project_name} > rdoc/README.rdoc`
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  Jeweler::RubyforgeTasks.new
 | 
			
		||||
rescue LoadError
 | 
			
		||||
  puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										1
									
								
								vendor/gems/gems/smusher-0.4.2/VERSION
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
0.4.2
 | 
			
		||||
							
								
								
									
										39
									
								
								vendor/gems/gems/smusher-0.4.2/bin/smusher
									
										
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,39 @@
 | 
			
		|||
#!/usr/bin/env ruby
 | 
			
		||||
require 'rubygems'
 | 
			
		||||
require 'optparse'
 | 
			
		||||
require 'smusher'
 | 
			
		||||
 | 
			
		||||
options = {}
 | 
			
		||||
OptionParser.new do |opts|
 | 
			
		||||
  opts.banner = <<BANNER
 | 
			
		||||
Optimize a single image or a whole folder in the cloud.
 | 
			
		||||
 | 
			
		||||
gif`s:
 | 
			
		||||
 - called with a folder gif`s will not be optimized
 | 
			
		||||
 - called on a singe .gif, it will be optimized if it is optimizeable
 | 
			
		||||
 | 
			
		||||
Usage:
 | 
			
		||||
    smusher /apps/x/public/images [options]
 | 
			
		||||
    smusher /apps/x/public/images/x.png [options]
 | 
			
		||||
    smusher /apps/x/public/images/*.png [options]
 | 
			
		||||
 | 
			
		||||
Options are:
 | 
			
		||||
BANNER
 | 
			
		||||
  opts.on("-q", "--quiet","no output") { options[:quiet]=true }
 | 
			
		||||
  opts.on("--service S", String, "use service: PunyPng or default SmushIt") {|x| options[:service]=x }
 | 
			
		||||
  opts.on("-c", "--convert-gifs","convert all .gif`s in the given folder") { options[:convert_gifs]=true }
 | 
			
		||||
  opts.on("-h", "--help","Show this.") { puts opts; exit }
 | 
			
		||||
  opts.on('-v', '--version','Show Version'){ puts Smusher::VERSION; exit}
 | 
			
		||||
end.parse!
 | 
			
		||||
 | 
			
		||||
path = ARGV.first
 | 
			
		||||
if path.to_s.empty? or not File.exist?(path)
 | 
			
		||||
  puts "Usage instructions: autotest --help"
 | 
			
		||||
  exit
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
if File.directory?(path)
 | 
			
		||||
  Smusher.optimize_images_in_folder(path,options)
 | 
			
		||||
else
 | 
			
		||||
  Smusher.optimize_image(ARGV,options)
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										97
									
								
								vendor/gems/gems/smusher-0.4.2/lib/smusher.rb
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,97 @@
 | 
			
		|||
require 'rubygems'
 | 
			
		||||
require 'rake'
 | 
			
		||||
require 'json'
 | 
			
		||||
require 'open-uri'
 | 
			
		||||
require 'httpclient'
 | 
			
		||||
 | 
			
		||||
require 'smusher/smush_it'
 | 
			
		||||
require 'smusher/puny_png'
 | 
			
		||||
 | 
			
		||||
module Smusher
 | 
			
		||||
  extend self
 | 
			
		||||
 | 
			
		||||
  MINIMUM_IMAGE_SIZE = 20#byte
 | 
			
		||||
 | 
			
		||||
  VERSION = File.read( File.join(File.dirname(__FILE__),'..','VERSION') ).strip
 | 
			
		||||
 | 
			
		||||
  # optimize the given image
 | 
			
		||||
  # converts gif to png, if size is lower
 | 
			
		||||
  # can be called with a file-path or an array of files-paths
 | 
			
		||||
  def optimize_image(files,options={})
 | 
			
		||||
    service = options[:service] || 'SmushIt'
 | 
			
		||||
    service = eval(service)
 | 
			
		||||
 | 
			
		||||
    files.each do |file|
 | 
			
		||||
      check_options(options)
 | 
			
		||||
      puts "THIS FILE IS EMPTY!!! #{file}" and return if size(file).zero?
 | 
			
		||||
      success = false
 | 
			
		||||
 | 
			
		||||
      with_logging(file,options[:quiet]) do
 | 
			
		||||
        write_optimized_data(file, service)
 | 
			
		||||
        success = true
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      if success and service.converts_gif_to_png?
 | 
			
		||||
        gif = /\.gif$/
 | 
			
		||||
        `mv #{file} #{file.sub(gif,'.png')}` if file =~ gif
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # fetch all jpg/png images from  given folder and optimize them
 | 
			
		||||
  def optimize_images_in_folder(folder, options={})
 | 
			
		||||
    check_options(options)
 | 
			
		||||
    images_in_folder(folder, options[:convert_gifs]).each do |file|
 | 
			
		||||
      optimize_image(file, options)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  private
 | 
			
		||||
 | 
			
		||||
  def check_options(options)
 | 
			
		||||
    known_options = [:convert_gifs, :quiet, :service]
 | 
			
		||||
    if options.detect{|k,v| not known_options.include?(k)}
 | 
			
		||||
      raise "Known options: #{known_options*' '}"
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def write_optimized_data(file, service)
 | 
			
		||||
    optimized = service.optimized_image_data_for(file)
 | 
			
		||||
 | 
			
		||||
    raise "Error: got larger" if size(file) < optimized.size
 | 
			
		||||
    raise "Error: empty file downloaded" if optimized.size < MINIMUM_IMAGE_SIZE
 | 
			
		||||
    raise "cannot be optimized further" if size(file) == optimized.size
 | 
			
		||||
 | 
			
		||||
    File.open(file,'w') {|f| f.write optimized}
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def sanitize_folder(folder)
 | 
			
		||||
    folder.sub(%r[/$],'')#remove tailing slash
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def images_in_folder(folder,with_gifs=false)
 | 
			
		||||
    folder = sanitize_folder(folder)
 | 
			
		||||
    images = %w[png jpg jpeg JPG]
 | 
			
		||||
    images << 'gif' if with_gifs
 | 
			
		||||
    images.map! {|ext| "#{folder}/**/*.#{ext}"}
 | 
			
		||||
    FileList[*images]
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def size(file)
 | 
			
		||||
    File.exist?(file) ? File.size(file) : 0
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def with_logging(file,quiet)
 | 
			
		||||
    puts "smushing #{file}" unless quiet
 | 
			
		||||
 | 
			
		||||
    before = size(file)
 | 
			
		||||
    begin; yield; rescue; puts $! unless quiet; end
 | 
			
		||||
    after = size(file)
 | 
			
		||||
 | 
			
		||||
    unless quiet
 | 
			
		||||
      result = "#{(100*after)/before}%"
 | 
			
		||||
      puts "#{before} -> #{after}".ljust(40) + " = #{result}"
 | 
			
		||||
      puts ''
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										17
									
								
								vendor/gems/gems/smusher-0.4.2/lib/smusher/puny_png.rb
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,17 @@
 | 
			
		|||
module Smusher
 | 
			
		||||
  class PunyPng
 | 
			
		||||
    def self.converts_gif_to_png?
 | 
			
		||||
      false
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def self.optimized_image_data_for(file)
 | 
			
		||||
      url = 'http://www.gracepointafterfive.com/punypng_staging/api/optimize'
 | 
			
		||||
      response = HTTPClient.post url, { 'img' => File.new(file), 'key' => 'd1b72ab4813da6b69e1d6018303ac690c014599d'}
 | 
			
		||||
      response = JSON.parse(response.body.content)
 | 
			
		||||
      raise "puny_png: #{response['error']}" if response['error']
 | 
			
		||||
      image_url = response['optimized_url']
 | 
			
		||||
      raise "no optimized_url found" unless image_url
 | 
			
		||||
      open(image_url) { |source| source.read() }
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										22
									
								
								vendor/gems/gems/smusher-0.4.2/lib/smusher/smush_it.rb
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,22 @@
 | 
			
		|||
module Smusher
 | 
			
		||||
  class SmushIt
 | 
			
		||||
    def self.converts_gif_to_png?
 | 
			
		||||
      true
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def self.optimized_image_data_for(file)
 | 
			
		||||
      #I leave these urls here, just in case it stops working again...
 | 
			
		||||
      # url = "http://smush.it/ws.php" # original, redirects to somewhere else..
 | 
			
		||||
      # url = "http://developer.yahoo.com/yslow/smushit/ws.php" # official but does not work
 | 
			
		||||
      # url = "http://smushit.com/ysmush.it/ws.php" # used at the new page but does not hande uploads
 | 
			
		||||
      # url = "http://smushit.eperf.vip.ac4.yahoo.com/ysmush.it/ws.php" # used at the new page but does not hande uploads
 | 
			
		||||
        url = 'http://ws1.adq.ac4.yahoo.com/ysmush.it/ws.php'
 | 
			
		||||
      response = HTTPClient.post url, { 'files[]' => File.new(file)}
 | 
			
		||||
      response = JSON.parse(response.body.content)
 | 
			
		||||
      raise "smush.it: #{response['error']}" if response['error']
 | 
			
		||||
      image_url = response['dest']
 | 
			
		||||
      raise "no dest path found" unless image_url
 | 
			
		||||
      open(image_url) { |source| source.read() }
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										79
									
								
								vendor/gems/gems/smusher-0.4.2/smusher.gemspec
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,79 @@
 | 
			
		|||
# Generated by jeweler
 | 
			
		||||
# DO NOT EDIT THIS FILE
 | 
			
		||||
# Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
 | 
			
		||||
# -*- encoding: utf-8 -*-
 | 
			
		||||
 | 
			
		||||
Gem::Specification.new do |s|
 | 
			
		||||
  s.name = %q{smusher}
 | 
			
		||||
  s.version = "0.4.2"
 | 
			
		||||
 | 
			
		||||
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
 | 
			
		||||
  s.authors = ["Michael Grosser"]
 | 
			
		||||
  s.date = %q{2009-10-09}
 | 
			
		||||
  s.default_executable = %q{smusher}
 | 
			
		||||
  s.email = %q{grosser.michael@gmail.com}
 | 
			
		||||
  s.executables = ["smusher"]
 | 
			
		||||
  s.extra_rdoc_files = [
 | 
			
		||||
    "README.markdown"
 | 
			
		||||
  ]
 | 
			
		||||
  s.files = [
 | 
			
		||||
    ".gitignore",
 | 
			
		||||
     "README.markdown",
 | 
			
		||||
     "Rakefile",
 | 
			
		||||
     "VERSION",
 | 
			
		||||
     "bin/smusher",
 | 
			
		||||
     "lib/smusher.rb",
 | 
			
		||||
     "lib/smusher/puny_png.rb",
 | 
			
		||||
     "lib/smusher/smush_it.rb",
 | 
			
		||||
     "rdoc/README.rdoc",
 | 
			
		||||
     "smusher.gemspec",
 | 
			
		||||
     "spec/empty/.gitignore",
 | 
			
		||||
     "spec/images/ad.gif",
 | 
			
		||||
     "spec/images/add.png",
 | 
			
		||||
     "spec/images/drink_empty.png",
 | 
			
		||||
     "spec/images/logo.gif",
 | 
			
		||||
     "spec/images/people.jpg",
 | 
			
		||||
     "spec/images/water.JPG",
 | 
			
		||||
     "spec/images/woman.jpeg",
 | 
			
		||||
     "spec/out/ad.gif",
 | 
			
		||||
     "spec/out/people.jpg",
 | 
			
		||||
     "spec/reduced/add.png",
 | 
			
		||||
     "spec/reduced/add_puny.png",
 | 
			
		||||
     "spec/reduced/fam.png",
 | 
			
		||||
     "spec/smusher/puny_png_spec.rb",
 | 
			
		||||
     "spec/smusher/smush_it_spec.rb",
 | 
			
		||||
     "spec/smusher_spec.rb",
 | 
			
		||||
     "spec/spec_helper.rb"
 | 
			
		||||
  ]
 | 
			
		||||
  s.homepage = %q{http://github.com/grosser/smusher}
 | 
			
		||||
  s.rdoc_options = ["--charset=UTF-8"]
 | 
			
		||||
  s.require_paths = ["lib"]
 | 
			
		||||
  s.rubyforge_project = %q{smusher}
 | 
			
		||||
  s.rubygems_version = %q{1.3.5}
 | 
			
		||||
  s.summary = %q{Automatic Lossless Reduction Of All Your Images}
 | 
			
		||||
  s.test_files = [
 | 
			
		||||
    "spec/smusher/smush_it_spec.rb",
 | 
			
		||||
     "spec/smusher/puny_png_spec.rb",
 | 
			
		||||
     "spec/spec_helper.rb",
 | 
			
		||||
     "spec/smusher_spec.rb"
 | 
			
		||||
  ]
 | 
			
		||||
 | 
			
		||||
  if s.respond_to? :specification_version then
 | 
			
		||||
    current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
 | 
			
		||||
    s.specification_version = 3
 | 
			
		||||
 | 
			
		||||
    if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
 | 
			
		||||
      s.add_runtime_dependency(%q<rake>, [">= 0"])
 | 
			
		||||
      s.add_runtime_dependency(%q<json>, [">= 0"])
 | 
			
		||||
      s.add_runtime_dependency(%q<httpclient>, [">= 0"])
 | 
			
		||||
    else
 | 
			
		||||
      s.add_dependency(%q<rake>, [">= 0"])
 | 
			
		||||
      s.add_dependency(%q<json>, [">= 0"])
 | 
			
		||||
      s.add_dependency(%q<httpclient>, [">= 0"])
 | 
			
		||||
    end
 | 
			
		||||
  else
 | 
			
		||||
    s.add_dependency(%q<rake>, [">= 0"])
 | 
			
		||||
    s.add_dependency(%q<json>, [">= 0"])
 | 
			
		||||
    s.add_dependency(%q<httpclient>, [">= 0"])
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										0
									
								
								vendor/gems/gems/smusher-0.4.2/spec/empty/.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								vendor/gems/gems/smusher-0.4.2/spec/images/ad.gif
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 371 B  | 
							
								
								
									
										
											BIN
										
									
								
								vendor/gems/gems/smusher-0.4.2/spec/images/add.png
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 733 B  | 
							
								
								
									
										
											BIN
										
									
								
								vendor/gems/gems/smusher-0.4.2/spec/images/drink_empty.png
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 433 B  | 
							
								
								
									
										
											BIN
										
									
								
								vendor/gems/gems/smusher-0.4.2/spec/images/logo.gif
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 945 B  | 
							
								
								
									
										
											BIN
										
									
								
								vendor/gems/gems/smusher-0.4.2/spec/images/people.jpg
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.4 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								vendor/gems/gems/smusher-0.4.2/spec/images/water.JPG
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.6 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								vendor/gems/gems/smusher-0.4.2/spec/images/woman.jpeg
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.5 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								vendor/gems/gems/smusher-0.4.2/spec/out/ad.gif
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 371 B  | 
							
								
								
									
										
											BIN
										
									
								
								vendor/gems/gems/smusher-0.4.2/spec/out/people.jpg
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.4 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								vendor/gems/gems/smusher-0.4.2/spec/reduced/add.png
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 680 B  | 
							
								
								
									
										
											BIN
										
									
								
								vendor/gems/gems/smusher-0.4.2/spec/reduced/add_puny.png
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 733 B  | 
							
								
								
									
										
											BIN
										
									
								
								vendor/gems/gems/smusher-0.4.2/spec/reduced/fam.png
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 381 B  | 
							
								
								
									
										12
									
								
								vendor/gems/gems/smusher-0.4.2/spec/smusher/puny_png_spec.rb
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,12 @@
 | 
			
		|||
require 'spec/spec_helper'
 | 
			
		||||
 | 
			
		||||
describe Smusher::PunyPng do
 | 
			
		||||
  describe :optimized_image_data_for do
 | 
			
		||||
    it "loads the reduced image" do
 | 
			
		||||
      original = File.join(ROOT,'images','add.png')
 | 
			
		||||
      reduced = File.read(File.join(ROOT, 'reduced', 'add_puny.png'))
 | 
			
		||||
      received = Smusher::PunyPng.optimized_image_data_for(original)
 | 
			
		||||
      received.should == reduced
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										12
									
								
								vendor/gems/gems/smusher-0.4.2/spec/smusher/smush_it_spec.rb
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,12 @@
 | 
			
		|||
require 'spec/spec_helper'
 | 
			
		||||
 | 
			
		||||
describe Smusher::SmushIt do
 | 
			
		||||
  describe :optimized_image_data_for do
 | 
			
		||||
    it "loads the reduced image" do
 | 
			
		||||
      original = File.join(ROOT,'images','add.png')
 | 
			
		||||
      reduced = File.open(File.join(ROOT,'reduced','add.png')).read
 | 
			
		||||
      received = Smusher::SmushIt.optimized_image_data_for(original)
 | 
			
		||||
      received.should == reduced
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										181
									
								
								vendor/gems/gems/smusher-0.4.2/spec/smusher_spec.rb
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,181 @@
 | 
			
		|||
require 'spec/spec_helper'
 | 
			
		||||
 | 
			
		||||
describe :smusher do
 | 
			
		||||
  def copy(image_name)
 | 
			
		||||
    FileUtils.cp(File.join(ROOT,'images',image_name), @out)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def size
 | 
			
		||||
    File.size(@file)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  before do
 | 
			
		||||
    #prepare output folder
 | 
			
		||||
    @out = File.join(ROOT,'out')
 | 
			
		||||
    FileUtils.rm_r @out, :force=>true
 | 
			
		||||
    FileUtils.mkdir @out
 | 
			
		||||
    copy 'people.jpg'
 | 
			
		||||
    copy 'ad.gif'
 | 
			
		||||
 | 
			
		||||
    @file = File.join(@out,'people.jpg')
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe :optimize_image do
 | 
			
		||||
    it "stores the image in an reduced size" do
 | 
			
		||||
      original_size = size
 | 
			
		||||
      Smusher.optimize_image(@file)
 | 
			
		||||
      size.should < original_size
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "does not append newline" do
 | 
			
		||||
      copy 'add.png'
 | 
			
		||||
      file = File.join(@out, 'add.png')
 | 
			
		||||
      Smusher.optimize_image file
 | 
			
		||||
      # pure File.read() will omit trailing \n
 | 
			
		||||
      File.readlines(file).last.split('').last.should_not == "\n" 
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "can be called with an array of files" do
 | 
			
		||||
      original_size = size
 | 
			
		||||
      Smusher.optimize_image([@file])
 | 
			
		||||
      size.should < original_size
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "it does nothing if size stayed the same" do
 | 
			
		||||
      original_size = size
 | 
			
		||||
      Smusher::SmushIt.should_receive(:optimized_image_data_for).and_return File.read(@file)
 | 
			
		||||
      Smusher.optimize_image(@file)
 | 
			
		||||
      size.should == original_size
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "does not save images whoes size got larger" do
 | 
			
		||||
      original_size = size
 | 
			
		||||
      Smusher::SmushIt.should_receive(:optimized_image_data_for).and_return File.read(@file)*2
 | 
			
		||||
      Smusher.optimize_image(@file)
 | 
			
		||||
      size.should == original_size
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "does not save images if their size is error-sugesting-small" do
 | 
			
		||||
      original_size = size
 | 
			
		||||
      Smusher::SmushIt.should_receive(:optimized_image_data_for).and_return 'oops...'
 | 
			
		||||
      Smusher.optimize_image(@file)
 | 
			
		||||
      size.should == original_size
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    describe "gif handling" do
 | 
			
		||||
      before do
 | 
			
		||||
        copy 'logo.gif'
 | 
			
		||||
        @file = File.join(@out,'logo.gif')
 | 
			
		||||
        @file_png = File.join(@out,'logo.png')
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "converts gifs to png even if they have the same size" do
 | 
			
		||||
        pending
 | 
			
		||||
        copy 'ad.gif'
 | 
			
		||||
        file = File.join(@out,'ad.gif')
 | 
			
		||||
        original_size = size
 | 
			
		||||
        Smusher.optimize_image(file)
 | 
			
		||||
        File.size(File.join(@out,'ad.png')).should == original_size
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "stores converted .gifs in .png files" do
 | 
			
		||||
        Smusher.optimize_image(@file)
 | 
			
		||||
        File.exist?(@file).should == false
 | 
			
		||||
        File.exist?(@file_png).should == true
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "does not rename gifs, if optimizing failed" do
 | 
			
		||||
        Smusher::SmushIt.should_receive(:optimized_image_data_for).and_return File.read(@file)
 | 
			
		||||
        Smusher.optimize_image(@file)
 | 
			
		||||
        File.exist?(@file).should == true
 | 
			
		||||
        File.exist?(@file_png).should == false
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    describe 'options' do
 | 
			
		||||
      it "does not produce output when :quiet is given" do
 | 
			
		||||
        $stdout.should_receive(:write).never
 | 
			
		||||
        Smusher.optimize_image(@file,:quiet=>true)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "raises when an unknown option was given" do
 | 
			
		||||
        lambda{Smusher.optimize_image(@file,:q=>true)}.should raise_error
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe :optimize_images_in_folder do
 | 
			
		||||
    before do
 | 
			
		||||
      FileUtils.rm @file
 | 
			
		||||
      @files = []
 | 
			
		||||
      %w[add.png drink_empty.png].each do |image_name|
 | 
			
		||||
        copy image_name
 | 
			
		||||
        @files << File.join(@out,image_name)
 | 
			
		||||
      end
 | 
			
		||||
      @before = @files.map {|f|File.size(f)}
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "optimizes all images" do
 | 
			
		||||
      Smusher.optimize_images_in_folder(@out)
 | 
			
		||||
      new_sizes = @files.map {|f|File.size(f)}
 | 
			
		||||
      new_sizes.size.times {|i| new_sizes[i].should < @before[i]}
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "does not convert gifs" do
 | 
			
		||||
      copy 'logo.gif'
 | 
			
		||||
      Smusher.optimize_images_in_folder(@out)
 | 
			
		||||
      File.exist?(File.join(@out,'logo.png')).should == false
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "converts gifs to png when option was given" do
 | 
			
		||||
      copy 'logo.gif'
 | 
			
		||||
      Smusher.optimize_images_in_folder(@out,:convert_gifs=>true)
 | 
			
		||||
      File.exist?(File.join(@out,'logo.png')).should == true
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe :sanitize_folder do
 | 
			
		||||
    it "cleans a folders trailing slash" do
 | 
			
		||||
      Smusher.send(:sanitize_folder,"xx/").should == 'xx'
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "does not clean if there is no trailing slash" do
 | 
			
		||||
      Smusher.send(:sanitize_folder,"/x/ccx").should == '/x/ccx'
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe :images_in_folder do
 | 
			
		||||
    it "finds all non-gif images" do
 | 
			
		||||
      folder = File.join(ROOT,'images')
 | 
			
		||||
      all = %w[add.png drink_empty.png people.jpg water.JPG woman.jpeg].map{|name|"#{folder}/#{name}"}
 | 
			
		||||
      result = Smusher.send(:images_in_folder,folder)
 | 
			
		||||
      (all+result).uniq.size.should == all.size
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "finds nothing if folder is empty" do
 | 
			
		||||
      Smusher.send(:images_in_folder,File.join(ROOT,'empty')).should == []
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe :size do
 | 
			
		||||
    it "find the size of a file" do
 | 
			
		||||
      Smusher.send(:size,@file).should == File.size(@file)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "and_return 0 for missing file" do
 | 
			
		||||
      Smusher.send(:size,File.join(ROOT,'xxxx','dssdfsddfs')).should == 0
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe :logging do
 | 
			
		||||
    it "yields" do
 | 
			
		||||
      val = 0
 | 
			
		||||
      Smusher.send(:with_logging,@file,false) {val = 1}
 | 
			
		||||
      val.should == 1
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  it "has a VERSION" do
 | 
			
		||||
    Smusher::VERSION.should =~ /^\d+\.\d+\.\d+$/
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										8
									
								
								vendor/gems/gems/smusher-0.4.2/spec/spec_helper.rb
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,8 @@
 | 
			
		|||
# ---- requirements
 | 
			
		||||
require 'rubygems'
 | 
			
		||||
require 'spec'
 | 
			
		||||
 | 
			
		||||
$LOAD_PATH << 'lib'
 | 
			
		||||
require 'smusher'
 | 
			
		||||
 | 
			
		||||
ROOT = File.expand_path(File.dirname(__FILE__))
 | 
			
		||||
							
								
								
									
										26
									
								
								vendor/gems/specifications/httpclient-2.1.5.2.gemspec
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,26 @@
 | 
			
		|||
# -*- encoding: utf-8 -*-
 | 
			
		||||
 | 
			
		||||
Gem::Specification.new do |s|
 | 
			
		||||
  s.name = %q{httpclient}
 | 
			
		||||
  s.version = "2.1.5.2"
 | 
			
		||||
 | 
			
		||||
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
 | 
			
		||||
  s.authors = ["NAKAMURA, Hiroshi"]
 | 
			
		||||
  s.date = %q{2009-06-24}
 | 
			
		||||
  s.email = %q{nahi@ruby-lang.org}
 | 
			
		||||
  s.files = ["lib/tags", "lib/http-access2", "lib/http-access2/http.rb", "lib/http-access2/cookie.rb", "lib/httpclient", "lib/httpclient/connection.rb", "lib/httpclient/cacert_sha1.p7s", "lib/httpclient/http.rb", "lib/httpclient/auth.rb", "lib/httpclient/util.rb", "lib/httpclient/session.rb", "lib/httpclient/ssl_config.rb", "lib/httpclient/timeout.rb", "lib/httpclient/cookie.rb", "lib/httpclient/cacert.p7s", "lib/httpclient.rb", "lib/http-access2.rb"]
 | 
			
		||||
  s.homepage = %q{http://dev.ctor.org/httpclient}
 | 
			
		||||
  s.require_paths = ["lib"]
 | 
			
		||||
  s.rubygems_version = %q{1.3.5}
 | 
			
		||||
  s.summary = %q{gives something like the functionality of libwww-perl (LWP) in Ruby}
 | 
			
		||||
 | 
			
		||||
  if s.respond_to? :specification_version then
 | 
			
		||||
    current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
 | 
			
		||||
    s.specification_version = 2
 | 
			
		||||
 | 
			
		||||
    if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
 | 
			
		||||
    else
 | 
			
		||||
    end
 | 
			
		||||
  else
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										41
									
								
								vendor/gems/specifications/smusher-0.4.2.gemspec
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,41 @@
 | 
			
		|||
# -*- encoding: utf-8 -*-
 | 
			
		||||
 | 
			
		||||
Gem::Specification.new do |s|
 | 
			
		||||
  s.name = %q{smusher}
 | 
			
		||||
  s.version = "0.4.2"
 | 
			
		||||
 | 
			
		||||
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
 | 
			
		||||
  s.authors = ["Michael Grosser"]
 | 
			
		||||
  s.date = %q{2009-10-08}
 | 
			
		||||
  s.default_executable = %q{smusher}
 | 
			
		||||
  s.email = %q{grosser.michael@gmail.com}
 | 
			
		||||
  s.executables = ["smusher"]
 | 
			
		||||
  s.extra_rdoc_files = ["README.markdown"]
 | 
			
		||||
  s.files = [".gitignore", "README.markdown", "Rakefile", "VERSION", "bin/smusher", "lib/smusher.rb", "lib/smusher/puny_png.rb", "lib/smusher/smush_it.rb", "rdoc/README.rdoc", "smusher.gemspec", "spec/empty/.gitignore", "spec/images/ad.gif", "spec/images/add.png", "spec/images/drink_empty.png", "spec/images/logo.gif", "spec/images/people.jpg", "spec/images/water.JPG", "spec/images/woman.jpeg", "spec/out/ad.gif", "spec/out/people.jpg", "spec/reduced/add.png", "spec/reduced/add_puny.png", "spec/reduced/fam.png", "spec/smusher/puny_png_spec.rb", "spec/smusher/smush_it_spec.rb", "spec/smusher_spec.rb", "spec/spec_helper.rb"]
 | 
			
		||||
  s.homepage = %q{http://github.com/grosser/smusher}
 | 
			
		||||
  s.rdoc_options = ["--charset=UTF-8"]
 | 
			
		||||
  s.require_paths = ["lib"]
 | 
			
		||||
  s.rubyforge_project = %q{smusher}
 | 
			
		||||
  s.rubygems_version = %q{1.3.5}
 | 
			
		||||
  s.summary = %q{Automatic Lossless Reduction Of All Your Images}
 | 
			
		||||
  s.test_files = ["spec/smusher/smush_it_spec.rb", "spec/smusher/puny_png_spec.rb", "spec/spec_helper.rb", "spec/smusher_spec.rb"]
 | 
			
		||||
 | 
			
		||||
  if s.respond_to? :specification_version then
 | 
			
		||||
    current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
 | 
			
		||||
    s.specification_version = 3
 | 
			
		||||
 | 
			
		||||
    if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
 | 
			
		||||
      s.add_runtime_dependency(%q<rake>, [">= 0"])
 | 
			
		||||
      s.add_runtime_dependency(%q<json>, [">= 0"])
 | 
			
		||||
      s.add_runtime_dependency(%q<httpclient>, [">= 0"])
 | 
			
		||||
    else
 | 
			
		||||
      s.add_dependency(%q<rake>, [">= 0"])
 | 
			
		||||
      s.add_dependency(%q<json>, [">= 0"])
 | 
			
		||||
      s.add_dependency(%q<httpclient>, [">= 0"])
 | 
			
		||||
    end
 | 
			
		||||
  else
 | 
			
		||||
    s.add_dependency(%q<rake>, [">= 0"])
 | 
			
		||||
    s.add_dependency(%q<json>, [">= 0"])
 | 
			
		||||
    s.add_dependency(%q<httpclient>, [">= 0"])
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||