add smusher dep
1
.gitignore
vendored
|
@ -26,3 +26,4 @@ bin/spec
|
||||||
bin/sprocketize
|
bin/sprocketize
|
||||||
bin/thin
|
bin/thin
|
||||||
bin/tt
|
bin/tt
|
||||||
|
bin/smusher
|
1
Gemfile
|
@ -11,6 +11,7 @@ gem "rack-test"
|
||||||
gem "yui-compressor"
|
gem "yui-compressor"
|
||||||
gem "haml"
|
gem "haml"
|
||||||
gem "compass"
|
gem "compass"
|
||||||
|
gem "smusher"
|
||||||
|
|
||||||
gem "rspec"
|
gem "rspec"
|
||||||
gem "sdoc"
|
gem "sdoc"
|
||||||
|
|
1
Rakefile
|
@ -21,6 +21,7 @@ begin
|
||||||
gem.add_dependency("sinatra-content-for")
|
gem.add_dependency("sinatra-content-for")
|
||||||
gem.add_dependency("rack-test")
|
gem.add_dependency("rack-test")
|
||||||
gem.add_dependency("yui-compressor")
|
gem.add_dependency("yui-compressor")
|
||||||
|
gem.add_dependency("smusher")
|
||||||
gem.add_dependency("haml", ">=2.1.0")
|
gem.add_dependency("haml", ">=2.1.0")
|
||||||
gem.add_dependency("compass")
|
gem.add_dependency("compass")
|
||||||
gem.add_development_dependency("rspec")
|
gem.add_development_dependency("rspec")
|
||||||
|
|
|
@ -26,9 +26,9 @@ configure :build do
|
||||||
# Shrink/smush PNG/JPEGs on build
|
# Shrink/smush PNG/JPEGs on build
|
||||||
# enable :smush_pngs
|
# enable :smush_pngs
|
||||||
|
|
||||||
|
# Enable cache buster
|
||||||
|
# enable :cache_buster
|
||||||
|
|
||||||
# Or use a different image path
|
# Or use a different image path
|
||||||
# set :http_path, "/Content/images/"
|
# set :http_path, "/Content/images/"
|
||||||
|
|
||||||
# Disable cache buster
|
|
||||||
# disable :cache_buster
|
|
||||||
end
|
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["PATH"] = "#{dir}/../../bin:#{ENV["PATH"]}"
|
||||||
ENV["RUBYOPT"] = "-r#{file} #{ENV["RUBYOPT"]}"
|
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/bin")
|
||||||
$LOAD_PATH.unshift File.expand_path("#{dir}/gems/builder-2.1.2/lib")
|
$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/bin")
|
||||||
$LOAD_PATH.unshift File.expand_path("#{dir}/gems/polyglot-0.2.9/lib")
|
$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/bin")
|
||||||
$LOAD_PATH.unshift File.expand_path("#{dir}/gems/treetop-1.4.2/lib")
|
$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/bin")
|
||||||
$LOAD_PATH.unshift File.expand_path("#{dir}/gems/term-ansicolor-1.0.4/lib")
|
$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/bin")
|
||||||
$LOAD_PATH.unshift File.expand_path("#{dir}/gems/cucumber-0.4.4/lib")
|
$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/rspec-1.2.9/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/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/bin")
|
||||||
$LOAD_PATH.unshift File.expand_path("#{dir}/gems/compass-0.8.17/lib")
|
$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"
|
@gemfile = "#{dir}/../../Gemfile"
|
||||||
|
|
||||||
|
@ -134,7 +138,7 @@ end
|
||||||
|
|
||||||
# Define all the Gem errors for gems that reference them.
|
# Define all the Gem errors for gems that reference them.
|
||||||
module Gem
|
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 LoadError < ::LoadError; end
|
||||||
class Exception < RuntimeError; end
|
class Exception < RuntimeError; end
|
||||||
class CommandLineError < Exception; 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
|