entp-astrotrain 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +26 -0
 - data/LICENSE +20 -0
 - data/README +47 -0
 - data/Rakefile +145 -0
 - data/VERSION +1 -0
 - data/astrotrain.gemspec +96 -0
 - data/config/sample.rb +12 -0
 - data/lib/astrotrain/api.rb +53 -0
 - data/lib/astrotrain/logged_mail.rb +41 -0
 - data/lib/astrotrain/mapping/http_post.rb +18 -0
 - data/lib/astrotrain/mapping/jabber.rb +23 -0
 - data/lib/astrotrain/mapping/transport.rb +55 -0
 - data/lib/astrotrain/mapping.rb +157 -0
 - data/lib/astrotrain/message.rb +313 -0
 - data/lib/astrotrain/tmail.rb +48 -0
 - data/lib/astrotrain.rb +55 -0
 - data/lib/vendor/rest-client/README.rdoc +104 -0
 - data/lib/vendor/rest-client/Rakefile +84 -0
 - data/lib/vendor/rest-client/bin/restclient +65 -0
 - data/lib/vendor/rest-client/foo.diff +66 -0
 - data/lib/vendor/rest-client/lib/rest_client/net_http_ext.rb +21 -0
 - data/lib/vendor/rest-client/lib/rest_client/payload.rb +185 -0
 - data/lib/vendor/rest-client/lib/rest_client/request_errors.rb +75 -0
 - data/lib/vendor/rest-client/lib/rest_client/resource.rb +103 -0
 - data/lib/vendor/rest-client/lib/rest_client.rb +189 -0
 - data/lib/vendor/rest-client/rest-client.gemspec +18 -0
 - data/lib/vendor/rest-client/spec/base.rb +5 -0
 - data/lib/vendor/rest-client/spec/master_shake.jpg +0 -0
 - data/lib/vendor/rest-client/spec/payload_spec.rb +71 -0
 - data/lib/vendor/rest-client/spec/request_errors_spec.rb +44 -0
 - data/lib/vendor/rest-client/spec/resource_spec.rb +52 -0
 - data/lib/vendor/rest-client/spec/rest_client_spec.rb +219 -0
 - data/tasks/doc.thor +149 -0
 - data/tasks/merb.thor +2020 -0
 - data/test/api_test.rb +28 -0
 - data/test/fixtures/apple_multipart.txt +100 -0
 - data/test/fixtures/basic.txt +14 -0
 - data/test/fixtures/custom.txt +15 -0
 - data/test/fixtures/fwd.txt +0 -0
 - data/test/fixtures/gb2312_encoding.txt +16 -0
 - data/test/fixtures/gb2312_encoding_invalid.txt +15 -0
 - data/test/fixtures/html.txt +16 -0
 - data/test/fixtures/iso-8859-1.txt +13 -0
 - data/test/fixtures/mapped.txt +13 -0
 - data/test/fixtures/multipart.txt +213 -0
 - data/test/fixtures/multipart2.txt +213 -0
 - data/test/fixtures/multiple.txt +13 -0
 - data/test/fixtures/multiple_delivered_to.txt +14 -0
 - data/test/fixtures/multiple_with_body_recipients.txt +15 -0
 - data/test/fixtures/reply.txt +16 -0
 - data/test/fixtures/utf-8.txt +13 -0
 - data/test/logged_mail_test.rb +63 -0
 - data/test/mapping_test.rb +129 -0
 - data/test/message_test.rb +424 -0
 - data/test/test_helper.rb +54 -0
 - data/test/transport_test.rb +111 -0
 - metadata +115 -0
 
| 
         @@ -0,0 +1,84 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rake'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'spec/rake/spectask'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            desc "Run all specs"
         
     | 
| 
      
 5 
     | 
    
         
            +
            Spec::Rake::SpecTask.new('spec') do |t|
         
     | 
| 
      
 6 
     | 
    
         
            +
            	t.spec_opts = ['--colour --format progress --loadby mtime --reverse']
         
     | 
| 
      
 7 
     | 
    
         
            +
            	t.spec_files = FileList['spec/*_spec.rb']
         
     | 
| 
      
 8 
     | 
    
         
            +
            end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            desc "Print specdocs"
         
     | 
| 
      
 11 
     | 
    
         
            +
            Spec::Rake::SpecTask.new(:doc) do |t|
         
     | 
| 
      
 12 
     | 
    
         
            +
            	t.spec_opts = ["--format", "specdoc", "--dry-run"]
         
     | 
| 
      
 13 
     | 
    
         
            +
            	t.spec_files = FileList['spec/*_spec.rb']
         
     | 
| 
      
 14 
     | 
    
         
            +
            end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            desc "Run all examples with RCov"
         
     | 
| 
      
 17 
     | 
    
         
            +
            Spec::Rake::SpecTask.new('rcov') do |t|
         
     | 
| 
      
 18 
     | 
    
         
            +
            	t.spec_files = FileList['spec/*_spec.rb']
         
     | 
| 
      
 19 
     | 
    
         
            +
            	t.rcov = true
         
     | 
| 
      
 20 
     | 
    
         
            +
            	t.rcov_opts = ['--exclude', 'examples']
         
     | 
| 
      
 21 
     | 
    
         
            +
            end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            task :default => :spec
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            ######################################################
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            require 'rake'
         
     | 
| 
      
 28 
     | 
    
         
            +
            require 'rake/testtask'
         
     | 
| 
      
 29 
     | 
    
         
            +
            require 'rake/clean'
         
     | 
| 
      
 30 
     | 
    
         
            +
            require 'rake/gempackagetask'
         
     | 
| 
      
 31 
     | 
    
         
            +
            require 'rake/rdoctask'
         
     | 
| 
      
 32 
     | 
    
         
            +
            require 'fileutils'
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
            version = "0.6.2"
         
     | 
| 
      
 35 
     | 
    
         
            +
            name = "rest-client"
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
            spec = Gem::Specification.new do |s|
         
     | 
| 
      
 38 
     | 
    
         
            +
            	s.name = name
         
     | 
| 
      
 39 
     | 
    
         
            +
            	s.version = version
         
     | 
| 
      
 40 
     | 
    
         
            +
            	s.summary = "Simple REST client for Ruby, inspired by microframework syntax for specifying actions."
         
     | 
| 
      
 41 
     | 
    
         
            +
            	s.description = "A simple REST client for Ruby, inspired by the Sinatra microframework style of specifying actions: get, put, post, delete."
         
     | 
| 
      
 42 
     | 
    
         
            +
            	s.author = "Adam Wiggins"
         
     | 
| 
      
 43 
     | 
    
         
            +
            	s.email = "adam@heroku.com"
         
     | 
| 
      
 44 
     | 
    
         
            +
            	s.homepage = "http://rest-client.heroku.com/"
         
     | 
| 
      
 45 
     | 
    
         
            +
            	s.rubyforge_project = "rest-client"
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
            	s.platform = Gem::Platform::RUBY
         
     | 
| 
      
 48 
     | 
    
         
            +
            	s.has_rdoc = true
         
     | 
| 
      
 49 
     | 
    
         
            +
            	
         
     | 
| 
      
 50 
     | 
    
         
            +
            	s.files = %w(Rakefile) + Dir.glob("{lib,spec}/**/*")
         
     | 
| 
      
 51 
     | 
    
         
            +
            	s.executables = ['restclient']
         
     | 
| 
      
 52 
     | 
    
         
            +
            	
         
     | 
| 
      
 53 
     | 
    
         
            +
            	s.require_path = "lib"
         
     | 
| 
      
 54 
     | 
    
         
            +
            end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
            Rake::GemPackageTask.new(spec) do |p|
         
     | 
| 
      
 57 
     | 
    
         
            +
            	p.need_tar = true if RUBY_PLATFORM !~ /mswin/
         
     | 
| 
      
 58 
     | 
    
         
            +
            end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
            task :install => [ :package ] do
         
     | 
| 
      
 61 
     | 
    
         
            +
            	sh %{sudo gem install pkg/#{name}-#{version}.gem}
         
     | 
| 
      
 62 
     | 
    
         
            +
            end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
            task :uninstall => [ :clean ] do
         
     | 
| 
      
 65 
     | 
    
         
            +
            	sh %{sudo gem uninstall #{name}}
         
     | 
| 
      
 66 
     | 
    
         
            +
            end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
            Rake::TestTask.new do |t|
         
     | 
| 
      
 69 
     | 
    
         
            +
            	t.libs << "spec"
         
     | 
| 
      
 70 
     | 
    
         
            +
            	t.test_files = FileList['spec/*_spec.rb']
         
     | 
| 
      
 71 
     | 
    
         
            +
            	t.verbose = true
         
     | 
| 
      
 72 
     | 
    
         
            +
            end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
            Rake::RDocTask.new do |t|
         
     | 
| 
      
 75 
     | 
    
         
            +
            	t.rdoc_dir = 'rdoc'
         
     | 
| 
      
 76 
     | 
    
         
            +
            	t.title    = "rest-client, fetch RESTful resources effortlessly"
         
     | 
| 
      
 77 
     | 
    
         
            +
            	t.options << '--line-numbers' << '--inline-source' << '-A cattr_accessor=object'
         
     | 
| 
      
 78 
     | 
    
         
            +
            	t.options << '--charset' << 'utf-8'
         
     | 
| 
      
 79 
     | 
    
         
            +
            	t.rdoc_files.include('README.rdoc')
         
     | 
| 
      
 80 
     | 
    
         
            +
            	t.rdoc_files.include('lib/*.rb')
         
     | 
| 
      
 81 
     | 
    
         
            +
            end
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
            CLEAN.include [ 'pkg', '*.gem', '.config' ]
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
         @@ -0,0 +1,65 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env ruby
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            $:.unshift File.dirname(__FILE__) + "/../lib"
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'rest_client'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            require "yaml"
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            def usage(why = nil)
         
     | 
| 
      
 9 
     | 
    
         
            +
            	puts "failed for reason: #{why}" if why
         
     | 
| 
      
 10 
     | 
    
         
            +
            	puts "usage: restclient url|name [username] [password]"
         
     | 
| 
      
 11 
     | 
    
         
            +
            	exit(1)
         
     | 
| 
      
 12 
     | 
    
         
            +
            end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            @url = ARGV.shift || 'http://localhost:4567'
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            config = YAML.load(File.read(ENV['HOME'] + "/.restclient")) rescue {}
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            @url, @username, @password = if c = config[@url]
         
     | 
| 
      
 19 
     | 
    
         
            +
            	[c['url'], c['username'], c['password']]
         
     | 
| 
      
 20 
     | 
    
         
            +
            else
         
     | 
| 
      
 21 
     | 
    
         
            +
            	[@url, *ARGV]
         
     | 
| 
      
 22 
     | 
    
         
            +
            end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            usage("invalid url '#{@url}") unless @url =~ /^https?/
         
     | 
| 
      
 25 
     | 
    
         
            +
            usage("to few args") unless ARGV.size < 3
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            def r
         
     | 
| 
      
 28 
     | 
    
         
            +
            	@r ||= RestClient::Resource.new(@url, @username, @password)
         
     | 
| 
      
 29 
     | 
    
         
            +
            end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            r # force rc to load
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
            %w(get post put delete).each do |m|
         
     | 
| 
      
 34 
     | 
    
         
            +
             eval <<-end_eval
         
     | 
| 
      
 35 
     | 
    
         
            +
            def #{m}(path, *args, &b)
         
     | 
| 
      
 36 
     | 
    
         
            +
            	r[path].#{m}(*args, &b)
         
     | 
| 
      
 37 
     | 
    
         
            +
            end
         
     | 
| 
      
 38 
     | 
    
         
            +
             end_eval
         
     | 
| 
      
 39 
     | 
    
         
            +
            end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
            def method_missing(s, *args, &b)
         
     | 
| 
      
 42 
     | 
    
         
            +
            	super unless r.respond_to?(s)
         
     | 
| 
      
 43 
     | 
    
         
            +
            	begin
         
     | 
| 
      
 44 
     | 
    
         
            +
            		r.send(s, *args, &b)
         
     | 
| 
      
 45 
     | 
    
         
            +
            	rescue RestClient::RequestFailed => e
         
     | 
| 
      
 46 
     | 
    
         
            +
            		puts e.response.body
         
     | 
| 
      
 47 
     | 
    
         
            +
            		raise e
         
     | 
| 
      
 48 
     | 
    
         
            +
            	end
         
     | 
| 
      
 49 
     | 
    
         
            +
            end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
            require 'irb'
         
     | 
| 
      
 52 
     | 
    
         
            +
            require 'irb/completion'
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
            if File.exists? ".irbrc"
         
     | 
| 
      
 55 
     | 
    
         
            +
            	ENV['IRBRC'] = ".irbrc"
         
     | 
| 
      
 56 
     | 
    
         
            +
            end
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
            if File.exists?(rcfile = "~/.restclientrc")
         
     | 
| 
      
 59 
     | 
    
         
            +
            	load(rcfile)
         
     | 
| 
      
 60 
     | 
    
         
            +
            end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
            ARGV.clear
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
            IRB.start
         
     | 
| 
      
 65 
     | 
    
         
            +
            exit!
         
     | 
| 
         @@ -0,0 +1,66 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            commit 1a1a16d6abda6b40091b49d3ad082400018e665b
         
     | 
| 
      
 2 
     | 
    
         
            +
            Author: rick <technoweenie@gmail.com>
         
     | 
| 
      
 3 
     | 
    
         
            +
            Date:   Wed Dec 10 20:01:02 2008 -0800
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                fix spacing issues with multipart bodies:
         
     | 
| 
      
 6 
     | 
    
         
            +
                 * the final boundary should be on a line below the final param's content.
         
     | 
| 
      
 7 
     | 
    
         
            +
                 * the ending double dash should be on the same line as the final boundary
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            diff --git a/lib/rest_client/payload.rb b/lib/rest_client/payload.rb
         
     | 
| 
      
 10 
     | 
    
         
            +
            index dfc2921..e896be0 100644
         
     | 
| 
      
 11 
     | 
    
         
            +
            --- a/lib/rest_client/payload.rb
         
     | 
| 
      
 12 
     | 
    
         
            +
            +++ b/lib/rest_client/payload.rb
         
     | 
| 
      
 13 
     | 
    
         
            +
            @@ -76,9 +76,10 @@ module RestClient
         
     | 
| 
      
 14 
     | 
    
         
            +
             					else
         
     | 
| 
      
 15 
     | 
    
         
            +
             						create_regular_field(@stream, k,v)
         
     | 
| 
      
 16 
     | 
    
         
            +
             					end
         
     | 
| 
      
 17 
     | 
    
         
            +
            -					@stream.write(b + EOL)
         
     | 
| 
      
 18 
     | 
    
         
            +
            +					@stream.write(EOL + b)
         
     | 
| 
      
 19 
     | 
    
         
            +
             				end
         
     | 
| 
      
 20 
     | 
    
         
            +
             				@stream.write('--')
         
     | 
| 
      
 21 
     | 
    
         
            +
            +				@stream.write(EOL)
         
     | 
| 
      
 22 
     | 
    
         
            +
             				@stream.seek(0)
         
     | 
| 
      
 23 
     | 
    
         
            +
             			end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
         
     | 
| 
      
 25 
     | 
    
         
            +
            diff --git a/spec/payload_spec.rb b/spec/payload_spec.rb
         
     | 
| 
      
 26 
     | 
    
         
            +
            index 22b5a5a..35564ee 100644
         
     | 
| 
      
 27 
     | 
    
         
            +
            --- a/spec/payload_spec.rb
         
     | 
| 
      
 28 
     | 
    
         
            +
            +++ b/spec/payload_spec.rb
         
     | 
| 
      
 29 
     | 
    
         
            +
            @@ -20,29 +20,27 @@ describe RestClient::Payload do
         
     | 
| 
      
 30 
     | 
    
         
            +
             			m.headers['Content-Type'].should == 'multipart/form-data; boundary="123"'
         
     | 
| 
      
 31 
     | 
    
         
            +
             		end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
         
     | 
| 
      
 33 
     | 
    
         
            +
            -		xit "should form properly seperated multipart data" do
         
     | 
| 
      
 34 
     | 
    
         
            +
            +		it "should form properly seperated multipart data" do
         
     | 
| 
      
 35 
     | 
    
         
            +
             			m = RestClient::Payload::Multipart.new({:foo => "bar"})
         
     | 
| 
      
 36 
     | 
    
         
            +
            -			m.stub!(:boundary).and_return("123")
         
     | 
| 
      
 37 
     | 
    
         
            +
             			m.to_s.should == <<-EOS
         
     | 
| 
      
 38 
     | 
    
         
            +
            ---123\r
         
     | 
| 
      
 39 
     | 
    
         
            +
            +--#{m.boundary}\r
         
     | 
| 
      
 40 
     | 
    
         
            +
             Content-Disposition: multipart/form-data; name="foo"\r
         
     | 
| 
      
 41 
     | 
    
         
            +
             \r
         
     | 
| 
      
 42 
     | 
    
         
            +
             bar\r
         
     | 
| 
      
 43 
     | 
    
         
            +
            ---123--\r
         
     | 
| 
      
 44 
     | 
    
         
            +
            +--#{m.boundary}--\r
         
     | 
| 
      
 45 
     | 
    
         
            +
             EOS
         
     | 
| 
      
 46 
     | 
    
         
            +
             		end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
         
     | 
| 
      
 48 
     | 
    
         
            +
            -		xit "should form properly seperated multipart data" do
         
     | 
| 
      
 49 
     | 
    
         
            +
            +		it "should form properly seperated multipart data" do
         
     | 
| 
      
 50 
     | 
    
         
            +
             			f = File.new(File.dirname(__FILE__) + "/master_shake.jpg")
         
     | 
| 
      
 51 
     | 
    
         
            +
             			m = RestClient::Payload::Multipart.new({:foo => f})
         
     | 
| 
      
 52 
     | 
    
         
            +
            -			m.stub!(:boundary).and_return("123")
         
     | 
| 
      
 53 
     | 
    
         
            +
             			m.to_s.should == <<-EOS
         
     | 
| 
      
 54 
     | 
    
         
            +
            ---123\r
         
     | 
| 
      
 55 
     | 
    
         
            +
            -Content-Disposition: multipart/form-data; name="foo"; filename="master_shake.jpg"\r
         
     | 
| 
      
 56 
     | 
    
         
            +
            +--#{m.boundary}\r
         
     | 
| 
      
 57 
     | 
    
         
            +
            +Content-Disposition: multipart/form-data; name="foo"; filename="./spec/master_shake.jpg"\r
         
     | 
| 
      
 58 
     | 
    
         
            +
             Content-Type: image/jpeg\r
         
     | 
| 
      
 59 
     | 
    
         
            +
             \r
         
     | 
| 
      
 60 
     | 
    
         
            +
            -datadatadata\r
         
     | 
| 
      
 61 
     | 
    
         
            +
            ---123--\r
         
     | 
| 
      
 62 
     | 
    
         
            +
            +#{IO.read(f.path)}\r
         
     | 
| 
      
 63 
     | 
    
         
            +
            +--#{m.boundary}--\r
         
     | 
| 
      
 64 
     | 
    
         
            +
             EOS
         
     | 
| 
      
 65 
     | 
    
         
            +
             		end
         
     | 
| 
      
 66 
     | 
    
         
            +
             	end
         
     | 
| 
         @@ -0,0 +1,21 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #
         
     | 
| 
      
 2 
     | 
    
         
            +
            # Replace the request method in Net::HTTP to sniff the body type
         
     | 
| 
      
 3 
     | 
    
         
            +
            # and set the stream if appropriate
         
     | 
| 
      
 4 
     | 
    
         
            +
            #
         
     | 
| 
      
 5 
     | 
    
         
            +
            # Taken from:	
         
     | 
| 
      
 6 
     | 
    
         
            +
            # http://www.missiondata.com/blog/ruby/29/streaming-data-to-s3-with-ruby/
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            module Net
         
     | 
| 
      
 9 
     | 
    
         
            +
            	class HTTP
         
     | 
| 
      
 10 
     | 
    
         
            +
            		alias __request__ request
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            		def request(req, body=nil, &block)
         
     | 
| 
      
 13 
     | 
    
         
            +
            			if body != nil && body.respond_to?(:read)
         
     | 
| 
      
 14 
     | 
    
         
            +
            				req.body_stream = body
         
     | 
| 
      
 15 
     | 
    
         
            +
            				return __request__(req, nil, &block)
         
     | 
| 
      
 16 
     | 
    
         
            +
            			else
         
     | 
| 
      
 17 
     | 
    
         
            +
            				return __request__(req, body, &block)
         
     | 
| 
      
 18 
     | 
    
         
            +
            			end
         
     | 
| 
      
 19 
     | 
    
         
            +
            		end
         
     | 
| 
      
 20 
     | 
    
         
            +
            	end
         
     | 
| 
      
 21 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,185 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "tempfile"
         
     | 
| 
      
 2 
     | 
    
         
            +
            require "stringio"
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module RestClient
         
     | 
| 
      
 5 
     | 
    
         
            +
            	module Payload
         
     | 
| 
      
 6 
     | 
    
         
            +
            		extend self
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            		def generate(params)
         
     | 
| 
      
 9 
     | 
    
         
            +
            			if params.is_a?(String)
         
     | 
| 
      
 10 
     | 
    
         
            +
            				Base.new(params)
         
     | 
| 
      
 11 
     | 
    
         
            +
            			elsif params.delete(:multipart) == true || 
         
     | 
| 
      
 12 
     | 
    
         
            +
            				params.any? { |_,v| v.respond_to?(:path) && v.respond_to?(:read) }
         
     | 
| 
      
 13 
     | 
    
         
            +
            				Multipart.new(params)
         
     | 
| 
      
 14 
     | 
    
         
            +
            			else
         
     | 
| 
      
 15 
     | 
    
         
            +
            				UrlEncoded.new(params)
         
     | 
| 
      
 16 
     | 
    
         
            +
            			end
         
     | 
| 
      
 17 
     | 
    
         
            +
            		end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            		class Base
         
     | 
| 
      
 20 
     | 
    
         
            +
            			def initialize(params)
         
     | 
| 
      
 21 
     | 
    
         
            +
            				build_stream(params)
         
     | 
| 
      
 22 
     | 
    
         
            +
            			end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            			def build_stream(params)
         
     | 
| 
      
 25 
     | 
    
         
            +
            				@stream = StringIO.new(params)
         
     | 
| 
      
 26 
     | 
    
         
            +
            				@stream.seek(0)
         
     | 
| 
      
 27 
     | 
    
         
            +
            			end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            			def read(bytes=nil)
         
     | 
| 
      
 30 
     | 
    
         
            +
            				@stream.read(bytes)
         
     | 
| 
      
 31 
     | 
    
         
            +
            			end
         
     | 
| 
      
 32 
     | 
    
         
            +
            			alias :to_s :read
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
            			def escape(v)
         
     | 
| 
      
 35 
     | 
    
         
            +
            				URI.escape(v.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
         
     | 
| 
      
 36 
     | 
    
         
            +
            			end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            			def headers
         
     | 
| 
      
 39 
     | 
    
         
            +
            				{ 'Content-Length' => size.to_s }
         
     | 
| 
      
 40 
     | 
    
         
            +
            			end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
            			def size
         
     | 
| 
      
 43 
     | 
    
         
            +
            				@stream.size
         
     | 
| 
      
 44 
     | 
    
         
            +
            			end
         
     | 
| 
      
 45 
     | 
    
         
            +
            			alias :length :size
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
            			def close
         
     | 
| 
      
 48 
     | 
    
         
            +
            				@stream.close
         
     | 
| 
      
 49 
     | 
    
         
            +
            			end
         
     | 
| 
      
 50 
     | 
    
         
            +
            		end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
            		class UrlEncoded < Base
         
     | 
| 
      
 53 
     | 
    
         
            +
            			def build_stream(params)
         
     | 
| 
      
 54 
     | 
    
         
            +
            				@stream = StringIO.new(params.map do |k,v| 
         
     | 
| 
      
 55 
     | 
    
         
            +
            					"#{escape(k)}=#{escape(v)}"
         
     | 
| 
      
 56 
     | 
    
         
            +
            				end.join("&"))
         
     | 
| 
      
 57 
     | 
    
         
            +
            				@stream.seek(0)
         
     | 
| 
      
 58 
     | 
    
         
            +
            			end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
            			def headers
         
     | 
| 
      
 61 
     | 
    
         
            +
            				super.merge({ 'Content-Type' => 'application/x-www-form-urlencoded' })
         
     | 
| 
      
 62 
     | 
    
         
            +
            			end
         
     | 
| 
      
 63 
     | 
    
         
            +
            		end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
            		class Multipart < Base
         
     | 
| 
      
 66 
     | 
    
         
            +
            			EOL = "\r\n"
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
            			def build_stream(params)
         
     | 
| 
      
 69 
     | 
    
         
            +
            				b = "--#{boundary}"
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
            				@stream = Tempfile.new("RESTClient.Stream.#{rand(1000)}")
         
     | 
| 
      
 72 
     | 
    
         
            +
            				@stream.write(b)
         
     | 
| 
      
 73 
     | 
    
         
            +
            				params.each do |k,v|
         
     | 
| 
      
 74 
     | 
    
         
            +
            				  @stream.write(EOL)
         
     | 
| 
      
 75 
     | 
    
         
            +
            					if v.respond_to?(:read) && v.respond_to?(:path)
         
     | 
| 
      
 76 
     | 
    
         
            +
            						create_file_field(@stream, k,v)
         
     | 
| 
      
 77 
     | 
    
         
            +
            					else
         
     | 
| 
      
 78 
     | 
    
         
            +
            						create_regular_field(@stream, k,v)
         
     | 
| 
      
 79 
     | 
    
         
            +
            					end
         
     | 
| 
      
 80 
     | 
    
         
            +
            					@stream.write(EOL + b)
         
     | 
| 
      
 81 
     | 
    
         
            +
            				end
         
     | 
| 
      
 82 
     | 
    
         
            +
            				@stream.write('--')
         
     | 
| 
      
 83 
     | 
    
         
            +
            				@stream.write(EOL)
         
     | 
| 
      
 84 
     | 
    
         
            +
            				@stream.seek(0)
         
     | 
| 
      
 85 
     | 
    
         
            +
            			end
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
            			def create_regular_field(s, k, v)
         
     | 
| 
      
 88 
     | 
    
         
            +
            				s.write("Content-Disposition: multipart/form-data; name=\"#{k}\"")
         
     | 
| 
      
 89 
     | 
    
         
            +
            				s.write(EOL)
         
     | 
| 
      
 90 
     | 
    
         
            +
            				s.write(EOL)
         
     | 
| 
      
 91 
     | 
    
         
            +
            				s.write(v)
         
     | 
| 
      
 92 
     | 
    
         
            +
            			end
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
            			def create_file_field(s, k, v)
         
     | 
| 
      
 95 
     | 
    
         
            +
            				begin
         
     | 
| 
      
 96 
     | 
    
         
            +
            					s.write("Content-Disposition: multipart/form-data; name=\"#{k}\"; filename=\"#{v.path}\"#{EOL}")
         
     | 
| 
      
 97 
     | 
    
         
            +
            					s.write("Content-Type: #{mime_for(v.path)}#{EOL}")
         
     | 
| 
      
 98 
     | 
    
         
            +
            					s.write(EOL)
         
     | 
| 
      
 99 
     | 
    
         
            +
            					while data = v.read(8124)
         
     | 
| 
      
 100 
     | 
    
         
            +
            						s.write(data)
         
     | 
| 
      
 101 
     | 
    
         
            +
            					end
         
     | 
| 
      
 102 
     | 
    
         
            +
            				ensure
         
     | 
| 
      
 103 
     | 
    
         
            +
            					v.close
         
     | 
| 
      
 104 
     | 
    
         
            +
            				end
         
     | 
| 
      
 105 
     | 
    
         
            +
            			end
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
            			def mime_for(path)
         
     | 
| 
      
 108 
     | 
    
         
            +
            				ext = File.extname(path)[1..-1]
         
     | 
| 
      
 109 
     | 
    
         
            +
            				MIME_TYPES[ext] || 'text/plain'
         
     | 
| 
      
 110 
     | 
    
         
            +
            			end
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
            			def boundary
         
     | 
| 
      
 113 
     | 
    
         
            +
            				@boundary ||= rand(1_000_000).to_s
         
     | 
| 
      
 114 
     | 
    
         
            +
            			end
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
            			def headers
         
     | 
| 
      
 117 
     | 
    
         
            +
            				super.merge({'Content-Type' => %Q{multipart/form-data; boundary="#{boundary}"}})
         
     | 
| 
      
 118 
     | 
    
         
            +
            			end
         
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
      
 120 
     | 
    
         
            +
            			def close
         
     | 
| 
      
 121 
     | 
    
         
            +
            				@stream.close
         
     | 
| 
      
 122 
     | 
    
         
            +
            			end
         
     | 
| 
      
 123 
     | 
    
         
            +
            		end
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
      
 125 
     | 
    
         
            +
            		# :stopdoc:
         
     | 
| 
      
 126 
     | 
    
         
            +
            		# From WEBrick.
         
     | 
| 
      
 127 
     | 
    
         
            +
            		MIME_TYPES = {
         
     | 
| 
      
 128 
     | 
    
         
            +
            			"ai"    => "application/postscript",
         
     | 
| 
      
 129 
     | 
    
         
            +
            			"asc"   => "text/plain",
         
     | 
| 
      
 130 
     | 
    
         
            +
            			"avi"   => "video/x-msvideo",
         
     | 
| 
      
 131 
     | 
    
         
            +
            			"bin"   => "application/octet-stream",
         
     | 
| 
      
 132 
     | 
    
         
            +
            			"bmp"   => "image/bmp",
         
     | 
| 
      
 133 
     | 
    
         
            +
            			"class" => "application/octet-stream",
         
     | 
| 
      
 134 
     | 
    
         
            +
            			"cer"   => "application/pkix-cert",
         
     | 
| 
      
 135 
     | 
    
         
            +
            			"crl"   => "application/pkix-crl",
         
     | 
| 
      
 136 
     | 
    
         
            +
            			"crt"   => "application/x-x509-ca-cert",
         
     | 
| 
      
 137 
     | 
    
         
            +
            			"css"   => "text/css",
         
     | 
| 
      
 138 
     | 
    
         
            +
            			"dms"   => "application/octet-stream",
         
     | 
| 
      
 139 
     | 
    
         
            +
            			"doc"   => "application/msword",
         
     | 
| 
      
 140 
     | 
    
         
            +
            			"dvi"   => "application/x-dvi",
         
     | 
| 
      
 141 
     | 
    
         
            +
            			"eps"   => "application/postscript",
         
     | 
| 
      
 142 
     | 
    
         
            +
            			"etx"   => "text/x-setext",
         
     | 
| 
      
 143 
     | 
    
         
            +
            			"exe"   => "application/octet-stream",
         
     | 
| 
      
 144 
     | 
    
         
            +
            			"gif"   => "image/gif",
         
     | 
| 
      
 145 
     | 
    
         
            +
            			"gz"   => "application/x-gzip",
         
     | 
| 
      
 146 
     | 
    
         
            +
            			"htm"   => "text/html",
         
     | 
| 
      
 147 
     | 
    
         
            +
            			"html"  => "text/html",
         
     | 
| 
      
 148 
     | 
    
         
            +
            			"jpe"   => "image/jpeg",
         
     | 
| 
      
 149 
     | 
    
         
            +
            			"jpeg"  => "image/jpeg",
         
     | 
| 
      
 150 
     | 
    
         
            +
            			"jpg"   => "image/jpeg",
         
     | 
| 
      
 151 
     | 
    
         
            +
            			"js"    => "text/javascript",
         
     | 
| 
      
 152 
     | 
    
         
            +
            			"lha"   => "application/octet-stream",
         
     | 
| 
      
 153 
     | 
    
         
            +
            			"lzh"   => "application/octet-stream",
         
     | 
| 
      
 154 
     | 
    
         
            +
            			"mov"   => "video/quicktime",
         
     | 
| 
      
 155 
     | 
    
         
            +
            			"mpe"   => "video/mpeg",
         
     | 
| 
      
 156 
     | 
    
         
            +
            			"mpeg"  => "video/mpeg",
         
     | 
| 
      
 157 
     | 
    
         
            +
            			"mpg"   => "video/mpeg",
         
     | 
| 
      
 158 
     | 
    
         
            +
            			"pbm"   => "image/x-portable-bitmap",
         
     | 
| 
      
 159 
     | 
    
         
            +
            			"pdf"   => "application/pdf",
         
     | 
| 
      
 160 
     | 
    
         
            +
            			"pgm"   => "image/x-portable-graymap",
         
     | 
| 
      
 161 
     | 
    
         
            +
            			"png"   => "image/png",
         
     | 
| 
      
 162 
     | 
    
         
            +
            			"pnm"   => "image/x-portable-anymap",
         
     | 
| 
      
 163 
     | 
    
         
            +
            			"ppm"   => "image/x-portable-pixmap",
         
     | 
| 
      
 164 
     | 
    
         
            +
            			"ppt"   => "application/vnd.ms-powerpoint",
         
     | 
| 
      
 165 
     | 
    
         
            +
            			"ps"    => "application/postscript",
         
     | 
| 
      
 166 
     | 
    
         
            +
            			"qt"    => "video/quicktime",
         
     | 
| 
      
 167 
     | 
    
         
            +
            			"ras"   => "image/x-cmu-raster",
         
     | 
| 
      
 168 
     | 
    
         
            +
            			"rb"    => "text/plain",
         
     | 
| 
      
 169 
     | 
    
         
            +
            			"rd"    => "text/plain",
         
     | 
| 
      
 170 
     | 
    
         
            +
            			"rtf"   => "application/rtf",
         
     | 
| 
      
 171 
     | 
    
         
            +
            			"sgm"   => "text/sgml",
         
     | 
| 
      
 172 
     | 
    
         
            +
            			"sgml"  => "text/sgml",
         
     | 
| 
      
 173 
     | 
    
         
            +
            			"tif"   => "image/tiff",
         
     | 
| 
      
 174 
     | 
    
         
            +
            			"tiff"  => "image/tiff",
         
     | 
| 
      
 175 
     | 
    
         
            +
            			"txt"   => "text/plain",
         
     | 
| 
      
 176 
     | 
    
         
            +
            			"xbm"   => "image/x-xbitmap",
         
     | 
| 
      
 177 
     | 
    
         
            +
            			"xls"   => "application/vnd.ms-excel",
         
     | 
| 
      
 178 
     | 
    
         
            +
            			"xml"   => "text/xml",
         
     | 
| 
      
 179 
     | 
    
         
            +
            			"xpm"   => "image/x-xpixmap",
         
     | 
| 
      
 180 
     | 
    
         
            +
            			"xwd"   => "image/x-xwindowdump",
         
     | 
| 
      
 181 
     | 
    
         
            +
            			"zip"   => "application/zip",
         
     | 
| 
      
 182 
     | 
    
         
            +
            		}
         
     | 
| 
      
 183 
     | 
    
         
            +
            		# :startdoc:
         
     | 
| 
      
 184 
     | 
    
         
            +
            	end
         
     | 
| 
      
 185 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,75 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module RestClient
         
     | 
| 
      
 2 
     | 
    
         
            +
            	# This is the base RestClient exception class. Rescue it if you want to
         
     | 
| 
      
 3 
     | 
    
         
            +
            	# catch any exception that your request might raise
         
     | 
| 
      
 4 
     | 
    
         
            +
            	class Exception < RuntimeError
         
     | 
| 
      
 5 
     | 
    
         
            +
            		def message(default=nil)
         
     | 
| 
      
 6 
     | 
    
         
            +
            			self.class::ErrorMessage
         
     | 
| 
      
 7 
     | 
    
         
            +
            		end
         
     | 
| 
      
 8 
     | 
    
         
            +
            	end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            	# A redirect was encountered; caught by execute to retry with the new url.
         
     | 
| 
      
 11 
     | 
    
         
            +
            	class Redirect < Exception
         
     | 
| 
      
 12 
     | 
    
         
            +
            		ErrorMessage = "Redirect"
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            		attr_accessor :url
         
     | 
| 
      
 15 
     | 
    
         
            +
            		def initialize(url)
         
     | 
| 
      
 16 
     | 
    
         
            +
            			@url = url
         
     | 
| 
      
 17 
     | 
    
         
            +
            		end
         
     | 
| 
      
 18 
     | 
    
         
            +
            	end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            	# Authorization is required to access the resource specified.
         
     | 
| 
      
 21 
     | 
    
         
            +
            	class Unauthorized < Exception
         
     | 
| 
      
 22 
     | 
    
         
            +
            		ErrorMessage = 'Unauthorized'
         
     | 
| 
      
 23 
     | 
    
         
            +
            	end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            	# No resource was found at the given URL.
         
     | 
| 
      
 26 
     | 
    
         
            +
            	class ResourceNotFound < Exception
         
     | 
| 
      
 27 
     | 
    
         
            +
            		ErrorMessage = 'Resource not found'
         
     | 
| 
      
 28 
     | 
    
         
            +
            	end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
            	# The server broke the connection prior to the request completing.
         
     | 
| 
      
 31 
     | 
    
         
            +
            	class ServerBrokeConnection < Exception
         
     | 
| 
      
 32 
     | 
    
         
            +
            		ErrorMessage = 'Server broke connection'
         
     | 
| 
      
 33 
     | 
    
         
            +
            	end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
            	# The server took too long to respond.
         
     | 
| 
      
 36 
     | 
    
         
            +
            	class RequestTimeout < Exception
         
     | 
| 
      
 37 
     | 
    
         
            +
            		ErrorMessage = 'Request timed out'
         
     | 
| 
      
 38 
     | 
    
         
            +
            	end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
            	# The request failed, meaning the remote HTTP server returned a code other
         
     | 
| 
      
 41 
     | 
    
         
            +
            	# than success, unauthorized, or redirect.
         
     | 
| 
      
 42 
     | 
    
         
            +
            	#
         
     | 
| 
      
 43 
     | 
    
         
            +
            	# The exception message attempts to extract the error from the XML, using
         
     | 
| 
      
 44 
     | 
    
         
            +
            	# format returned by Rails: <errors><error>some message</error></errors>
         
     | 
| 
      
 45 
     | 
    
         
            +
            	#
         
     | 
| 
      
 46 
     | 
    
         
            +
            	# You can get the status code by e.http_code, or see anything about the
         
     | 
| 
      
 47 
     | 
    
         
            +
            	# response via e.response.  For example, the entire result body (which is
         
     | 
| 
      
 48 
     | 
    
         
            +
            	# probably an HTML error page) is e.response.body.
         
     | 
| 
      
 49 
     | 
    
         
            +
            	class RequestFailed < Exception
         
     | 
| 
      
 50 
     | 
    
         
            +
            		attr_accessor :response
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
            		def initialize(response=nil)
         
     | 
| 
      
 53 
     | 
    
         
            +
            			@response = response
         
     | 
| 
      
 54 
     | 
    
         
            +
            		end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
            		def http_code
         
     | 
| 
      
 57 
     | 
    
         
            +
            			@response.code.to_i if @response
         
     | 
| 
      
 58 
     | 
    
         
            +
            		end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
            		def message
         
     | 
| 
      
 61 
     | 
    
         
            +
            			"HTTP status code #{http_code}"
         
     | 
| 
      
 62 
     | 
    
         
            +
            		end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
            		def to_s
         
     | 
| 
      
 65 
     | 
    
         
            +
            			message
         
     | 
| 
      
 66 
     | 
    
         
            +
            		end
         
     | 
| 
      
 67 
     | 
    
         
            +
            	end
         
     | 
| 
      
 68 
     | 
    
         
            +
            end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
            # backwards compatibility
         
     | 
| 
      
 71 
     | 
    
         
            +
            class RestClient::Request
         
     | 
| 
      
 72 
     | 
    
         
            +
            	Redirect = RestClient::Redirect
         
     | 
| 
      
 73 
     | 
    
         
            +
            	Unauthorized = RestClient::Unauthorized
         
     | 
| 
      
 74 
     | 
    
         
            +
            	RequestFailed = RestClient::RequestFailed
         
     | 
| 
      
 75 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,103 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module RestClient
         
     | 
| 
      
 2 
     | 
    
         
            +
            	# A class that can be instantiated for access to a RESTful resource,
         
     | 
| 
      
 3 
     | 
    
         
            +
            	# including authentication.
         
     | 
| 
      
 4 
     | 
    
         
            +
            	#
         
     | 
| 
      
 5 
     | 
    
         
            +
            	# Example:
         
     | 
| 
      
 6 
     | 
    
         
            +
            	#
         
     | 
| 
      
 7 
     | 
    
         
            +
            	#   resource = RestClient::Resource.new('http://some/resource')
         
     | 
| 
      
 8 
     | 
    
         
            +
            	#   jpg = resource.get(:accept => 'image/jpg')
         
     | 
| 
      
 9 
     | 
    
         
            +
            	#
         
     | 
| 
      
 10 
     | 
    
         
            +
            	# With HTTP basic authentication:
         
     | 
| 
      
 11 
     | 
    
         
            +
            	#
         
     | 
| 
      
 12 
     | 
    
         
            +
            	#   resource = RestClient::Resource.new('http://protected/resource', 'user', 'pass')
         
     | 
| 
      
 13 
     | 
    
         
            +
            	#   resource.delete
         
     | 
| 
      
 14 
     | 
    
         
            +
            	#
         
     | 
| 
      
 15 
     | 
    
         
            +
            	# Use the [] syntax to allocate subresources:
         
     | 
| 
      
 16 
     | 
    
         
            +
            	#
         
     | 
| 
      
 17 
     | 
    
         
            +
            	#   site = RestClient::Resource.new('http://example.com', 'adam', 'mypasswd')
         
     | 
| 
      
 18 
     | 
    
         
            +
            	#   site['posts/1/comments'].post 'Good article.', :content_type => 'text/plain'
         
     | 
| 
      
 19 
     | 
    
         
            +
            	#
         
     | 
| 
      
 20 
     | 
    
         
            +
            	class Resource
         
     | 
| 
      
 21 
     | 
    
         
            +
            		attr_reader :url, :user, :password
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            		def initialize(url, user=nil, password=nil)
         
     | 
| 
      
 24 
     | 
    
         
            +
            			@url = url
         
     | 
| 
      
 25 
     | 
    
         
            +
            			@user = user
         
     | 
| 
      
 26 
     | 
    
         
            +
            			@password = password
         
     | 
| 
      
 27 
     | 
    
         
            +
            		end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            		def get(headers={}, &b)
         
     | 
| 
      
 30 
     | 
    
         
            +
            			Request.execute(:method => :get,
         
     | 
| 
      
 31 
     | 
    
         
            +
            				:url => url,
         
     | 
| 
      
 32 
     | 
    
         
            +
            				:user => user,
         
     | 
| 
      
 33 
     | 
    
         
            +
            				:password => password,
         
     | 
| 
      
 34 
     | 
    
         
            +
            				:headers => headers, &b)
         
     | 
| 
      
 35 
     | 
    
         
            +
            		end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
            		def post(payload, headers={}, &b)
         
     | 
| 
      
 38 
     | 
    
         
            +
            			Request.execute(:method => :post,
         
     | 
| 
      
 39 
     | 
    
         
            +
            				:url => url,
         
     | 
| 
      
 40 
     | 
    
         
            +
            				:payload => payload,
         
     | 
| 
      
 41 
     | 
    
         
            +
            				:user => user,
         
     | 
| 
      
 42 
     | 
    
         
            +
            				:password => password,
         
     | 
| 
      
 43 
     | 
    
         
            +
            				:headers => headers, &b)
         
     | 
| 
      
 44 
     | 
    
         
            +
            		end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
            		def put(payload, headers={}, &b)
         
     | 
| 
      
 47 
     | 
    
         
            +
            			Request.execute(:method => :put,
         
     | 
| 
      
 48 
     | 
    
         
            +
            				:url => url,
         
     | 
| 
      
 49 
     | 
    
         
            +
            				:payload => payload,
         
     | 
| 
      
 50 
     | 
    
         
            +
            				:user => user,
         
     | 
| 
      
 51 
     | 
    
         
            +
            				:password => password,
         
     | 
| 
      
 52 
     | 
    
         
            +
            				:headers => headers, &b)
         
     | 
| 
      
 53 
     | 
    
         
            +
            		end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
            		def delete(headers={}, &b)
         
     | 
| 
      
 56 
     | 
    
         
            +
            			Request.execute(:method => :delete,
         
     | 
| 
      
 57 
     | 
    
         
            +
            				:url => url,
         
     | 
| 
      
 58 
     | 
    
         
            +
            				:user => user,
         
     | 
| 
      
 59 
     | 
    
         
            +
            				:password => password,
         
     | 
| 
      
 60 
     | 
    
         
            +
            				:headers => headers, &b)
         
     | 
| 
      
 61 
     | 
    
         
            +
            		end
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
            		# Construct a subresource, preserving authentication.
         
     | 
| 
      
 64 
     | 
    
         
            +
            		#
         
     | 
| 
      
 65 
     | 
    
         
            +
            		# Example:
         
     | 
| 
      
 66 
     | 
    
         
            +
            		#
         
     | 
| 
      
 67 
     | 
    
         
            +
            		#   site = RestClient::Resource.new('http://example.com', 'adam', 'mypasswd')
         
     | 
| 
      
 68 
     | 
    
         
            +
            		#   site['posts/1/comments'].post 'Good article.', :content_type => 'text/plain'
         
     | 
| 
      
 69 
     | 
    
         
            +
            		#
         
     | 
| 
      
 70 
     | 
    
         
            +
            		# This is especially useful if you wish to define your site in one place and
         
     | 
| 
      
 71 
     | 
    
         
            +
            		# call it in multiple locations:
         
     | 
| 
      
 72 
     | 
    
         
            +
            		#
         
     | 
| 
      
 73 
     | 
    
         
            +
            		#   def orders
         
     | 
| 
      
 74 
     | 
    
         
            +
            		#     RestClient::Resource.new('http://example.com/orders', 'admin', 'mypasswd')
         
     | 
| 
      
 75 
     | 
    
         
            +
            		#   end
         
     | 
| 
      
 76 
     | 
    
         
            +
            		#
         
     | 
| 
      
 77 
     | 
    
         
            +
            		#   orders.get                     # GET http://example.com/orders
         
     | 
| 
      
 78 
     | 
    
         
            +
            		#   orders['1'].get                # GET http://example.com/orders/1
         
     | 
| 
      
 79 
     | 
    
         
            +
            		#   orders['1/items'].delete       # DELETE http://example.com/orders/1/items
         
     | 
| 
      
 80 
     | 
    
         
            +
            		#
         
     | 
| 
      
 81 
     | 
    
         
            +
            		# Nest resources as far as you want:
         
     | 
| 
      
 82 
     | 
    
         
            +
            		#
         
     | 
| 
      
 83 
     | 
    
         
            +
            		#   site = RestClient::Resource.new('http://example.com')
         
     | 
| 
      
 84 
     | 
    
         
            +
            		#   posts = site['posts']
         
     | 
| 
      
 85 
     | 
    
         
            +
            		#   first_post = posts['1']
         
     | 
| 
      
 86 
     | 
    
         
            +
            		#   comments = first_post['comments']
         
     | 
| 
      
 87 
     | 
    
         
            +
            		#   comments.post 'Hello', :content_type => 'text/plain'
         
     | 
| 
      
 88 
     | 
    
         
            +
            		#
         
     | 
| 
      
 89 
     | 
    
         
            +
            		def [](suburl)
         
     | 
| 
      
 90 
     | 
    
         
            +
            			self.class.new(concat_urls(url, suburl), user, password)
         
     | 
| 
      
 91 
     | 
    
         
            +
            		end
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
            		def concat_urls(url, suburl)   # :nodoc:
         
     | 
| 
      
 94 
     | 
    
         
            +
            			url = url.to_s
         
     | 
| 
      
 95 
     | 
    
         
            +
            			suburl = suburl.to_s
         
     | 
| 
      
 96 
     | 
    
         
            +
            			if url.slice(-1, 1) == '/' or suburl.slice(0, 1) == '/'
         
     | 
| 
      
 97 
     | 
    
         
            +
            				url + suburl
         
     | 
| 
      
 98 
     | 
    
         
            +
            			else
         
     | 
| 
      
 99 
     | 
    
         
            +
            				"#{url}/#{suburl}"
         
     | 
| 
      
 100 
     | 
    
         
            +
            			end
         
     | 
| 
      
 101 
     | 
    
         
            +
            		end
         
     | 
| 
      
 102 
     | 
    
         
            +
            	end
         
     | 
| 
      
 103 
     | 
    
         
            +
            end
         
     |