thomaskay-curb-fu 0.2.2

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.
@@ -0,0 +1,5 @@
1
+ module CurbFu
2
+ module Authentication
3
+ BASIC = Curl::CURLAUTH_BASIC
4
+ end
5
+ end
@@ -0,0 +1,59 @@
1
+ require 'cgi'
2
+
3
+ ##
4
+ # ActiveSupport look alike for to_param. Very useful.
5
+ module CurbFu
6
+ module HashExtensions
7
+ def self.included(base)
8
+ base.send(:include, InstanceMethods) unless base.methods.include?(:to_param)
9
+ #base.extend(ClassMethods)
10
+ end
11
+
12
+ module InstanceMethods
13
+ def to_param(prefix)
14
+ collect do |k, v|
15
+ key_prefix = prefix ? "#{prefix}[#{k}]" : k
16
+ v.to_param(key_prefix)
17
+ end.join("&")
18
+ end
19
+ end
20
+ end
21
+
22
+ module ObjectExtensions
23
+ def self.included(base)
24
+ base.send(:include, InstanceMethods) unless base.methods.include?(:to_param)
25
+ #base.extend(ClassMethods)
26
+ end
27
+
28
+ module InstanceMethods
29
+ def to_param(prefix)
30
+ value = CGI::escape(to_s)
31
+ "#{prefix}=#{value}"
32
+ end
33
+ end
34
+ end
35
+
36
+ module ArrayExtensions
37
+ def self.included(base)
38
+ base.send(:include, InstanceMethods) unless base.methods.include?(:to_param)
39
+ #base.extend(ClassMethods)
40
+ end
41
+
42
+ module InstanceMethods
43
+ def to_param(prefix)
44
+ prefix = "#{prefix}[]"
45
+ collect { |item| "#{item.to_param(prefix)}" }.join('&')
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ class Hash
52
+ include CurbFu::HashExtensions
53
+ end
54
+ class Array
55
+ include CurbFu::ArrayExtensions
56
+ end
57
+ class Object
58
+ include CurbFu::ObjectExtensions
59
+ end
@@ -0,0 +1,104 @@
1
+ module CurbFu
2
+ class Request
3
+ module Base
4
+ include Common
5
+
6
+ def build(url_params, query_params = {})
7
+ curb = Curl::Easy.new(build_url(url_params, query_params))
8
+ unless url_params.is_a?(String)
9
+ curb.userpwd = "#{url_params[:username]}:#{url_params[:password]}" if url_params[:username]
10
+ if url_params[:authtype]
11
+ curb.http_auth_types = url_params[:authtype]
12
+ elsif url_params[:username]
13
+ curb.http_auth_types = CurbFu::Authentication::BASIC
14
+ end
15
+
16
+ curb.headers = url_params[:headers] || {}
17
+ end
18
+
19
+ curb.timeout = @timeout
20
+
21
+ curb
22
+ end
23
+
24
+ def get(url, params = {})
25
+ curb = self.build(url, params)
26
+ curb.http_get
27
+ CurbFu::Response::Base.from_curb_response(curb)
28
+ end
29
+
30
+ def put(url, params = {})
31
+ fields = create_put_fields(params)
32
+
33
+ curb = self.build(url)
34
+ curb.http_put(fields)
35
+ CurbFu::Response::Base.from_curb_response(curb)
36
+ end
37
+
38
+ def post(url, params = {})
39
+ fields = create_post_fields(params)
40
+
41
+ curb = self.build(url)
42
+ curb.headers["Expect:"] = ''
43
+ curb.http_post(*fields)
44
+ CurbFu::Response::Base.from_curb_response(curb)
45
+ end
46
+
47
+ def post_file(url, params = {}, filez = {})
48
+ fields = create_post_fields(params)
49
+ fields += create_file_fields(filez)
50
+
51
+ curb = self.build(url)
52
+ curb.multipart_form_post = true
53
+ curb.http_post(*fields)
54
+ CurbFu::Response::Base.from_curb_response(curb)
55
+ end
56
+
57
+ def delete(url)
58
+ curb = self.build(url)
59
+ curb.http_delete
60
+ CurbFu::Response::Base.from_curb_response(curb)
61
+ end
62
+
63
+ private
64
+ def create_post_fields(params)
65
+ return params if params.is_a? String
66
+
67
+ fields = []
68
+ params.each do |name, value|
69
+ value_string = value if value.is_a?(String)
70
+ value_string = value.join(',') if value.is_a?(Array)
71
+ value_string ||= value.to_s
72
+
73
+ fields << Curl::PostField.content(name,value_string)
74
+ end
75
+ return fields
76
+ end
77
+
78
+ def create_put_fields(params)
79
+ return params if params.is_a? String
80
+
81
+ params.inject([]) do |list, (k,v)|
82
+ v = v.is_a?(Array) ? v.join(',') : v
83
+ list << "#{k}=#{v}"
84
+ list
85
+ end.join('&')
86
+ end
87
+
88
+ def create_file_fields(filez)
89
+ fields = []
90
+ filez.each do |name, data|
91
+ if data.instance_of?File
92
+ fields << Curl::PostField.file(name, data.path)
93
+ else
94
+ post_field = Curl::PostField.content(name, data.read)
95
+ post_field.remote_file = data.original_filename
96
+ post_field.content_type = 'application/octet-stream'
97
+ fields << post_field
98
+ end
99
+ end
100
+ fields
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,32 @@
1
+ module CurbFu
2
+ class Request
3
+ module Common
4
+ def timeout=(val)
5
+ @timeout = val
6
+ end
7
+
8
+ def timeout
9
+ @timeout.nil? ? 60 : @timeout
10
+ end
11
+
12
+ def build_url(url_params, query_params = {})
13
+ if url_params.is_a? String
14
+ built_url = url_params
15
+ else
16
+ built_url = "http://#{url_params[:host]}"
17
+ built_url += ":" + url_params[:port].to_s if url_params[:port]
18
+ built_url += url_params[:path] if url_params[:path]
19
+ end
20
+ if query_params.is_a? String
21
+ built_url += query_params
22
+ elsif !query_params.empty?
23
+ built_url += "?"
24
+ built_url += query_params.collect do |name, value|
25
+ CurbFu::Request::Parameter.new(name, value).to_uri_param
26
+ end.join('&')
27
+ end
28
+ built_url
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,33 @@
1
+ module CurbFu
2
+ class Request
3
+ class Parameter
4
+ attr_accessor :name, :value
5
+
6
+ def initialize(name, value)
7
+ self.name = name
8
+ self.value = value
9
+ end
10
+
11
+ def self.build_uri_params(param_hash)
12
+ param_hash.to_param
13
+ end
14
+
15
+ def self.build_post_fields(param_hash)
16
+ param_hash.to_post_fields
17
+ end
18
+
19
+ def to_uri_param
20
+ value.to_param(name)
21
+ end
22
+
23
+ def to_curl_post_field
24
+ field_string = value.to_param(name)
25
+ fields = field_string.split('&').collect do |field_value_pair|
26
+ field_name, field_value = field_value_pair.split('=')
27
+ Curl::PostField.content(field_name, CGI::unescape(field_value))
28
+ end
29
+ fields.length == 1 ? fields[0] : fields
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,119 @@
1
+ require 'rack/test'
2
+
3
+ module CurbFu
4
+ class Request
5
+ module Test
6
+ include Common
7
+
8
+ def self.included(target)
9
+ target.extend(ClassMethods)
10
+ end
11
+
12
+ module ClassMethods
13
+ def get(url, params = {})
14
+ request_options = build_request_options(url)
15
+ respond(request_options[:interface], :get, request_options[:url],
16
+ params, request_options[:headers], request_options[:username], request_options[:password])
17
+ end
18
+
19
+ def post(url, params = {})
20
+ request_options = build_request_options(url)
21
+ respond(request_options[:interface], :post, request_options[:url],
22
+ params, request_options[:headers], request_options[:username], request_options[:password])
23
+ end
24
+
25
+ def post_file(url, params = {}, filez = {})
26
+ request_options = build_request_options(url)
27
+ uploaded_files = filez.inject({}) { |hsh, f| hsh["file_#{hsh.keys.length}"] = Rack::Test::UploadedFile.new(f.last.path); hsh }
28
+ respond(request_options[:interface], :post, request_options[:url],
29
+ params.merge(uploaded_files), request_options[:headers], request_options[:username], request_options[:password])
30
+ end
31
+
32
+ def put(url, params = {})
33
+ request_options = build_request_options(url)
34
+ respond(request_options[:interface], :put, request_options[:url],
35
+ params, request_options[:headers], request_options[:username], request_options[:password])
36
+ end
37
+
38
+ def delete(url, params = {})
39
+ request_options = build_request_options(url)
40
+ respond(request_options[:interface], :delete, request_options[:url],
41
+ params, request_options[:headers], request_options[:username], request_options[:password])
42
+ end
43
+
44
+ def build_request_options(url)
45
+ options = {}
46
+ options[:headers] = (url.is_a?(String)) ? nil : url.delete(:headers)
47
+ options[:url] = build_url(url)
48
+ options[:username], options[:password] = get_auth(url)
49
+ options[:interface] = get_interface(url)
50
+ options
51
+ end
52
+
53
+ def respond(interface, operation, url, params, headers, username = nil, password = nil)
54
+ if interface.nil?
55
+ raise Curl::Err::ConnectionFailedError
56
+ else
57
+ unless headers.nil?
58
+ process_headers(headers).each do |name, value|
59
+ interface.header(name, value)
60
+ end
61
+ end
62
+ interface.authorize(username, password) unless username.nil?
63
+ response = interface.send(operation, url, params)
64
+ CurbFu::Response::Base.from_rack_response(response)
65
+ end
66
+ end
67
+
68
+ def process_headers(headers)
69
+ headers.inject({}) do |accum, (header_name, value)|
70
+ key = header_name.gsub("-", "_").upcase
71
+ key = "HTTP_" + key unless key =~ /^HTTP_/
72
+ accum[key] = value
73
+ accum
74
+ end
75
+ end
76
+
77
+ def get_interface(url)
78
+ if url.is_a?(Hash)
79
+ host = url[:host]
80
+ else
81
+ host = parse_hostname(url)
82
+ end
83
+ match_host(host)
84
+ end
85
+
86
+ def parse_hostname(uri)
87
+ parsed_hostname = URI.parse(uri)
88
+ parsed_hostname.host || parsed_hostname.path
89
+ end
90
+
91
+ def match_host(host)
92
+ match = CurbFu.stubs.find do |(hostname, interface)|
93
+ hostname == host
94
+ end
95
+ match.last unless match.nil?
96
+ end
97
+
98
+ def get_auth(url)
99
+ username = password = nil
100
+ if url.is_a?(Hash) && url[:username]
101
+ username = url[:username]
102
+ password = url[:password]
103
+ end
104
+ [username, password]
105
+ end
106
+ end
107
+
108
+ class Interface
109
+ include Rack::Test::Methods
110
+
111
+ attr_accessor :app
112
+
113
+ def initialize(app)
114
+ @app = app
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,12 @@
1
+ require 'rubygems'
2
+ require 'curb'
3
+ require 'curb-fu/request/common'
4
+ require 'curb-fu/request/base'
5
+ require 'curb-fu/request/parameter'
6
+ require 'curb-fu/request/test'
7
+
8
+ module CurbFu
9
+ class Request
10
+ extend Base
11
+ end
12
+ end
@@ -0,0 +1,170 @@
1
+ module CurbFu
2
+ module Response
3
+ class Base
4
+ attr_accessor :status, :body, :headers
5
+
6
+ def initialize(status, headers, body)
7
+ @status = status
8
+ set_response_type(status)
9
+ @body = body
10
+ @headers = headers.is_a?(String) ? parse_headers(headers) : headers
11
+ end
12
+
13
+ def success?
14
+ self.is_a?(CurbFu::Response::Success)
15
+ end
16
+
17
+ def redirect?
18
+ self.is_a?(CurbFu::Response::Redirection)
19
+ end
20
+
21
+ def failure?
22
+ !(success? || redirect?)
23
+ end
24
+
25
+ def server_fail?
26
+ self.is_a?(CurbFu::Response::ServerError)
27
+ end
28
+
29
+ def client_fail?
30
+ self.is_a?(CurbFu::Response::ClientError)
31
+ end
32
+
33
+ def parse_headers(header_string)
34
+ header_lines = header_string.split($/)
35
+ header_lines.shift
36
+ header_lines.inject({}) do |hsh, line|
37
+ whole_enchillada, key, value = /^(.*?):\s*(.*)$/.match(line.chomp).to_a
38
+ hsh[key] = value unless whole_enchillada.nil?
39
+ hsh
40
+ end
41
+ end
42
+
43
+ def set_response_type(status)
44
+ case status
45
+ when 100..199 then
46
+ self.extend CurbFu::Response::Information
47
+ case self.status
48
+ when 101 then self.extend CurbFu::Response::Continue
49
+ when 102 then self.extend CurbFu::Response::SwitchProtocl
50
+ end
51
+ when 200..299 then
52
+ self.extend CurbFu::Response::Success
53
+ case self.status
54
+ when 200 then self.extend CurbFu::Response::OK
55
+ when 201 then self.extend CurbFu::Response::Created
56
+ when 202 then self.extend CurbFu::Response::Accepted
57
+ when 203 then self.extend CurbFu::Response::NonAuthoritativeInformation
58
+ when 204 then self.extend CurbFu::Response::NoContent
59
+ when 205 then self.extend CurbFu::Response::ResetContent
60
+ when 206 then self.extend CurbFu::Response::PartialContent
61
+ end
62
+ when 300..399 then
63
+ self.extend CurbFu::Response::Redirection
64
+ case self.status
65
+ when 300 then self.extend CurbFu::Response::MultipleChoice
66
+ when 301 then self.extend CurbFu::Response::MovedPermanently
67
+ when 302 then self.extend CurbFu::Response::Found
68
+ when 303 then self.extend CurbFu::Response::SeeOther
69
+ when 304 then self.extend CurbFu::Response::NotModified
70
+ when 305 then self.extend CurbFu::Response::UseProxy
71
+ when 307 then self.extend CurbFu::Response::TemporaryRedirect
72
+ end
73
+ when 400..499 then
74
+ self.extend CurbFu::Response::ClientError
75
+ case self.status
76
+ when 400 then self.extend CurbFu::Response::BadRequest
77
+ when 401 then self.extend CurbFu::Response::Unauthorized
78
+ when 402 then self.extend CurbFu::Response::PaymentRequired
79
+ when 403 then self.extend CurbFu::Response::Forbidden
80
+ when 404 then self.extend CurbFu::Response::NotFound
81
+ when 405 then self.extend CurbFu::Response::MethodNotAllowed
82
+ when 406 then self.extend CurbFu::Response::NotAcceptable
83
+ when 407 then self.extend CurbFu::Response::ProxyAuthenticationRequired
84
+ when 408 then self.extend CurbFu::Response::RequestTimeOut
85
+ when 409 then self.extend CurbFu::Response::Conflict
86
+ when 410 then self.extend CurbFu::Response::Gone
87
+ when 411 then self.extend CurbFu::Response::LengthRequired
88
+ when 412 then self.extend CurbFu::Response::PreconditionFailed
89
+ when 413 then self.extend CurbFu::Response::RequestEntityTooLarge
90
+ when 414 then self.extend CurbFu::Response::RequestURITooLong
91
+ when 415 then self.extend CurbFu::Response::UnsupportedMediaType
92
+ when 416 then self.extend CurbFu::Response::UnsupportedMediaType
93
+ when 417 then self.extend CurbFu::Response::ExpectationFailed
94
+ end
95
+ when 500..599 then
96
+ self.extend CurbFu::Response::ServerError
97
+ case self.status
98
+ when 500 then self.extend CurbFu::Response::InternalServerError
99
+ when 501 then self.extend CurbFu::Response::NotImplemented
100
+ when 502 then self.extend CurbFu::Response::BadGateway
101
+ when 503 then self.extend CurbFu::Response::ServiceUnavailable
102
+ when 504 then self.extend CurbFu::Response::GatewayTimeOut
103
+ when 505 then self.extend CurbFu::Response::VersionNotSupported
104
+ end
105
+ else
106
+ self.extend CurbFu::Response::UnknownResponse
107
+ end
108
+ end
109
+
110
+ class << self
111
+ def from_rack_response(rack)
112
+ raise ArgumentError.new("Rack response may not be nil") if rack.nil?
113
+ response = self.new(rack.status, rack.headers, rack.body)
114
+ end
115
+
116
+ def from_curb_response(curb)
117
+ response = self.new(curb.response_code, curb.header_str, curb.body_str)
118
+ response
119
+ end
120
+ end
121
+ end
122
+
123
+ module Information; end
124
+ module Continue; def self.to_i; 100; end; end
125
+ module SwitchProtocl; end
126
+ module Success; def self.to_i; 200; end; end
127
+ module OK; def self.to_i; 200; end; end
128
+ module Created; def self.to_i; 201; end; end
129
+ module Accepted; def self.to_i; 202; end; end
130
+ module NonAuthoritativeInformation; end
131
+ module NoContent; end
132
+ module ResetContent; end
133
+ module PartialContent; end
134
+ module Redirection; end # 3xx
135
+ module MultipleChoice; end # 300
136
+ module MovedPermanently; end # 301
137
+ module Found; def self.to_i; 302; end; end
138
+ module SeeOther; end # 303
139
+ module NotModified; end # 304
140
+ module UseProxy; end # 305
141
+ module TemporaryRedirect; end # 307
142
+ module ClientError; end # 4xx
143
+ module BadRequest; end # 400
144
+ module Unauthorized; end # 401
145
+ module PaymentRequired; end # 402
146
+ module Forbidden; end # 403
147
+ module NotFound; def self.to_i; 404; end; end
148
+ module MethodNotAllowed; end # 405
149
+ module NotAcceptable; end # 406
150
+ module ProxyAuthenticationRequired; end # 407
151
+ module RequestTimeOut; end # 408
152
+ module Conflict; end # 409
153
+ module Gone; def self.to_i; 410; end; end
154
+ module LengthRequired; end # 411
155
+ module PreconditionFailed; end # 412
156
+ module RequestEntityTooLarge; end # 413
157
+ module RequestURITooLong; end # 414
158
+ module UnsupportedMediaType; end # 415
159
+ module RequestedRangeNotSatisfiable; end # 416
160
+ module ExpectationFailed; end # 417
161
+ module ServerError; end # 5xx
162
+ module InternalServerError; def self.to_i; 500; end; end
163
+ module NotImplemented; end # 501
164
+ module BadGateway; end # 502
165
+ module ServiceUnavailable; def self.to_i; 503; end; end
166
+ module GatewayTimeOut; end # 504
167
+ module VersionNotSupported; end # 505
168
+ module UnknownResponse; end
169
+ end
170
+ end
data/lib/curb-fu.rb ADDED
@@ -0,0 +1,43 @@
1
+ dir = File.dirname(__FILE__)
2
+ $:.unshift(dir) unless $:.include?(dir)
3
+ require 'curb-fu/response'
4
+ require 'curb-fu/request'
5
+ require 'curb-fu/authentication'
6
+ require 'curb-fu/core_ext'
7
+
8
+ module CurbFu
9
+ class << self
10
+ def get(*args)
11
+ CurbFu::Request.get(*args)
12
+ end
13
+
14
+ def post(*args)
15
+ CurbFu::Request.post(*args)
16
+ end
17
+
18
+ def put(*args)
19
+ CurbFu::Request.put(*args)
20
+ end
21
+
22
+ def delete(*args)
23
+ CurbFu::Request.delete(*args)
24
+ end
25
+
26
+ attr_accessor :stubs
27
+
28
+ def stubs=(val)
29
+ if val
30
+ @stubs = val.inject({}) do |hsh, (hostname, rack_app)|
31
+ hsh[hostname] = CurbFu::Request::Test::Interface.new(rack_app)
32
+ hsh
33
+ end
34
+
35
+ unless CurbFu::Request.include?(CurbFu::Request::Test)
36
+ CurbFu::Request.send(:include, CurbFu::Request::Test)
37
+ end
38
+ else
39
+ @stubs = nil
40
+ end
41
+ end
42
+ end
43
+ end
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: thomaskay-curb-fu
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.2
5
+ platform: ruby
6
+ authors:
7
+ - Phil Green, Derek Kastner, Matt Wilson
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-05-25 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: taf2-curb
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.2.8.0
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: rack-test
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.2.0
34
+ version:
35
+ description:
36
+ email: support@greenviewdata.com
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files: []
42
+
43
+ files:
44
+ - lib/curb-fu.rb
45
+ - lib/curb-fu/authentication.rb
46
+ - lib/curb-fu/core_ext.rb
47
+ - lib/curb-fu/request.rb
48
+ - lib/curb-fu/response.rb
49
+ - lib/curb-fu/request/base.rb
50
+ - lib/curb-fu/request/common.rb
51
+ - lib/curb-fu/request/parameter.rb
52
+ - lib/curb-fu/request/test.rb
53
+ has_rdoc: false
54
+ homepage:
55
+ post_install_message:
56
+ rdoc_options: []
57
+
58
+ require_paths:
59
+ - lib
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: "0"
65
+ version:
66
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: "0"
71
+ version:
72
+ requirements: []
73
+
74
+ rubyforge_project:
75
+ rubygems_version: 1.2.0
76
+ signing_key:
77
+ specification_version: 2
78
+ summary: Friendly wrapper for curb
79
+ test_files: []
80
+