cm-httpclient 1.0.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/README.md ADDED
@@ -0,0 +1,4 @@
1
+ A simple HTTP client
2
+ ============================
3
+
4
+ Doc in progress...
@@ -0,0 +1,45 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{httpclient}
5
+ s.version = "1.0.0"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["pedro gutierrez"]
9
+ s.date = %q{2009-05-29}
10
+ s.description = %q{a simple httpclient}
11
+ s.email = %q{pedrogutierrez@mac.com}
12
+
13
+ s.files = %w[
14
+ README.md
15
+ httpclient.gemspec
16
+ lib/httpclient.rb
17
+ lib/httpclient/multipart.rb
18
+ lib/httpclient/httpclient.rb
19
+ ]
20
+
21
+
22
+ s.has_rdoc = true
23
+ s.homepage = %q{http://codemutiny.tumblr.com}
24
+ s.rdoc_options = ["--inline-source", "--charset=UTF-8"]
25
+ s.require_paths = ["lib"]
26
+ s.rubyforge_project = %q{cm-httpclient}
27
+ s.rubygems_version = %q{1.0.0}
28
+ s.summary = %q{a simple httpclient}
29
+
30
+ #if s.respond_to? :specification_version then
31
+ # current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
32
+ # s.specification_version = 2
33
+
34
+ # if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
35
+ # s.add_runtime_dependency(%q<mime-types>, [">= 1.15"])
36
+ # s.add_runtime_dependency(%q<diff-lcs>, [">= 1.1.2"])
37
+ # else
38
+ # s.add_dependency(%q<mime-types>, [">= 1.15"])
39
+ # s.add_dependency(%q<diff-lcs>, [">= 1.1.2"])
40
+ # end
41
+ #else
42
+ # s.add_dependency(%q<mime-types>, [">= 1.15"])
43
+ # s.add_dependency(%q<diff-lcs>, [">= 1.1.2"])
44
+ #end
45
+ end
@@ -0,0 +1,181 @@
1
+ require 'net/https'
2
+ require 'uri'
3
+ require 'rexml/document'
4
+ require 'helpers/multipart'
5
+
6
+ class Hash
7
+ def to_s
8
+ s = "{ "
9
+ self.each{ |k, v| s << "#{k} => #{v}, " }
10
+ s.chop!
11
+ s.chop!
12
+ s << " }"
13
+ end
14
+
15
+ def desym!
16
+ r = Hash.new
17
+ self.each do |k, v|
18
+ r[k.to_s]=v.to_s
19
+ end
20
+ self.replace(r)
21
+ end
22
+ end
23
+
24
+ class REXML::Document
25
+
26
+ def method_missing( name, *args )
27
+ self.root.send( name, args )
28
+ end
29
+
30
+ end
31
+
32
+ class REXML::Element
33
+
34
+ def method_missing( name, *args )
35
+ self.get_text( name.to_s ).to_s
36
+ end
37
+
38
+ end
39
+
40
+ class String
41
+
42
+ def to_simple_date
43
+ DateTime.strptime( self, '%Y-%m-%d' ).strftime( '%B %d, %Y ')
44
+ end
45
+
46
+ end
47
+
48
+ module HttpClient
49
+
50
+ def host( host )
51
+ @@host = host
52
+ end
53
+
54
+ def connect( &block )
55
+ uri = URI.parse( @@host )
56
+ h = Net::HTTP.new( uri.host, uri.port )
57
+ if( uri.scheme == 'https' )
58
+ h.use_ssl = uri.scheme
59
+ h.verify_mode = OpenSSL::SSL::VERIFY_NONE
60
+ end
61
+ headers = {}
62
+ headers.merge!( @auth ) if @auth
63
+ headers.desym!
64
+
65
+ block.call( h, headers )
66
+ end
67
+
68
+ def debug( &block )
69
+ @debug = true
70
+ instance_eval( &block )
71
+ @debug = false
72
+ end
73
+
74
+
75
+
76
+ def debug_request( http_method, path, headers, form = nil )
77
+ if @debug
78
+ puts ""
79
+ puts "Request"
80
+ puts "==========================="
81
+ puts "method: #{http_method}"
82
+ puts "path: #{path}"
83
+ puts "headers: #{headers}"
84
+ puts "form: #{form}" if form
85
+ puts ""
86
+ end
87
+ end
88
+
89
+ def debug_response( code, headers, body )
90
+ if @debug
91
+ puts ""
92
+ puts "Response"
93
+ puts "==========================="
94
+ puts "status code: #{code}"
95
+ puts "headers: #{headers}"
96
+ puts "body: #{body}"
97
+ puts ""
98
+ end
99
+ end
100
+
101
+ def retrieve( path, &block )
102
+ connect do |http, headers|
103
+ debug_request( :get, path, headers )
104
+ res = http.get path, headers
105
+ handle_response( res, block )
106
+ end
107
+ end
108
+
109
+ def remove( path, &block )
110
+ connect do |http, headers|
111
+ debug_request( :delete, path, headers )
112
+ res = http.delete path, headers
113
+ handle_response( res, block )
114
+ end
115
+ end
116
+
117
+
118
+ def create( path, form = nil, &block )
119
+ connect do |http, headers|
120
+ data = nil
121
+ headers[ 'Content-Length' ] = '0'
122
+
123
+ if form
124
+ data, extra_headers = Multipart::Post.prepare_query( form )
125
+ headers.merge!( extra_headers )
126
+ headers[ 'Content-Length' ] = data.length.to_s
127
+ end
128
+
129
+ debug_request( :post, path, headers, form )
130
+
131
+ res = http.post path, data, headers
132
+ handle_response( res, block )
133
+ end
134
+ end
135
+
136
+ alias :update :create
137
+
138
+
139
+ def handle_response( res, block = nil )
140
+ code = res.code.to_i
141
+ headers = res.to_hash
142
+ body = res.body
143
+
144
+ debug_response( code, headers, body )
145
+
146
+ if res[ 'Content-Type' ] == 'text/xml'
147
+ body = REXML::Document.new( body )
148
+ end
149
+ if block
150
+ block.call( code, body, headers )
151
+ else
152
+ @obtained_code = code
153
+ @obtained_body = body
154
+ @obtained_headers = headers
155
+ end
156
+ end
157
+
158
+ attr_reader :obtained_code, :obtained_body, :obtained_headers
159
+
160
+ def admin( key, &block )
161
+ if key == nil
162
+ anonymous( &block )
163
+ else
164
+ @auth = { :cmuser => key }
165
+ instance_eval( &block )
166
+ end
167
+ end
168
+
169
+ def user( username, password = nil, &block )
170
+ @auth = { :cmuser => username }
171
+ @auth[ :cmpasswd ] = password if password
172
+ instance_eval( &block )
173
+ end
174
+
175
+ def anonymous( &block )
176
+ @auth = { :cmuser => 'anonymous' }
177
+ instance_eval( &block )
178
+ end
179
+
180
+ end
181
+
@@ -0,0 +1,83 @@
1
+ # Takes a hash of string and file parameters and returns a string of text
2
+ # formatted to be sent as a multipart form post.
3
+ #
4
+ # Author:: Cody Brimhall <mailto:cbrimhall@ucdavis.edu>
5
+ # Created:: 22 Feb 2008
6
+
7
+ require 'rubygems'
8
+ require 'mime/types'
9
+ require 'cgi'
10
+
11
+
12
+ module Multipart
13
+ VERSION = "1.0.0" unless const_defined?(:VERSION)
14
+
15
+ # Formats a given hash as a multipart form post
16
+ # If a hash value responds to :string or :read messages, then it is
17
+ # interpreted as a file and processed accordingly; otherwise, it is assumed
18
+ # to be a string
19
+ class Post
20
+ # We have to pretend like we're a web browser...
21
+ USERAGENT = "Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-us) AppleWebKit/523.10.6 (KHTML, like Gecko) Version/3.0.4 Safari/523.10.6" unless const_defined?(:USERAGENT)
22
+ BOUNDARY = "0123456789ABLEWASIEREISAWELBA9876543210" unless const_defined?(:BOUNDARY)
23
+ CONTENT_TYPE = "multipart/form-data; boundary=#{ BOUNDARY }" unless const_defined?(:CONTENT_TYPE)
24
+ HEADER = { "Content-Type" => CONTENT_TYPE, "User-Agent" => USERAGENT } unless const_defined?(:HEADER)
25
+
26
+ def self.prepare_query(params)
27
+ fp = []
28
+
29
+ params.each do |k, v|
30
+
31
+ k = k.to_s
32
+
33
+ # Are we trying to make a file parameter?
34
+ if v.respond_to?(:path) and v.respond_to?(:read) then
35
+ fp.push(FileParam.new(k, v.path, v.read))
36
+ # We must be trying to make a regular parameter
37
+ else
38
+ fp.push(StringParam.new(k, v))
39
+ end
40
+ end
41
+
42
+ # Assemble the request body using the special multipart format
43
+ query = fp.collect {|p| "--" + BOUNDARY + "\r\n" + p.to_multipart }.join("") + "--" + BOUNDARY + "--"
44
+ return query, HEADER
45
+ end
46
+ end
47
+
48
+ private
49
+
50
+ # Formats a basic string key/value pair for inclusion with a multipart post
51
+ class StringParam
52
+ attr_accessor :k, :v
53
+
54
+ def initialize(k, v)
55
+ @k = k
56
+ @v = v
57
+ end
58
+
59
+ def to_multipart
60
+ return "Content-Disposition: form-data; name=\"#{CGI::escape(k)}\"\r\n\r\n#{v}\r\n"
61
+ end
62
+ end
63
+
64
+ # Formats the contents of a file or string for inclusion with a multipart
65
+ # form post
66
+ class FileParam
67
+ attr_accessor :k, :filename, :content
68
+
69
+ def initialize(k, filename, content)
70
+ @k = k
71
+ @filename = filename
72
+ @content = content
73
+ end
74
+
75
+ def to_multipart
76
+ # If we can tell the possible mime-type from the filename, use the
77
+ # first in the list; otherwise, use "application/octet-stream"
78
+ mime_type = MIME::Types.type_for(filename)[0] || MIME::Types["application/octet-stream"][0]
79
+ return "Content-Disposition: form-data; name=\"#{CGI::escape(k)}\"; filename=\"#{ filename }\"\r\n" +
80
+ "Content-Type: #{ mime_type.simplified }\r\n\r\n#{ content }\r\n"
81
+ end
82
+ end
83
+ end
data/lib/httpclient.rb ADDED
@@ -0,0 +1,7 @@
1
+ libdir = File.dirname(__FILE__)
2
+ $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
3
+
4
+ require 'httpclient/multipart'
5
+ require 'httpclient/httpclient'
6
+
7
+ include HttpClient
metadata ADDED
@@ -0,0 +1,58 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cm-httpclient
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - pedro gutierrez
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-05-29 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: a simple httpclient
17
+ email: pedrogutierrez@mac.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - README.md
26
+ - httpclient.gemspec
27
+ - lib/httpclient.rb
28
+ - lib/httpclient/multipart.rb
29
+ - lib/httpclient/httpclient.rb
30
+ has_rdoc: true
31
+ homepage: http://codemutiny.tumblr.com
32
+ post_install_message:
33
+ rdoc_options:
34
+ - --inline-source
35
+ - --charset=UTF-8
36
+ require_paths:
37
+ - lib
38
+ required_ruby_version: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: "0"
43
+ version:
44
+ required_rubygems_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: "0"
49
+ version:
50
+ requirements: []
51
+
52
+ rubyforge_project: cm-httpclient
53
+ rubygems_version: 1.2.0
54
+ signing_key:
55
+ specification_version: 2
56
+ summary: a simple httpclient
57
+ test_files: []
58
+