pezra-resourceful 0.5.4 → 0.6.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.
@@ -0,0 +1,18 @@
1
+ Version 0.6.0
2
+ =============
3
+
4
+ * Improved support for multi-valued header fields. (Peter Williams)
5
+ * Added convenience mechanisms for making URL encoded and multipart form data requests. (Peter Williams)
6
+ * Ruby 1.9 support (Peter Williams)
7
+
8
+ Compatibility issues
9
+ --------------------
10
+
11
+ * The semantics of the Resourceful::Header API have changed slightly.
12
+ Previously, any header might return a string or an array. Now
13
+ fields are either "single-value" and always return a string, or
14
+ "multi-value" and always return an array. See API doc for more
15
+ details.
16
+
17
+
18
+
data/Manifest CHANGED
@@ -1,34 +1,39 @@
1
- lib/resourceful/authentication_manager.rb
2
- lib/resourceful/cache_manager.rb
3
- lib/resourceful/exceptions.rb
4
- lib/resourceful/header.rb
5
- lib/resourceful/http_accessor.rb
6
- lib/resourceful/memcache_cache_manager.rb
7
- lib/resourceful/multipart_form_data.rb
1
+ lib/resourceful.rb
8
2
  lib/resourceful/net_http_adapter.rb
9
3
  lib/resourceful/options_interpretation.rb
10
- lib/resourceful/request.rb
11
- lib/resourceful/resource.rb
12
- lib/resourceful/response.rb
13
4
  lib/resourceful/stubbed_resource_proxy.rb
5
+ lib/resourceful/urlencoded_form_data.rb
6
+ lib/resourceful/header.rb
7
+ lib/resourceful/memcache_cache_manager.rb
8
+ lib/resourceful/response.rb
14
9
  lib/resourceful/util.rb
15
- lib/resourceful.rb
16
- Manifest
10
+ lib/resourceful/abstract_form_data.rb
11
+ lib/resourceful/cache_manager.rb
12
+ lib/resourceful/request.rb
13
+ lib/resourceful/resource.rb
14
+ lib/resourceful/exceptions.rb
15
+ lib/resourceful/multipart_form_data.rb
16
+ lib/resourceful/http_accessor.rb
17
+ lib/resourceful/authentication_manager.rb
18
+ History.txt
19
+ resourceful.gemspec
20
+ README.markdown
17
21
  MIT-LICENSE
18
22
  Rakefile
19
- README.markdown
20
- resourceful.gemspec
23
+ Manifest
24
+ spec/simple_sinatra_server_spec.rb
25
+ spec/old_acceptance_specs.rb
26
+ spec/acceptance_shared_specs.rb
27
+ spec/spec_helper.rb
28
+ spec/simple_sinatra_server.rb
21
29
  spec/acceptance/authorization_spec.rb
22
- spec/acceptance/caching_spec.rb
23
30
  spec/acceptance/header_spec.rb
24
- spec/acceptance/redirecting_spec.rb
25
31
  spec/acceptance/resource_spec.rb
26
- spec/acceptance_shared_specs.rb
27
- spec/caching_spec.rb
28
- spec/old_acceptance_specs.rb
32
+ spec/acceptance/caching_spec.rb
33
+ spec/acceptance/redirecting_spec.rb
29
34
  spec/resourceful/multipart_form_data_spec.rb
35
+ spec/resourceful/header_spec.rb
30
36
  spec/resourceful/resource_spec.rb
31
- spec/simple_sinatra_server.rb
32
- spec/simple_sinatra_server_spec.rb
37
+ spec/resourceful/urlencoded_form_data_spec.rb
38
+ spec/caching_spec.rb
33
39
  spec/spec.opts
34
- spec/spec_helper.rb
@@ -58,8 +58,17 @@ Post a URL encoded form
58
58
 
59
59
  require 'resourceful'
60
60
  http = Resourceful::HttpAccessor.new
61
- resp = http.resource('http://mysite.example/service').
62
- post('hostname=test&level=super', :content_type => 'application/x-www-form-urlencoded')
61
+ resp = http.resource('http://mysite.example/service').
62
+ post(Resourceful::UrlencodedFormData.new(:hostname => 'test', :level => 'super'))
63
+
64
+ Post a Mulitpart form with a file
65
+ -----------------------
66
+
67
+ require 'resourceful'
68
+ http = Resourceful::HttpAccessor.new
69
+ form_data = Resourceful::MultipartFormData.new(:username => 'me')
70
+ form_data.add_file('avatar', '/tmp/my_avatar.png', 'image/png')
71
+ resp = http.resource('http://mysite.example/service').post(form_data)
63
72
 
64
73
  Put an XML document
65
74
  -------------------
@@ -10,9 +10,13 @@ require 'resourceful/util'
10
10
  require 'resourceful/header'
11
11
  require 'resourceful/http_accessor'
12
12
 
13
+ module Resourceful
14
+ autoload :MultipartFormData, 'resourceful/multipart_form_data'
15
+ autoload :UrlencodedFormData, 'resourceful/urlencoded_form_data'
16
+ end
17
+
13
18
  # Resourceful is a library that provides a high level HTTP interface.
14
19
  module Resourceful
15
- VERSION = "0.5.4"
20
+ VERSION = "0.6.0"
16
21
  RESOURCEFUL_USER_AGENT_TOKEN = "Resourceful/#{VERSION}(Ruby/#{RUBY_VERSION})"
17
-
18
22
  end
@@ -0,0 +1,18 @@
1
+ module Resourceful
2
+ class AbstractFormData
3
+ def initialize(contents = {})
4
+ @form_data = []
5
+
6
+ contents.each do |k,v|
7
+ add(k, v)
8
+ end
9
+ end
10
+
11
+ def add(name, value)
12
+ form_data << [name.to_s, value]
13
+ end
14
+
15
+ protected
16
+ attr_reader :form_data
17
+ end
18
+ end
@@ -1,125 +1,256 @@
1
- # A case-normalizing Hash, adjusting on [] and []=.
2
- # Shamelessly swiped from Rack
1
+ require 'resourceful/options_interpretation'
2
+ require 'set'
3
+
4
+ # Represents the header fields of an HTTP message. To access a field
5
+ # you can use `#[]` and `#[]=`. For example, to get the content type
6
+ # of a response you can do
7
+ #
8
+ # response.header['Content-Type'] # => "application/xml"
9
+ #
10
+ # Lookups and modifications done in this way are case insensitive, so
11
+ # 'Content-Type', 'content-type' and :content_type are all equivalent.
12
+ #
13
+ # Multi-valued fields
14
+ # -------------------
15
+ #
16
+ # Multi-value fields (e.g. Accept) are always returned as an Array
17
+ # regardless of the number of values, if the field is present.
18
+ # Single-value fields (e.g. Content-Type) are always returned as
19
+ # strings. The multi/single valueness of a header field is determined
20
+ # by the way it is defined in the HTTP spec. Unknown fields are
21
+ # treated as multi-valued.
22
+ #
23
+ # (This behavior is new in 0.6 and may be slightly incompatible with
24
+ # the way previous versions worked in some situations.)
25
+ #
26
+ # For example
27
+ #
28
+ # h = Resourceful::Header.new
29
+ # h['Accept'] = "application/xml"
30
+ # h['Accept'] # => ["application/xml"]
31
+ #
3
32
  module Resourceful
4
- class Header < Hash
33
+ class Header
34
+ include Enumerable
35
+
5
36
  def initialize(hash={})
37
+ @raw_fields = {}
6
38
  hash.each { |k, v| self[k] = v }
7
39
  end
8
40
 
9
41
  def to_hash
10
- {}.replace(self)
42
+ @raw_fields.dup
11
43
  end
12
44
 
13
45
  def [](k)
14
- super capitalize(k)
46
+ field_def(k).get_from(@raw_fields)
15
47
  end
16
48
 
17
49
  def []=(k, v)
18
- super capitalize(k), v
50
+ field_def(k).set_to(v, @raw_fields)
19
51
  end
20
52
 
21
53
  def has_key?(k)
22
- super capitalize(k)
54
+ field_def(k).exists_in?(@raw_fields)
55
+ end
56
+
57
+ def each(&blk)
58
+ @raw_fields.each(&blk)
59
+ end
60
+ alias each_field each
61
+
62
+ def merge!(another)
63
+ another.each do |k,v|
64
+ self[k] = v
65
+ end
66
+ self
23
67
  end
24
68
 
25
- def capitalize(k)
26
- k.to_s.downcase.gsub(/^.|[-_\s]./) { |x| x.upcase }.gsub('_', '-')
69
+ def merge(another)
70
+ self.class.new(self).merge!(another)
27
71
  end
28
72
 
29
- def each_field(&blk)
30
- to_hash.each { |k,v|
31
- blk.call capitalize(k), v
32
- }
73
+ def reverse_merge(another)
74
+ self.class.new(another).merge!(self)
33
75
  end
34
76
 
35
- HEADERS = %w[
36
- Accept
37
- Accept-Charset
38
- Accept-Encoding
39
- Accept-Language
40
- Accept-Ranges
41
- Age
42
- Allow
43
- Authorization
44
- Cache-Control
45
- Connection
46
- Content-Encoding
47
- Content-Language
48
- Content-Length
49
- Content-Location
50
- Content-MD5
51
- Content-Range
52
- Content-Type
53
- Date
54
- ETag
55
- Expect
56
- Expires
57
- From
58
- Host
59
- If-Match
60
- If-Modified-Since
61
- If-None-Match
62
- If-Range
63
- If-Unmodified-Since
64
- Keep-Alive
65
- Last-Modified
66
- Location
67
- Max-Forwards
68
- Pragma
69
- Proxy-Authenticate
70
- Proxy-Authorization
71
- Range
72
- Referer
73
- Retry-After
74
- Server
75
- TE
76
- Trailer
77
- Transfer-Encoding
78
- Upgrade
79
- User-Agent
80
- Vary
81
- Via
82
- Warning
83
- WWW-Authenticate
84
- ]
85
-
86
- HEADERS.each do |header|
87
- const = header.upcase.gsub('-', '_')
88
- meth = header.downcase.gsub('-', '_')
89
-
90
- class_eval <<-RUBY, __FILE__, __LINE__
91
- #{const} = "#{header}".freeze # ACCEPT = "accept".freeze
92
-
93
- def #{meth} # def accept
94
- self[#{const}] # self[ACCEPT]
95
- end # end
96
-
97
- def #{meth}=(str) # def accept=(str)
98
- self[#{const}] = str # self[ACCEPT] = str
99
- end # end
100
- RUBY
77
+ def dup
78
+ self.class.new(@raw_fields.dup)
79
+ end
80
+
81
+
82
+ # Class to handle the details of each type of field.
83
+ class HeaderFieldDef
84
+ include Comparable
85
+ include OptionsInterpretation
86
+
87
+ ##
88
+ attr_reader :name
89
+
90
+ def initialize(name, options = {})
91
+ @name = name
92
+ extract_opts(options) do |opts|
93
+ @repeatable = opts.extract(:repeatable, :default => false)
94
+ @hop_by_hop = opts.extract(:hop_by_hop, :default => false)
95
+ @modifiable = opts.extract(:modifiable, :default => true)
96
+ end
97
+ end
98
+
99
+ def repeatable?
100
+ @repeatable
101
+ end
102
+
103
+ def hop_by_hop?
104
+ @hop_by_hop
105
+ end
106
+
107
+ def modifiable?
108
+ @modifiable
109
+ end
110
+
111
+ def get_from(raw_fields_hash)
112
+ raw_fields_hash[name]
113
+ end
114
+
115
+ def set_to(value, raw_fields_hash)
116
+ raw_fields_hash[name] = if repeatable?
117
+ Array(value)
118
+ elsif value.kind_of?(Array)
119
+ raise ArgumentError, "#{name} field may only have one value" if value.size > 1
120
+ value.first
121
+ else
122
+ value
123
+ end
124
+ end
125
+
126
+ def exists_in?(raw_fields_hash)
127
+ raw_fields_hash.has_key?(name)
128
+ end
129
+
130
+ def <=>(another)
131
+ name <=> another.name
132
+ end
101
133
 
134
+ def ==(another)
135
+ name_pattern === another.name
136
+ end
137
+ alias eql? ==
138
+
139
+ def ===(another)
140
+ if another.kind_of?(HeaderFieldDef)
141
+ self == another
142
+ else
143
+ name_pattern === another
144
+ end
145
+ end
146
+
147
+ def name_pattern
148
+ Regexp.new('^' + name.gsub('-', '[_-]') + '$', Regexp::IGNORECASE)
149
+ end
150
+
151
+ def methodized_name
152
+ name.downcase.gsub('-', '_')
153
+ end
154
+
155
+ alias to_s name
156
+
157
+ def gen_setter(klass)
158
+ klass.class_eval <<-RUBY
159
+ def #{methodized_name}=(val) # def accept=(val)
160
+ self['#{name}'] = val # self['Accept'] = val
161
+ end # end
162
+ RUBY
163
+ end
164
+
165
+ def gen_getter(klass)
166
+ klass.class_eval <<-RUBY
167
+ def #{methodized_name} # def accept
168
+ self['#{name}'] # self['Accept']
169
+ end # end
170
+ RUBY
171
+ end
172
+
173
+ def gen_canonical_name_const(klass)
174
+ const_name = name.upcase.gsub('-', '_')
175
+
176
+ klass.const_set(const_name, name)
177
+ end
178
+ end
179
+
180
+ @@header_field_defs = Set.new
181
+
182
+ def self.header_field(name, options = {})
183
+ hfd = HeaderFieldDef.new(name, options)
184
+
185
+ @@header_field_defs << hfd
186
+
187
+ hfd.gen_getter(self)
188
+ hfd.gen_setter(self)
189
+ hfd.gen_canonical_name_const(self)
190
+ end
191
+
192
+ def self.hop_by_hop_headers
193
+ @@header_field_defs.select{|hfd| hfd.hop_by_hop?}
194
+ end
195
+
196
+ def self.non_modifiable_headers
197
+ @@header_field_defs.reject{|hfd| hfd.repeatable?}
198
+ end
199
+
200
+ def field_def(name)
201
+ @@header_field_defs.find{|hfd| hfd === name} ||
202
+ HeaderFieldDef.new(name.to_s.downcase.gsub(/^.|[-_\s]./) { |x| x.upcase }.gsub('_', '-'), :repeatable => true)
102
203
  end
103
204
 
104
- HOP_BY_HOP_HEADERS = [
105
- CONNECTION,
106
- KEEP_ALIVE,
107
- PROXY_AUTHENTICATE,
108
- PROXY_AUTHORIZATION,
109
- TE,
110
- TRAILER,
111
- TRANSFER_ENCODING,
112
- UPGRADE
113
- ].freeze
114
-
115
- NON_MODIFIABLE_HEADERS = [
116
- CONTENT_LOCATION,
117
- CONTENT_MD5,
118
- ETAG,
119
- LAST_MODIFIED,
120
- EXPIRES
121
- ].freeze
122
205
 
206
+ header_field('Accept', :repeatable => true)
207
+ header_field('Accept-Charset', :repeatable => true)
208
+ header_field('Accept-Encoding', :repeatable => true)
209
+ header_field('Accept-Language', :repeatable => true)
210
+ header_field('Accept-Ranges', :repeatable => true)
211
+ header_field('Age')
212
+ header_field('Allow', :repeatable => true)
213
+ header_field('Authorization', :repeatable => true)
214
+ header_field('Cache-Control', :repeatable => true)
215
+ header_field('Connection', :hop_by_hop => true)
216
+ header_field('Content-Encoding', :repeatable => true)
217
+ header_field('Content-Language', :repeatable => true)
218
+ header_field('Content-Length')
219
+ header_field('Content-Location', :modifiable => false)
220
+ header_field('Content-MD5', :modifiable => false)
221
+ header_field('Content-Range')
222
+ header_field('Content-Type')
223
+ header_field('Date')
224
+ header_field('ETag', :modifiable => false)
225
+ header_field('Expect', :repeatable => true)
226
+ header_field('Expires', :modifiable => false)
227
+ header_field('From')
228
+ header_field('Host')
229
+ header_field('If-Match', :repeatable => true)
230
+ header_field('If-Modified-Since')
231
+ header_field('If-None-Match', :repeatable => true)
232
+ header_field('If-Range')
233
+ header_field('If-Unmodified-Since')
234
+ header_field('Keep-Alive', :hop_by_hop => true)
235
+ header_field('Last-Modified', :modifiable => false)
236
+ header_field('Location')
237
+ header_field('Max-Forwards')
238
+ header_field('Pragma', :repeatable => true)
239
+ header_field('Proxy-Authenticate', :hop_by_hop => true)
240
+ header_field('Proxy-Authorization', :hop_by_hop => true)
241
+ header_field('Range')
242
+ header_field('Referer')
243
+ header_field('Retry-After')
244
+ header_field('Server')
245
+ header_field('TE', :repeatable => true, :hop_by_hop => true)
246
+ header_field('Trailer', :repeatable => true, :hop_by_hop => true)
247
+ header_field('Transfer-Encoding', :repeatable => true, :hop_by_hop => true)
248
+ header_field('Upgrade', :repeatable => true, :hop_by_hop => true)
249
+ header_field('User-Agent')
250
+ header_field('Vary', :repeatable => true)
251
+ header_field('Via', :repeatable => true)
252
+ header_field('Warning', :repeatable => true)
253
+ header_field('WWW-Authenticate', :repeatable => true)
123
254
  end
124
255
  end
125
256
 
@@ -1,16 +1,9 @@
1
+ require 'resourceful/abstract_form_data'
1
2
 
2
3
  module Resourceful
3
- class MultipartFormData
4
+ class MultipartFormData < AbstractFormData
4
5
  FileParamValue = Struct.new(:content, :file_name, :content_type)
5
6
 
6
- def initialize()
7
- @form_data = []
8
- end
9
-
10
- def add(name, value)
11
- form_data << [name, value]
12
- end
13
-
14
7
  def add_file(name, file_name, content_type="application/octet-stream")
15
8
  add(name, FileParamValue.new(File.new(file_name, 'r'), File.basename(file_name), content_type))
16
9
  end
@@ -21,8 +14,10 @@ module Resourceful
21
14
 
22
15
  def read
23
16
  StringIO.new.tap do |out|
17
+ first = true
24
18
  form_data.each do |key, val|
25
- out << "\r\n--" << boundary
19
+ out << "\r\n" unless first
20
+ out << "--" << boundary
26
21
  out << "\r\nContent-Disposition: form-data; name=\"#{key}\""
27
22
  if val.kind_of?(FileParamValue)
28
23
  out << "; filename=\"#{val.file_name}\""
@@ -34,13 +29,13 @@ module Resourceful
34
29
  else
35
30
  out << val.to_s
36
31
  end
32
+ first = false
37
33
  end
38
34
  out << "\r\n--#{boundary}--"
39
35
  end.string
40
36
  end
41
37
 
42
38
  protected
43
- attr_reader :form_data
44
39
 
45
40
  def boundary
46
41
  @boundary ||= (0..30).map{BOUNDARY_CHARS[rand(BOUNDARY_CHARS.length)]}.join
@@ -30,15 +30,21 @@ module Resourceful
30
30
  def make_request(method, uri, body = nil, header = nil)
31
31
  uri = uri.is_a?(Addressable::URI) ? uri : Addressable::URI.parse(uri)
32
32
 
33
+ if [:put, :post].include? method
34
+ body = body ? body.read : ""
35
+ header[:content_length] = body.size
36
+ end
37
+
33
38
  req = net_http_request_class(method).new(uri.absolute_path)
34
39
  header.each_field { |k,v| req[k] = v } if header
35
40
  https = ("https" == uri.scheme)
36
- conn = Net::HTTP.Proxy(*proxy_details).new(uri.host, uri.port || (https ? 443 : 80))
41
+ conn_class = proxy_details ? Net::HTTP.Proxy(*proxy_details) : Net::HTTP
42
+ conn = conn_class.new(uri.host, uri.port || (https ? 443 : 80))
37
43
  conn.use_ssl = https
38
44
  begin
39
45
  conn.start
40
46
  res = if body
41
- conn.request(req, body.read)
47
+ conn.request(req, body)
42
48
  else
43
49
  conn.request(req)
44
50
  end
@@ -205,7 +205,7 @@ module Resourceful
205
205
 
206
206
  # Does this request force us to revalidate the cache?
207
207
  def forces_revalidation?
208
- if max_age == 0 || header.cache_control && cc.include?('no-cache')
208
+ if max_age == 0 || skip_cache?
209
209
  logger.info(" Client forced revalidation")
210
210
  true
211
211
  else
@@ -30,7 +30,7 @@ module Resourceful
30
30
  alias uri effective_uri
31
31
 
32
32
  def default_header(temp_defaults = {})
33
- temp_defaults.merge(@default_header)
33
+ @default_header.merge(temp_defaults)
34
34
  end
35
35
 
36
36
  # Returns the host for this Resource's current uri
@@ -139,14 +139,14 @@ module Resourceful
139
139
 
140
140
  # Ensures that the request has a content type header
141
141
  def ensure_content_type(body, header)
142
- return if header.has_key?(:content_type)
142
+ return if header.has_key?('Content-Type')
143
143
 
144
144
  if body.respond_to?(:content_type)
145
- header[:content_type] = body.content_type
145
+ header['Content-Type'] = body.content_type
146
146
  return
147
147
  end
148
148
 
149
- return if default_header.has_key?(:content_type)
149
+ return if default_header.has_key?('Content-Type')
150
150
 
151
151
  # could not figure it out
152
152
  raise MissingContentType
@@ -154,12 +154,16 @@ module Resourceful
154
154
 
155
155
  # Actually make the request
156
156
  def request(method, data, header)
157
+ header = default_header.merge(header)
157
158
  ensure_content_type(data, header) if data
158
159
 
159
160
  data = StringIO.new(data) if data.kind_of?(String)
160
161
 
161
- log_request_with_time "#{method.to_s.upcase} [#{uri}]" do
162
- request = Request.new(method, self, data, default_header.merge(header))
162
+ logger.debug { header.map {|k,v| "#{k}: #{v}"}.join("\n\t\t") }
163
+ logger.debug { data = StringIO.new(data.read); data.string } if data
164
+
165
+ log_request_with_time "#{method.to_s.upcase} [#{uri}]" do
166
+ request = Request.new(method, self, data, header)
163
167
  request.fetch_response
164
168
  end
165
169
  end
@@ -26,8 +26,8 @@ module Resourceful
26
26
  if header['Cache-Control'] and header['Cache-Control'].first.include?('max-age')
27
27
  max_age = header['Cache-Control'].first.split(',').grep(/max-age/).first.split('=').last.to_i
28
28
  return true if current_age > max_age
29
- elsif header['Expire']
30
- return true if Time.httpdate(header['Expire'].first) < Time.now
29
+ elsif header['Expires']
30
+ return true if Time.httpdate(header['Expires']) < Time.now
31
31
  end
32
32
 
33
33
  false
@@ -75,8 +75,8 @@ module Resourceful
75
75
 
76
76
  # Algorithm taken from RCF2616#13.2.3
77
77
  def current_age
78
- age_value = header['Age'] ? header['Age'].first.to_i : 0
79
- date_value = Time.httpdate(header['Date'].first)
78
+ age_value = header['Age'] || 0
79
+ date_value = Time.httpdate(header['Date'])
80
80
  now = Time.now
81
81
 
82
82
  apparent_age = [0, response_time - date_value].max
@@ -85,7 +85,7 @@ module Resourceful
85
85
  end
86
86
 
87
87
  def body
88
- encoding = header['Content-Encoding'] && header['Content-Encoding'].first
88
+ encoding = header['Content-Encoding']
89
89
  case encoding
90
90
  when nil
91
91
  # body is identity encoded; just return it
@@ -0,0 +1,17 @@
1
+ require 'resourceful/abstract_form_data'
2
+ require 'cgi'
3
+
4
+ module Resourceful
5
+ class UrlencodedFormData < AbstractFormData
6
+
7
+ def content_type
8
+ "application/x-www-form-urlencoded"
9
+ end
10
+
11
+ def read
12
+ @form_data.map do |k,v|
13
+ CGI.escape(k) + '=' + CGI.escape(v)
14
+ end.join('&')
15
+ end
16
+ end
17
+ end
@@ -2,26 +2,25 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{resourceful}
5
- s.version = "0.5.4"
5
+ s.version = "0.6.0"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Paul Sadauskas"]
9
- s.date = %q{2009-08-07}
9
+ s.date = %q{2009-08-14}
10
10
  s.description = %q{An HTTP library for Ruby that takes advantage of everything HTTP has to offer.}
11
11
  s.email = %q{psadauskas@gmail.com}
12
- s.extra_rdoc_files = ["lib/resourceful/authentication_manager.rb", "lib/resourceful/cache_manager.rb", "lib/resourceful/exceptions.rb", "lib/resourceful/header.rb", "lib/resourceful/http_accessor.rb", "lib/resourceful/memcache_cache_manager.rb", "lib/resourceful/multipart_form_data.rb", "lib/resourceful/net_http_adapter.rb", "lib/resourceful/options_interpretation.rb", "lib/resourceful/request.rb", "lib/resourceful/resource.rb", "lib/resourceful/response.rb", "lib/resourceful/stubbed_resource_proxy.rb", "lib/resourceful/util.rb", "lib/resourceful.rb", "README.markdown"]
13
- s.files = ["lib/resourceful/authentication_manager.rb", "lib/resourceful/cache_manager.rb", "lib/resourceful/exceptions.rb", "lib/resourceful/header.rb", "lib/resourceful/http_accessor.rb", "lib/resourceful/memcache_cache_manager.rb", "lib/resourceful/multipart_form_data.rb", "lib/resourceful/net_http_adapter.rb", "lib/resourceful/options_interpretation.rb", "lib/resourceful/request.rb", "lib/resourceful/resource.rb", "lib/resourceful/response.rb", "lib/resourceful/stubbed_resource_proxy.rb", "lib/resourceful/util.rb", "lib/resourceful.rb", "Manifest", "MIT-LICENSE", "Rakefile", "README.markdown", "resourceful.gemspec", "spec/acceptance/authorization_spec.rb", "spec/acceptance/caching_spec.rb", "spec/acceptance/header_spec.rb", "spec/acceptance/redirecting_spec.rb", "spec/acceptance/resource_spec.rb", "spec/acceptance_shared_specs.rb", "spec/caching_spec.rb", "spec/old_acceptance_specs.rb", "spec/resourceful/multipart_form_data_spec.rb", "spec/resourceful/resource_spec.rb", "spec/simple_sinatra_server.rb", "spec/simple_sinatra_server_spec.rb", "spec/spec.opts", "spec/spec_helper.rb"]
14
- s.has_rdoc = true
12
+ s.extra_rdoc_files = ["lib/resourceful.rb", "lib/resourceful/net_http_adapter.rb", "lib/resourceful/options_interpretation.rb", "lib/resourceful/stubbed_resource_proxy.rb", "lib/resourceful/urlencoded_form_data.rb", "lib/resourceful/header.rb", "lib/resourceful/memcache_cache_manager.rb", "lib/resourceful/response.rb", "lib/resourceful/util.rb", "lib/resourceful/abstract_form_data.rb", "lib/resourceful/cache_manager.rb", "lib/resourceful/request.rb", "lib/resourceful/resource.rb", "lib/resourceful/exceptions.rb", "lib/resourceful/multipart_form_data.rb", "lib/resourceful/http_accessor.rb", "lib/resourceful/authentication_manager.rb", "README.markdown"]
13
+ s.files = ["lib/resourceful.rb", "lib/resourceful/net_http_adapter.rb", "lib/resourceful/options_interpretation.rb", "lib/resourceful/stubbed_resource_proxy.rb", "lib/resourceful/urlencoded_form_data.rb", "lib/resourceful/header.rb", "lib/resourceful/memcache_cache_manager.rb", "lib/resourceful/response.rb", "lib/resourceful/util.rb", "lib/resourceful/abstract_form_data.rb", "lib/resourceful/cache_manager.rb", "lib/resourceful/request.rb", "lib/resourceful/resource.rb", "lib/resourceful/exceptions.rb", "lib/resourceful/multipart_form_data.rb", "lib/resourceful/http_accessor.rb", "lib/resourceful/authentication_manager.rb", "History.txt", "resourceful.gemspec", "README.markdown", "MIT-LICENSE", "Rakefile", "Manifest", "spec/simple_sinatra_server_spec.rb", "spec/old_acceptance_specs.rb", "spec/acceptance_shared_specs.rb", "spec/spec_helper.rb", "spec/simple_sinatra_server.rb", "spec/acceptance/authorization_spec.rb", "spec/acceptance/header_spec.rb", "spec/acceptance/resource_spec.rb", "spec/acceptance/caching_spec.rb", "spec/acceptance/redirecting_spec.rb", "spec/resourceful/multipart_form_data_spec.rb", "spec/resourceful/header_spec.rb", "spec/resourceful/resource_spec.rb", "spec/resourceful/urlencoded_form_data_spec.rb", "spec/caching_spec.rb", "spec/spec.opts"]
15
14
  s.homepage = %q{http://github.com/paul/resourceful}
16
15
  s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Resourceful", "--main", "README.markdown"]
17
- s.require_paths = ["lib", "ext"]
16
+ s.require_paths = ["lib"]
18
17
  s.rubyforge_project = %q{resourceful}
19
- s.rubygems_version = %q{1.3.1}
18
+ s.rubygems_version = %q{1.3.5}
20
19
  s.summary = %q{An HTTP library for Ruby that takes advantage of everything HTTP has to offer.}
21
20
 
22
21
  if s.respond_to? :specification_version then
23
22
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
24
- s.specification_version = 2
23
+ s.specification_version = 3
25
24
 
26
25
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
27
26
  s.add_runtime_dependency(%q<addressable>, [">= 2.1.0"])
@@ -104,7 +104,7 @@ describe Resourceful do
104
104
 
105
105
  it 'should revalidate the cached response if the response is expired' do
106
106
  in_the_past = (Time.now - 60).httpdate
107
- resource = @http.resource(uri_for_code(200, "Expire" => in_the_past))
107
+ resource = @http.resource(uri_for_code(200, "Expires" => in_the_past))
108
108
 
109
109
  resp = resource.get
110
110
  resp.should be_expired
@@ -7,12 +7,12 @@ describe Resourceful do
7
7
  describe "working with a resource" do
8
8
  before do
9
9
  @http = Resourceful::HttpAccessor.new
10
- @resource = @http.resource('http://localhost:3000/')
10
+ @resource = @http.resource('http://localhost:42682/')
11
11
  end
12
12
 
13
13
  it 'should make the original uri available' do
14
- @resource.effective_uri.should == 'http://localhost:3000/'
15
- @resource.uri.should == 'http://localhost:3000/'
14
+ @resource.effective_uri.should == 'http://localhost:42682/'
15
+ @resource.uri.should == 'http://localhost:42682/'
16
16
  end
17
17
 
18
18
  it 'should set the user agent string on the default header' do
@@ -0,0 +1,8 @@
1
+ require File.dirname(__FILE__) + "/../spec_helper.rb"
2
+
3
+
4
+ describe Resourceful::Header do
5
+ it "should have constants for header names" do
6
+ Resourceful::Header::CONTENT_TYPE.should == 'Content-Type'
7
+ end
8
+ end
@@ -29,7 +29,6 @@ describe Resourceful::MultipartFormData do
29
29
 
30
30
  boundary = /boundary=(\w+)/.match(@form_data.content_type)[1]
31
31
  @form_data.read.should eql(<<MPFD[0..-2])
32
- \r
33
32
  --#{boundary}\r
34
33
  Content-Disposition: form-data; name="foo"\r
35
34
  \r
@@ -62,7 +61,6 @@ MPFD
62
61
 
63
62
  boundary = /boundary=(\w+)/.match(@form_data.content_type)[1]
64
63
  @form_data.read.should eql(<<MPFD[0..-2])
65
- \r
66
64
  --#{boundary}\r
67
65
  Content-Disposition: form-data; name="foo"; filename="#{File.basename(file_to_upload.path)}"\r
68
66
  Content-Type: application/octet-stream\r
@@ -0,0 +1,44 @@
1
+ require File.dirname(__FILE__) + "/../spec_helper"
2
+ require 'tempfile'
3
+ require "resourceful/urlencoded_form_data.rb"
4
+
5
+ describe Resourceful::UrlencodedFormData do
6
+
7
+ before do
8
+ @form_data = Resourceful::UrlencodedFormData.new
9
+ end
10
+
11
+ it "should know its content-type" do
12
+ @form_data.content_type.should match(/^application\/x-www-form-urlencoded$/i)
13
+ end
14
+
15
+ describe "instantiation" do
16
+ it "should be creatable with hash" do
17
+ Resourceful::UrlencodedFormData.new(:foo => 'testing').read.should eql("foo=testing")
18
+ end
19
+ end
20
+
21
+ describe "with simple parameters" do
22
+ it "should all simple parameters to be added" do
23
+ @form_data.add(:foo, "testing")
24
+ end
25
+
26
+ it "should render a multipart form-data document when #read is called" do
27
+ @form_data.add('foo', 'bar')
28
+ @form_data.add('baz', 'this')
29
+
30
+ @form_data.read.should eql("foo=bar&baz=this")
31
+ end
32
+
33
+ it "should escape character in values that are unsafe" do
34
+ @form_data.add('foo', 'this & that')
35
+
36
+ @form_data.read.should eql("foo=this+%26+that")
37
+ end
38
+
39
+ it "should escape character in names that are unsafe" do
40
+ @form_data.add('foo=bar', 'this')
41
+ @form_data.read.should eql("foo%3Dbar=this")
42
+ end
43
+ end
44
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pezra-resourceful
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.4
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Sadauskas
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-08-07 00:00:00 -07:00
12
+ date: 2009-08-14 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -79,58 +79,65 @@ executables: []
79
79
  extensions: []
80
80
 
81
81
  extra_rdoc_files:
82
- - lib/resourceful/authentication_manager.rb
83
- - lib/resourceful/cache_manager.rb
84
- - lib/resourceful/exceptions.rb
85
- - lib/resourceful/header.rb
86
- - lib/resourceful/http_accessor.rb
87
- - lib/resourceful/memcache_cache_manager.rb
88
- - lib/resourceful/multipart_form_data.rb
82
+ - lib/resourceful.rb
89
83
  - lib/resourceful/net_http_adapter.rb
90
84
  - lib/resourceful/options_interpretation.rb
91
- - lib/resourceful/request.rb
92
- - lib/resourceful/resource.rb
93
- - lib/resourceful/response.rb
94
85
  - lib/resourceful/stubbed_resource_proxy.rb
86
+ - lib/resourceful/urlencoded_form_data.rb
87
+ - lib/resourceful/header.rb
88
+ - lib/resourceful/memcache_cache_manager.rb
89
+ - lib/resourceful/response.rb
95
90
  - lib/resourceful/util.rb
96
- - lib/resourceful.rb
97
- - README.markdown
98
- files:
99
- - lib/resourceful/authentication_manager.rb
91
+ - lib/resourceful/abstract_form_data.rb
100
92
  - lib/resourceful/cache_manager.rb
93
+ - lib/resourceful/request.rb
94
+ - lib/resourceful/resource.rb
101
95
  - lib/resourceful/exceptions.rb
102
- - lib/resourceful/header.rb
103
- - lib/resourceful/http_accessor.rb
104
- - lib/resourceful/memcache_cache_manager.rb
105
96
  - lib/resourceful/multipart_form_data.rb
97
+ - lib/resourceful/http_accessor.rb
98
+ - lib/resourceful/authentication_manager.rb
99
+ - README.markdown
100
+ files:
101
+ - lib/resourceful.rb
106
102
  - lib/resourceful/net_http_adapter.rb
107
103
  - lib/resourceful/options_interpretation.rb
108
- - lib/resourceful/request.rb
109
- - lib/resourceful/resource.rb
110
- - lib/resourceful/response.rb
111
104
  - lib/resourceful/stubbed_resource_proxy.rb
105
+ - lib/resourceful/urlencoded_form_data.rb
106
+ - lib/resourceful/header.rb
107
+ - lib/resourceful/memcache_cache_manager.rb
108
+ - lib/resourceful/response.rb
112
109
  - lib/resourceful/util.rb
113
- - lib/resourceful.rb
114
- - Manifest
110
+ - lib/resourceful/abstract_form_data.rb
111
+ - lib/resourceful/cache_manager.rb
112
+ - lib/resourceful/request.rb
113
+ - lib/resourceful/resource.rb
114
+ - lib/resourceful/exceptions.rb
115
+ - lib/resourceful/multipart_form_data.rb
116
+ - lib/resourceful/http_accessor.rb
117
+ - lib/resourceful/authentication_manager.rb
118
+ - History.txt
119
+ - resourceful.gemspec
120
+ - README.markdown
115
121
  - MIT-LICENSE
116
122
  - Rakefile
117
- - README.markdown
118
- - resourceful.gemspec
123
+ - Manifest
124
+ - spec/simple_sinatra_server_spec.rb
125
+ - spec/old_acceptance_specs.rb
126
+ - spec/acceptance_shared_specs.rb
127
+ - spec/spec_helper.rb
128
+ - spec/simple_sinatra_server.rb
119
129
  - spec/acceptance/authorization_spec.rb
120
- - spec/acceptance/caching_spec.rb
121
130
  - spec/acceptance/header_spec.rb
122
- - spec/acceptance/redirecting_spec.rb
123
131
  - spec/acceptance/resource_spec.rb
124
- - spec/acceptance_shared_specs.rb
125
- - spec/caching_spec.rb
126
- - spec/old_acceptance_specs.rb
132
+ - spec/acceptance/caching_spec.rb
133
+ - spec/acceptance/redirecting_spec.rb
127
134
  - spec/resourceful/multipart_form_data_spec.rb
135
+ - spec/resourceful/header_spec.rb
128
136
  - spec/resourceful/resource_spec.rb
129
- - spec/simple_sinatra_server.rb
130
- - spec/simple_sinatra_server_spec.rb
137
+ - spec/resourceful/urlencoded_form_data_spec.rb
138
+ - spec/caching_spec.rb
131
139
  - spec/spec.opts
132
- - spec/spec_helper.rb
133
- has_rdoc: true
140
+ has_rdoc: false
134
141
  homepage: http://github.com/paul/resourceful
135
142
  licenses:
136
143
  post_install_message:
@@ -143,7 +150,6 @@ rdoc_options:
143
150
  - README.markdown
144
151
  require_paths:
145
152
  - lib
146
- - ext
147
153
  required_ruby_version: !ruby/object:Gem::Requirement
148
154
  requirements:
149
155
  - - ">="
@@ -161,7 +167,7 @@ requirements: []
161
167
  rubyforge_project: resourceful
162
168
  rubygems_version: 1.3.5
163
169
  signing_key:
164
- specification_version: 2
170
+ specification_version: 3
165
171
  summary: An HTTP library for Ruby that takes advantage of everything HTTP has to offer.
166
172
  test_files: []
167
173