rufus-verbs 0.10 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+
2
+ require 'rufus/verbs'
3
+
@@ -1,6 +1,5 @@
1
- #
2
1
  #--
3
- # Copyright (c) 2008, John Mettraux, jmettraux@gmail.com
2
+ # Copyright (c) 2008-2010, John Mettraux, jmettraux@gmail.com
4
3
  #
5
4
  # Permission is hereby granted, free of charge, to any person obtaining a copy
6
5
  # of this software and associated documentation files (the "Software"), to deal
@@ -20,17 +19,9 @@
20
19
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
20
  # THE SOFTWARE.
22
21
  #
23
- # (MIT license)
22
+ # Made in Japan.
24
23
  #++
25
- #
26
24
 
27
- #
28
- # John Mettraux
29
- #
30
- # Made in Japan
31
- #
32
- # 2008/01/11
33
- #
34
25
 
35
26
  require 'rufus/verbs/endpoint'
36
27
  require 'rufus/verbs/conditional'
@@ -39,94 +30,94 @@ require 'rufus/verbs/conditional'
39
30
  module Rufus::Verbs
40
31
 
41
32
 
42
- #
43
- # GET
44
- #
45
- def get (*args)
46
-
47
- EndPoint.request :get, args
48
- end
33
+ #
34
+ # GET
35
+ #
36
+ def get (*args)
49
37
 
50
- #
51
- # POST
52
- #
53
- def post (*args, &block)
38
+ EndPoint.request :get, args
39
+ end
54
40
 
55
- EndPoint.request :post, args, &block
56
- end
41
+ #
42
+ # POST
43
+ #
44
+ def post (*args, &block)
57
45
 
58
- #
59
- # PUT
60
- #
61
- def put (*args, &block)
46
+ EndPoint.request :post, args, &block
47
+ end
62
48
 
63
- EndPoint.request :put, args, &block
64
- end
49
+ #
50
+ # PUT
51
+ #
52
+ def put (*args, &block)
65
53
 
66
- #
67
- # DELETE
68
- #
69
- def delete (*args)
54
+ EndPoint.request :put, args, &block
55
+ end
70
56
 
71
- EndPoint.request :delete, args
72
- end
57
+ #
58
+ # DELETE
59
+ #
60
+ def delete (*args)
73
61
 
74
- #
75
- # HEAD
76
- #
77
- def head (*args)
62
+ EndPoint.request :delete, args
63
+ end
78
64
 
79
- EndPoint.request :head, args
80
- end
65
+ #
66
+ # HEAD
67
+ #
68
+ def head (*args)
81
69
 
82
- #
83
- # OPTIONS
84
- #
85
- def options (*args)
70
+ EndPoint.request :head, args
71
+ end
86
72
 
87
- EndPoint.request :options, args
88
- end
73
+ #
74
+ # OPTIONS
75
+ #
76
+ def options (*args)
89
77
 
90
- #
91
- # Opens a file or a URI (GETs it and return the reply). Will tolerate
92
- # a HTTP[S] URI or a file path.
93
- #
94
- # It is not named open() in order not to collide with File.open and
95
- # open-uri's open.
96
- #
97
- def fopen (uri, *args, &block)
78
+ EndPoint.request :options, args
79
+ end
98
80
 
99
- # should I really care about blocks here ? ...
81
+ #
82
+ # Opens a file or a URI (GETs it and return the reply). Will tolerate
83
+ # a HTTP[S] URI or a file path.
84
+ #
85
+ # It is not named open() in order not to collide with File.open and
86
+ # open-uri's open.
87
+ #
88
+ def fopen (uri, *args, &block)
100
89
 
101
- u = URI.parse uri.to_s
90
+ # should I really care about blocks here ? ...
102
91
 
103
- return File.open(uri.to_s, &block) \
104
- if u.scheme == nil
92
+ u = URI.parse uri.to_s
105
93
 
106
- return File.open(uri.to_s[5..-1], &block) \
107
- if u.scheme == 'file'
94
+ return File.open(uri.to_s, &block) \
95
+ if u.scheme == nil
108
96
 
109
- if u.scheme == 'http' or u.scheme == 'https'
97
+ return File.open(uri.to_s[5..-1], &block) \
98
+ if u.scheme == 'file'
110
99
 
111
- r = EndPoint.request(:get, [ uri ] + args) \
100
+ if u.scheme == 'http' or u.scheme == 'https'
112
101
 
113
- if block
114
- block.call r
115
- return
116
- end
102
+ r = EndPoint.request(:get, [ uri ] + args) \
117
103
 
118
- class << r
119
- def read
120
- self.body
121
- end
122
- end unless r.respond_to?(:read)
104
+ if block
105
+ block.call r
106
+ return
107
+ end
123
108
 
124
- return r
109
+ class << r
110
+ def read
111
+ self.body
125
112
  end
113
+ end unless r.respond_to?(:read)
126
114
 
127
- raise "can't handle scheme '#{u.scheme}' for #{u.to_s}"
115
+ return r
128
116
  end
129
117
 
130
- extend self
118
+ raise "can't handle scheme '#{u.scheme}' for #{u.to_s}"
119
+ end
120
+
121
+ extend self
131
122
  end
132
123
 
@@ -1,6 +1,5 @@
1
- #
2
1
  #--
3
- # Copyright (c) 2008, John Mettraux, jmettraux@gmail.com
2
+ # Copyright (c) 2008-2010, John Mettraux, jmettraux@gmail.com
4
3
  #
5
4
  # Permission is hereby granted, free of charge, to any person obtaining a copy
6
5
  # of this software and associated documentation files (the "Software"), to deal
@@ -8,10 +7,10 @@
8
7
  # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
8
  # copies of the Software, and to permit persons to whom the Software is
10
9
  # furnished to do so, subject to the following conditions:
11
- #
10
+ #
12
11
  # The above copyright notice and this permission notice shall be included in
13
12
  # all copies or substantial portions of the Software.
14
- #
13
+ #
15
14
  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
15
  # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
16
  # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -20,120 +19,111 @@
20
19
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
20
  # THE SOFTWARE.
22
21
  #
23
- # (MIT license)
22
+ # Made in Japan.
24
23
  #++
25
- #
26
24
 
27
- #
28
- # John Mettraux
29
- #
30
- # Made in Japan
31
- #
32
- # 2008/01/16
33
- #
34
25
 
35
- #require 'rubygems'
36
26
  require 'rufus/lru'
37
27
 
38
28
 
39
29
  module Rufus::Verbs
40
30
 
31
+ #
32
+ # An EndPoint with a cache for conditional GETs.
33
+ #
34
+ # ep = ConditionalEndPoint.new(
35
+ # :host => "restful.server",
36
+ # :port => 7080,
37
+ # :resource => "inventory/tools")
38
+ #
39
+ # res = ep.get :id => 1
40
+ # # first call will retrieve the representation completely
41
+ #
42
+ # res = ep.get :id => 1
43
+ # # the server (provided that it supports conditional GET) only
44
+ # # returned a 304 answer, the response is returned from the
45
+ # # ConditionalEndPoint cache
46
+ #
47
+ # The :cache_size option allows to set the size of the conditional GET
48
+ # cache. The default size is currently 147.
49
+ #
50
+ class ConditionalEndPoint < EndPoint
51
+
52
+ def initialize (opts)
53
+
54
+ super
55
+
56
+ cs = opts[:cache_size] || 147
57
+
58
+ @cache = LruHash.new cs
59
+ end
60
+
41
61
  #
42
- # An EndPoint with a cache for conditional GETs.
43
- #
44
- # ep = ConditionalEndPoint.new(
45
- # :host => "restful.server",
46
- # :port => 7080,
47
- # :resource => "inventory/tools")
48
- #
49
- # res = ep.get :id => 1
50
- # # first call will retrieve the representation completely
51
- #
52
- # res = ep.get :id => 1
53
- # # the server (provided that it supports conditional GET) only
54
- # # returned a 304 answer, the response is returned from the
55
- # # ConditionalEndPoint cache
56
- #
57
- # The :cache_size option allows to set the size of the conditional GET
58
- # cache. The default size is currently 147.
62
+ # Returns the count of representation 'cached' here for the
63
+ # purpose of conditional GET requests.
59
64
  #
60
- class ConditionalEndPoint < EndPoint
61
-
62
- def initialize (opts)
63
-
64
- super
65
+ def cache_current_size
65
66
 
66
- cs = opts[:cache_size] || 147
67
-
68
- @cache = LruHash.new cs
69
- end
70
-
71
- #
72
- # Returns the count of representation 'cached' here for the
73
- # purpose of conditional GET requests.
74
- #
75
- def cache_current_size
76
-
77
- @cache.size
78
- end
67
+ @cache.size
68
+ end
79
69
 
80
- #
81
- # Returns the max size of the conditional GET cache.
82
- #
83
- def cache_size
70
+ #
71
+ # Returns the max size of the conditional GET cache.
72
+ #
73
+ def cache_size
84
74
 
85
- @cache.maxsize
86
- end
75
+ @cache.maxsize
76
+ end
87
77
 
88
- private
78
+ private
89
79
 
90
- #
91
- # If the representation has already been gotten, send
92
- # potential If-Modified-Since and/or If-None-Match.
93
- #
94
- def add_conditional_headers (req, opts)
80
+ #
81
+ # If the representation has already been gotten, send
82
+ # potential If-Modified-Since and/or If-None-Match.
83
+ #
84
+ def add_conditional_headers (req, opts)
95
85
 
96
- # if path is cached send since and/or match
86
+ # if path is cached send since and/or match
97
87
 
98
- e = @cache[opts[:c_uri]]
88
+ e = @cache[opts[:c_uri]]
99
89
 
100
- return unless e # not cached
90
+ return unless e # not cached
101
91
 
102
- req['If-Modified-Since'] = e.lastmod if e.lastmod
103
- req['If-None-Match'] = e.etag if e.etag
92
+ req['If-Modified-Since'] = e.lastmod if e.lastmod
93
+ req['If-None-Match'] = e.etag if e.etag
104
94
 
105
- opts[:c_cached] = e
106
- end
95
+ opts[:c_cached] = e
96
+ end
107
97
 
108
- def handle_response (method, res, opts)
98
+ def handle_response (method, res, opts)
109
99
 
110
- # if method is get and reply is 200, cache (if et and/or lm)
111
- # if method is get and reply is 304, return from cache
100
+ # if method is get and reply is 200, cache (if et and/or lm)
101
+ # if method is get and reply is 304, return from cache
112
102
 
113
- super
103
+ super
114
104
 
115
- code = res.code.to_i
105
+ code = res.code.to_i
116
106
 
117
- return opts[:c_cached] if code == 304
107
+ return opts[:c_cached] if code == 304
118
108
 
119
- cache(res, opts) if code == 200
109
+ cache(res, opts) if code == 200
120
110
 
121
- res
122
- end
111
+ res
112
+ end
123
113
 
124
- def cache (res, opts)
114
+ def cache (res, opts)
125
115
 
126
- class << res
127
- def lastmod
128
- self['Last-Modified']
129
- end
130
- def etag
131
- self['Etag']
132
- end
133
- end
116
+ class << res
117
+ def lastmod
118
+ self['Last-Modified']
119
+ end
120
+ def etag
121
+ self['Etag']
122
+ end
123
+ end
134
124
 
135
- @cache[opts[:c_uri]] = res
136
- end
125
+ @cache[opts[:c_uri]] = res
137
126
  end
127
+ end
138
128
  end
139
129
 
@@ -1,6 +1,5 @@
1
- #
2
1
  #--
3
- # Copyright (c) 2008, John Mettraux, jmettraux@gmail.com
2
+ # Copyright (c) 2008-2010, John Mettraux, jmettraux@gmail.com
4
3
  #
5
4
  # Permission is hereby granted, free of charge, to any person obtaining a copy
6
5
  # of this software and associated documentation files (the "Software"), to deal
@@ -8,10 +7,10 @@
8
7
  # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
8
  # copies of the Software, and to permit persons to whom the Software is
10
9
  # furnished to do so, subject to the following conditions:
11
- #
10
+ #
12
11
  # The above copyright notice and this permission notice shall be included in
13
12
  # all copies or substantial portions of the Software.
14
- #
13
+ #
15
14
  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
15
  # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
16
  # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -20,308 +19,299 @@
20
19
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
20
  # THE SOFTWARE.
22
21
  #
23
- # (MIT license)
22
+ # Made in Japan.
24
23
  #++
25
- #
26
24
 
27
- #
28
- # John Mettraux
29
- #
30
- # Made in Japan
31
- #
32
- # 2008/01/19
33
- #
34
25
 
35
26
  require 'webrick/cookie'
36
27
 
37
- #require 'rubygems'
38
28
  require 'rufus/lru'
39
29
 
40
30
 
41
31
  module Rufus
42
32
  module Verbs
43
33
 
34
+ #
35
+ # Cookies related methods
36
+ #
37
+ # http://www.ietf.org/rfc/rfc2109.txt
38
+ #
39
+ module CookieMixin
40
+
44
41
  #
45
- # Cookies related methods
46
- #
47
- # http://www.ietf.org/rfc/rfc2109.txt
42
+ # making the cookie jar available
48
43
  #
49
- module CookieMixin
50
-
51
- #
52
- # making the cookie jar available
53
- #
54
- attr_reader :cookies
44
+ attr_reader :cookies
55
45
 
56
- protected
46
+ protected
57
47
 
58
- #
59
- # Prepares the instance variable @cookies for storing
60
- # cooking for this endpoint.
61
- #
62
- # Reads the :cookies endpoint option for determining the
63
- # size of the cookie jar (77 by default).
64
- #
65
- def prepare_cookie_jar
48
+ #
49
+ # Prepares the instance variable @cookies for storing
50
+ # cooking for this endpoint.
51
+ #
52
+ # Reads the :cookies endpoint option for determining the
53
+ # size of the cookie jar (77 by default).
54
+ #
55
+ def prepare_cookie_jar
66
56
 
67
- o = @opts[:cookies]
57
+ o = @opts[:cookies]
68
58
 
69
- return unless o and o != false
59
+ return unless o and o != false
70
60
 
71
- s = o.to_s.to_i
72
- s = 77 if s < 1
61
+ s = o.to_s.to_i
62
+ s = 77 if s < 1
73
63
 
74
- @cookies = CookieJar.new s
75
- end
64
+ @cookies = CookieJar.new s
65
+ end
76
66
 
77
- #
78
- # Parses the HTTP response for a potential 'Set-Cookie' header,
79
- # parses and returns it as a hash.
80
- #
81
- def parse_cookies (response)
67
+ #
68
+ # Parses the HTTP response for a potential 'Set-Cookie' header,
69
+ # parses and returns it as a hash.
70
+ #
71
+ def parse_cookies (response)
82
72
 
83
- c = response['Set-Cookie']
84
- return nil unless c
85
- Cookie.parse_set_cookies c
86
- end
73
+ c = response['Set-Cookie']
74
+ return nil unless c
75
+ Cookie.parse_set_cookies c
76
+ end
87
77
 
88
- #
89
- # (This method will have no effect if the EndPoint is not
90
- # tracking cookies)
91
- #
92
- # Registers a potential cookie set by the server.
93
- #
94
- def register_cookies (response, opts)
78
+ #
79
+ # (This method will have no effect if the EndPoint is not
80
+ # tracking cookies)
81
+ #
82
+ # Registers a potential cookie set by the server.
83
+ #
84
+ def register_cookies (response, opts)
95
85
 
96
- return unless @cookies
86
+ return unless @cookies
97
87
 
98
- cs = parse_cookies response
88
+ cs = parse_cookies response
99
89
 
100
- return unless cs
90
+ return unless cs
101
91
 
102
- # "The origin server effectively ends a session by
103
- # sending the client a Set-Cookie header with Max-Age=0"
92
+ # "The origin server effectively ends a session by
93
+ # sending the client a Set-Cookie header with Max-Age=0"
104
94
 
105
- cs.each do |c|
95
+ cs.each do |c|
106
96
 
107
- host = opts[:host]
108
- path = opts[:path]
109
- cpath = c.path || "/"
97
+ host = opts[:host]
98
+ path = opts[:path]
99
+ cpath = c.path || "/"
110
100
 
111
- next unless cookie_acceptable?(opts, response, c)
101
+ next unless cookie_acceptable?(opts, response, c)
112
102
 
113
- domain = c.domain || host
103
+ domain = c.domain || host
114
104
 
115
- if c.max_age == 0
116
- @cookies.remove_cookie domain, path, c
117
- else
118
- @cookies.add_cookie domain, path, c
119
- end
120
- end
121
- end
105
+ if c.max_age == 0
106
+ @cookies.remove_cookie domain, path, c
107
+ else
108
+ @cookies.add_cookie domain, path, c
109
+ end
110
+ end
111
+ end
122
112
 
123
- #
124
- # Checks if the cookie is acceptable in the context of
125
- # the request that sent it.
126
- #
127
- def cookie_acceptable? (opts, response, cookie)
113
+ #
114
+ # Checks if the cookie is acceptable in the context of
115
+ # the request that sent it.
116
+ #
117
+ def cookie_acceptable? (opts, response, cookie)
128
118
 
129
- # reject if :
130
- #
131
- # * The value for the Path attribute is not a prefix of the
132
- # request-URI.
133
- # * The value for the Domain attribute contains no embedded dots
134
- # or does not start with a dot.
135
- # * The value for the request-host does not domain-match the
136
- # Domain attribute.
137
- # * The request-host is a FQDN (not IP address) and has the form
138
- # HD, where D is the value of the Domain attribute, and H is a
139
- # string that contains one or more dots.
119
+ # reject if :
120
+ #
121
+ # * The value for the Path attribute is not a prefix of the
122
+ # request-URI.
123
+ # * The value for the Domain attribute contains no embedded dots
124
+ # or does not start with a dot.
125
+ # * The value for the request-host does not domain-match the
126
+ # Domain attribute.
127
+ # * The request-host is a FQDN (not IP address) and has the form
128
+ # HD, where D is the value of the Domain attribute, and H is a
129
+ # string that contains one or more dots.
140
130
 
141
- cdomain = cookie.domain
131
+ cdomain = cookie.domain
142
132
 
143
- if cdomain
133
+ if cdomain
144
134
 
145
- return false unless cdomain.index '.'
146
- return false if cdomain[0, 1] != '.'
135
+ return false unless cdomain.index '.'
136
+ return false if cdomain[0, 1] != '.'
147
137
 
148
- h, d = split_host(opts[:host])
149
- return false if d != cdomain
150
- end
138
+ h, d = split_host(opts[:host])
139
+ return false if d != cdomain
140
+ end
151
141
 
152
- #path = opts[:path]
153
- path = response.request.path
142
+ #path = opts[:path]
143
+ path = response.request.path
154
144
 
155
- cpath = cookie.path || "/"
145
+ cpath = cookie.path || "/"
156
146
 
157
- return false if path[0..cpath.length-1] != cpath
147
+ return false if path[0..cpath.length-1] != cpath
158
148
 
159
- true
160
- end
149
+ true
150
+ end
161
151
 
162
- #
163
- # Places the 'Cookie' header in the request if appropriate.
164
- #
165
- # (This method will have no effect if the EndPoint is not
166
- # tracking cookies)
167
- #
168
- def mention_cookies (request, opts)
152
+ #
153
+ # Places the 'Cookie' header in the request if appropriate.
154
+ #
155
+ # (This method will have no effect if the EndPoint is not
156
+ # tracking cookies)
157
+ #
158
+ def mention_cookies (request, opts)
169
159
 
170
- return unless @cookies
160
+ return unless @cookies
171
161
 
172
- cs = @cookies.fetch_cookies opts[:host], opts[:path]
162
+ cs = @cookies.fetch_cookies opts[:host], opts[:path]
173
163
 
174
- request['Cookie'] = cs.collect { |c| c.to_header_s }.join(",")
175
- end
164
+ request['Cookie'] = cs.collect { |c| c.to_header_s }.join(",")
165
+ end
166
+ end
167
+
168
+ #
169
+ # An extension of the cookie implementation found in WEBrick.
170
+ #
171
+ # Unmodified for now.
172
+ #
173
+ class Cookie < WEBrick::Cookie
174
+
175
+ def to_header_s
176
+
177
+ ret = ''
178
+ ret << @name << '=' << @value
179
+ ret << '; ' << '$Version=' << @version.to_s if @version > 0
180
+ ret << '; ' << '$Domain=' << @domain if @domain
181
+ ret << '; ' << '$Port=' << @port if @port
182
+ ret << '; ' << '$Path=' << @path if @path
183
+ ret
176
184
  end
185
+ end
177
186
 
178
- #
179
- # An extension of the cookie implementation found in WEBrick.
180
- #
181
- # Unmodified for now.
182
- #
183
- class Cookie < WEBrick::Cookie
187
+ #
188
+ # Cookies are stored by domain, they via this CookieKey which gathers
189
+ # path and name of the cookie.
190
+ #
191
+ class CookieKey
184
192
 
185
- def to_header_s
193
+ attr_reader :name, :path
186
194
 
187
- ret = ""
188
- ret << @name << "=" << @value
189
- ret << "; " << "$Version=" << @version.to_s if @version > 0
190
- ret << "; " << "$Domain=" << @domain if @domain
191
- ret << "; " << "$Port=" << @port if @port
192
- ret << "; " << "$Path=" << @path if @path
193
- ret
194
- end
195
+ def initialize (path, cookie)
196
+
197
+ @name = cookie.name
198
+ @path = path || cookie.path
195
199
  end
196
200
 
197
201
  #
198
- # Cookies are stored by domain, they via this CookieKey which gathers
199
- # path and name of the cookie.
202
+ # longer paths first
200
203
  #
201
- class CookieKey
202
-
203
- attr_reader :name, :path
204
+ def <=> (other)
204
205
 
205
- def initialize (path, cookie)
206
+ -1 * (@path <=> other.path)
207
+ end
206
208
 
207
- @name = cookie.name
208
- @path = path || cookie.path
209
- end
209
+ def hash
210
+ "#{@name}|#{@path}".hash
211
+ end
210
212
 
211
- #
212
- # longer paths first
213
- #
214
- def <=> (other)
213
+ def == (other)
214
+ (@path == other.path and @name == other.name)
215
+ end
215
216
 
216
- -1 * (@path <=> other.path)
217
- end
217
+ alias eql? ==
218
+ end
218
219
 
219
- def hash
220
- "#{@name}|#{@path}".hash
221
- end
220
+ #
221
+ # A few methods about hostnames.
222
+ #
223
+ # (in a mixin... could be helpful somewhere else later)
224
+ #
225
+ module HostMixin
222
226
 
223
- def == (other)
224
- (@path == other.path and @name == other.name)
225
- end
226
-
227
- alias eql? ==
228
- end
227
+ #
228
+ # Matching a classical IP address (not a v6 though).
229
+ # Should be sufficient for now.
230
+ #
231
+ IP_REGEX = /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/
229
232
 
230
233
  #
231
- # A few methods about hostnames.
234
+ # Returns a pair host/domain, note that the domain starts with a dot.
232
235
  #
233
- # (in a mixin... could be helpful somewhere else later)
236
+ # split_host('localhost') --> [ 'localhost', nil ]
237
+ # split_host('benz.car.co.nz') --> [ 'benz', '.car.co.nz' ]
238
+ # split_host('127.0.0.1') --> [ '127.0.0.1', nil ]
239
+ # split_host('::1') --> [ '::1', nil ]
234
240
  #
235
- module HostMixin
236
-
237
- #
238
- # Matching a classical IP address (not a v6 though).
239
- # Should be sufficient for now.
240
- #
241
- IP_REGEX = /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/
242
-
243
- #
244
- # Returns a pair host/domain, note that the domain starts with a dot.
245
- #
246
- # split_host('localhost') --> [ 'localhost', nil ]
247
- # split_host('benz.car.co.nz') --> [ 'benz', '.car.co.nz' ]
248
- # split_host('127.0.0.1') --> [ '127.0.0.1', nil ]
249
- # split_host('::1') --> [ '::1', nil ]
250
- #
251
- def split_host (host)
252
-
253
- return [ host, nil ] if IP_REGEX.match host
254
- i = host.index('.')
255
- return [ host, nil ] unless i
256
- [ host[0..i-1], host[i..-1] ]
257
- end
241
+ def split_host (host)
242
+
243
+ return [ host, nil ] if IP_REGEX.match host
244
+ i = host.index('.')
245
+ return [ host, nil ] unless i
246
+ [ host[0..i-1], host[i..-1] ]
258
247
  end
248
+ end
259
249
 
260
- #
261
- # The container for cookies. Features methods for storing and retrieving
262
- # cookies easily.
263
- #
264
- class CookieJar
265
- include HostMixin
250
+ #
251
+ # The container for cookies. Features methods for storing and retrieving
252
+ # cookies easily.
253
+ #
254
+ class CookieJar
255
+ include HostMixin
266
256
 
267
- def initialize (jar_size)
257
+ def initialize (jar_size)
268
258
 
269
- @per_domain = LruHash.new jar_size
270
- end
259
+ @per_domain = LruHash.new jar_size
260
+ end
271
261
 
272
- #
273
- # Returns the count of cookies currently stored in this jar.
274
- #
275
- def size
262
+ #
263
+ # Returns the count of cookies currently stored in this jar.
264
+ #
265
+ def size
276
266
 
277
- @per_domain.keys.inject(0) { |i, d| i + @per_domain[d].size }
278
- end
267
+ @per_domain.keys.inject(0) { |i, d| i + @per_domain[d].size }
268
+ end
279
269
 
280
- def add_cookie (domain, path, cookie)
270
+ def add_cookie (domain, path, cookie)
281
271
 
282
- (@per_domain[domain] ||= {})[CookieKey.new(path, cookie)] = cookie
283
- end
272
+ (@per_domain[domain] ||= {})[CookieKey.new(path, cookie)] = cookie
273
+ end
284
274
 
285
- def remove_cookie (domain, path, cookie)
275
+ def remove_cookie (domain, path, cookie)
286
276
 
287
- (d = @per_domain[domain])
288
- return unless d
289
- d.delete CookieKey.new(path, cookie)
290
- end
277
+ (d = @per_domain[domain])
278
+ return unless d
279
+ d.delete CookieKey.new(path, cookie)
280
+ end
291
281
 
292
- #
293
- # Retrieves the cookies that matches the combination host/path.
294
- # If the retrieved cookie is expired, will remove it from the jar
295
- # and return nil.
296
- #
297
- def fetch_cookies (host, path)
282
+ #
283
+ # Retrieves the cookies that matches the combination host/path.
284
+ # If the retrieved cookie is expired, will remove it from the jar
285
+ # and return nil.
286
+ #
287
+ def fetch_cookies (host, path)
298
288
 
299
- c = do_fetch(@per_domain[host], path)
289
+ c = do_fetch(@per_domain[host], path)
300
290
 
301
- h, d = split_host host
302
- c += do_fetch(@per_domain[d], path) if d
291
+ h, d = split_host host
292
+ c += do_fetch(@per_domain[d], path) if d
303
293
 
304
- c
305
- end
294
+ c
295
+ end
306
296
 
307
- private
297
+ private
308
298
 
309
- #
310
- # Returns all the cookies that match a domain (host) and a path.
311
- #
312
- def do_fetch (dh, path)
299
+ #
300
+ # Returns all the cookies that match a domain (host) and a path.
301
+ #
302
+ def do_fetch (dh, path)
313
303
 
314
- return [] unless dh
304
+ return [] unless dh
315
305
 
316
- keys = dh.keys.sort.find_all do |k|
317
- path[0..k.path.length-1] == k.path
318
- end
319
- keys.inject([]) do |r, k|
320
- r << dh[k]
321
- r
322
- end
323
- end
306
+ keys = dh.keys.sort.find_all do |k|
307
+ path[0..k.path.length-1] == k.path
308
+ end
309
+ keys.inject([]) do |r, k|
310
+ r << dh[k]
311
+ r
312
+ end
324
313
  end
314
+ end
325
315
  end
326
316
  end
327
317