merb 0.4.1 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. data/README +138 -56
  2. data/Rakefile +23 -8
  3. data/app_generators/merb/templates/Rakefile +13 -0
  4. data/app_generators/merb/templates/app/helpers/global_helper.rb +1 -1
  5. data/app_generators/merb/templates/app/views/exceptions/internal_server_error.html.erb +12 -3
  6. data/app_generators/merb/templates/config/merb.yml +14 -1
  7. data/app_generators/merb/templates/spec/spec_helper.rb +6 -0
  8. data/app_generators/merb/templates/test/test_helper.rb +1 -0
  9. data/lib/merb.rb +27 -7
  10. data/lib/merb/abstract_controller.rb +76 -36
  11. data/lib/merb/caching/store/memcache.rb +20 -0
  12. data/lib/merb/constants.rb +2 -4
  13. data/lib/merb/controller.rb +44 -2
  14. data/lib/merb/core_ext/get_args.rb +23 -4
  15. data/lib/merb/core_ext/hash.rb +16 -11
  16. data/lib/merb/core_ext/inflections.rb +1 -1
  17. data/lib/merb/core_ext/kernel.rb +106 -26
  18. data/lib/merb/core_ext/numeric.rb +1 -1
  19. data/lib/merb/core_ext/string.rb +10 -13
  20. data/lib/merb/dispatcher.rb +2 -2
  21. data/lib/merb/exceptions.rb +3 -1
  22. data/lib/merb/logger.rb +15 -6
  23. data/lib/merb/mail_controller.rb +18 -2
  24. data/lib/merb/mailer.rb +1 -1
  25. data/lib/merb/mixins/controller.rb +64 -228
  26. data/lib/merb/mixins/erubis_capture.rb +1 -1
  27. data/lib/merb/mixins/general_controller.rb +258 -0
  28. data/lib/merb/mixins/render.rb +45 -24
  29. data/lib/merb/mixins/responder.rb +89 -18
  30. data/lib/merb/mixins/view_context.rb +32 -5
  31. data/lib/merb/mixins/web_controller.rb +8 -1
  32. data/lib/merb/mongrel_handler.rb +27 -17
  33. data/lib/merb/part_controller.rb +10 -0
  34. data/lib/merb/request.rb +34 -14
  35. data/lib/merb/router.rb +77 -45
  36. data/lib/merb/server.rb +116 -72
  37. data/lib/merb/session/cookie_store.rb +14 -22
  38. data/lib/merb/session/mem_cache_session.rb +2 -2
  39. data/lib/merb/session/memory_session.rb +12 -1
  40. data/lib/merb/template/erubis.rb +31 -0
  41. data/lib/merb/template/haml.rb +4 -14
  42. data/lib/merb/template/xml_builder.rb +1 -1
  43. data/lib/merb/test/helper.rb +90 -18
  44. data/lib/merb/test/rspec.rb +145 -74
  45. data/lib/merb/version.rb +11 -0
  46. data/lib/merb/view_context.rb +3 -6
  47. data/lib/patch +69 -0
  48. data/lib/tasks/merb.rake +1 -1
  49. data/spec/fixtures/config/environments/environment_config_test.yml +1 -0
  50. data/spec/fixtures/controllers/render_spec_controllers.rb +63 -4
  51. data/spec/fixtures/views/examples/template_throw_content_without_block.html.erb +3 -0
  52. data/spec/fixtures/views/partials/_erubis.html.erb +1 -1
  53. data/spec/merb/abstract_controller_spec.rb +1 -0
  54. data/spec/merb/controller_filters_spec.rb +68 -3
  55. data/spec/merb/controller_spec.rb +35 -68
  56. data/spec/merb/cookie_store_spec.rb +7 -20
  57. data/spec/merb/core_ext_spec.rb +35 -1
  58. data/spec/merb/dispatch_spec.rb +8 -2
  59. data/spec/merb/generator_spec.rb +12 -4
  60. data/spec/merb/mail_controller_spec.rb +33 -0
  61. data/spec/merb/part_controller_spec.rb +33 -1
  62. data/spec/merb/render_spec.rb +74 -0
  63. data/spec/merb/request_spec.rb +43 -0
  64. data/spec/merb/responder_spec.rb +1 -0
  65. data/spec/merb/router_spec.rb +118 -13
  66. data/spec/merb/server_spec.rb +19 -0
  67. data/spec/merb/view_context_spec.rb +31 -3
  68. data/spec/spec_helper.rb +8 -0
  69. data/spec/spec_helpers/url_shared_behaviour.rb +112 -0
  70. metadata +124 -87
@@ -9,7 +9,7 @@ class Numeric
9
9
  # after the number:
10
10
  # 1.5.to_currency nil, ",", ".", "$USD" #=> "1.50$USD"
11
11
  # 67_000.5.to_currency nil, ".", ",", "DM" #=> "67.000,50DM"
12
- def to_currency(pre_symbol='$', thousands=',', decimal='.', post_symbol=nil) #:nodoc:
12
+ def to_currency(pre_symbol='$', thousands=',', decimal='.', post_symbol=nil)
13
13
  "#{pre_symbol}#{("%.2f" % self ).gsub(".", decimal).gsub(/(\d)(?=(?:\d{3})+(?:$|[\\#{decimal}]))/,"\\1#{thousands}")}#{post_symbol}"
14
14
  end
15
15
 
@@ -2,7 +2,10 @@ require 'strscan'
2
2
 
3
3
  class String
4
4
  class InvalidPathConversion < Exception; end
5
-
5
+
6
+ # Escapes any characters in the string that would have special meaning in a
7
+ # regular expression.
8
+ # $ "\*?{}.".escape_regexp #=> "\\*\\?\\{\\}\\."
6
9
  def escape_regexp
7
10
  Regexp.escape self
8
11
  end
@@ -17,6 +20,8 @@ class String
17
20
  split('_').map{|e| e.capitalize}.join
18
21
  end
19
22
 
23
+ # "merb/core_ext/string" #=> "Merb::CoreExt::String"
24
+ #
20
25
  # About 50% faster than string.split('/').map{ |s| s.camel_case }.join('::')
21
26
  def to_const_string
22
27
  new_string = ""
@@ -33,24 +38,16 @@ class String
33
38
  end
34
39
 
35
40
  # Concatenates a path
41
+ # $ "merb"/"core_ext" #=> "merb/core_ext"
36
42
  def /(o)
37
43
  File.join(self, o.to_s)
38
44
  end
39
45
 
40
46
  # Takes lines of text, removes any indentation, and
41
47
  # adds +indentation+ number of spaces to each line
48
+ # $ " Hello\n Bob\nHow are you?".indent(3)
49
+ # #=> " Hello\n Bob\n How are you?"
42
50
  def indent(indentation)
43
- lines = to_a
44
- initial_indentation = lines.first.scan(/^(\s+)/).flatten.first
45
- lines.map do |line|
46
- if initial_indentation.nil?
47
- " " * indentation + line
48
- elsif line.index(initial_indentation) == 0
49
- " " * indentation + line[initial_indentation.size..-1]
50
- else
51
- " " * indentation + line
52
- end
53
- end.join
51
+ match(/\s*/) && gsub(/^\s{0,#{$&.length}}/, " " * indentation)
54
52
  end
55
-
56
53
  end
@@ -25,9 +25,9 @@ module Merb
25
25
  MERB_LOGGER.info("Cookies: #{request.cookies.inspect}")
26
26
  # user friendly error messages
27
27
  if request.route_params.empty?
28
- raise ControllerExceptions::NotFound, "No routes match the request"
28
+ raise ControllerExceptions::BadRequest, "No routes match the request"
29
29
  elsif request.controller_name.nil?
30
- raise ControllerExceptions::NotFound, "Route matched, but route did not specify a controller"
30
+ raise ControllerExceptions::BadRequest, "Route matched, but route did not specify a controller"
31
31
  end
32
32
  MERB_LOGGER.debug("Routed to: #{request.route_params.inspect}")
33
33
  # set controller class and the action to call
@@ -136,6 +136,7 @@ module Merb
136
136
  class TemporaryRedirect < Merb::ControllerExceptions::Redirection; STATUS = 307; end
137
137
  class ClientError < Merb::ControllerExceptions::Base; end
138
138
  class BadRequest < Merb::ControllerExceptions::ClientError; STATUS = 400; end
139
+ class MultiPartParseError < Merb::ControllerExceptions::BadRequest; end
139
140
  class Unauthorized < Merb::ControllerExceptions::ClientError; STATUS = 401; end
140
141
  class PaymentRequired < Merb::ControllerExceptions::ClientError; STATUS = 402; end
141
142
  class Forbidden < Merb::ControllerExceptions::ClientError; STATUS = 403; end
@@ -162,7 +163,8 @@ module Merb
162
163
  class ServiceUnavailable < Merb::ControllerExceptions::ServerError; STATUS = 503; end
163
164
  class GatewayTimeout < Merb::ControllerExceptions::ServerError; STATUS = 504; end
164
165
  class HTTPVersionNotSupported < Merb::ControllerExceptions::ServerError; STATUS = 505; end
165
- class InternalServerError < Merb::ControllerExceptions::ServerError; STATUS = 500
166
+ class InternalServerError < Merb::ControllerExceptions::ServerError;
167
+ STATUS = 500
166
168
  DEFAULT_TEMPLATE = ::Merb::Dispatcher::DEFAULT_ERROR_TEMPLATE
167
169
 
168
170
  def initialize(exception = nil)
@@ -17,6 +17,7 @@ module Merb
17
17
  def initialize(log, level = DEBUG)
18
18
  @level = level
19
19
  @buffer = []
20
+ @aio = false
20
21
  if log.respond_to?(:write)
21
22
  @log = log
22
23
  elsif File.exist?(log)
@@ -27,16 +28,24 @@ module Merb
27
28
  @log.sync = true
28
29
  @log.write("# Logfile created on %s\n" % [Time.now.to_s])
29
30
  end
31
+ if !MERB_ENV.match(/development|test/) &&
32
+ !RUBY_PLATFORM.match(/java|mswin/) &&
33
+ !(@log == STDOUT) &&
34
+ @log.respond_to?(:write_nonblock)
35
+ @aio = true
36
+ end
30
37
  end
31
-
38
+
32
39
  def flush
33
- if @log.respond_to?(:write_nonblock)
34
- @log.write_nonblock @buffer.slice!(0..-1).to_s unless @buffer.size == 0
35
- else
36
- @log.write @buffer.slice!(0..-1).to_s unless @buffer.size == 0
40
+ unless @buffer.size == 0
41
+ if @aio
42
+ @log.write_nonblock(@buffer.slice!(0..-1).to_s)
43
+ else
44
+ @log.write(@buffer.slice!(0..-1).to_s)
45
+ end
37
46
  end
38
47
  end
39
-
48
+
40
49
  def close
41
50
  flush
42
51
  @log.close if @log.respond_to?(:close)
@@ -245,9 +245,25 @@ module Merb
245
245
 
246
246
  # A convenience method that creates a blank copy of the MailController and runs
247
247
  # dispatch_and_deliver on it.
248
- def self.dispatch_and_deliver(method, mail_params)
249
- new({}).dispatch_and_deliver method, mail_params
248
+ def self.dispatch_and_deliver(method, mail_params, send_params = {})
249
+ new(send_params).dispatch_and_deliver method, mail_params
250
250
  end
251
251
 
252
+ protected
253
+ def route
254
+ @base_controller.route if @base_controller
255
+ end
256
+
257
+ private
258
+ # This method is here to overwrite the one in the general_controller mixin
259
+ # The method ensures that when a url is generated with a hash, it contains a controller
260
+ def get_controller_for_url_generation(opts)
261
+ puts @base_controller.params[:controller] if @base_controller
262
+ controller = opts[:controller] || ( @base_controller.params[:controller] if @base_controller)
263
+ raise "No Controller Specified for url()" unless controller
264
+ controller
265
+ end
266
+
267
+
252
268
  end
253
269
  end
@@ -53,7 +53,7 @@ module Merb
53
53
  def net_smtp
54
54
  Net::SMTP.start(config[:host], config[:port].to_i, config[:domain],
55
55
  config[:user], config[:pass], config[:auth]) { |smtp|
56
- smtp.send_message(@mail.to_s, @mail.from.first, @mail.to)
56
+ smtp.send_message(@mail.to_s, @mail.from.first, @mail.to.to_s.split(/[,;]/))
57
57
  }
58
58
  end
59
59
 
@@ -1,201 +1,32 @@
1
1
  module Merb
2
+ # Module that is mixed in to all implemented controllers.
2
3
  module ControllerMixin
3
4
 
4
- # Returns a URL according to the defined route. Accepts the path and
5
- # an options hash. The path specifies the route requested. The options
6
- # hash fills in the dynamic parts of the route.
5
+ # Renders the block given as a parameter using chunked
6
+ # encoding.
7
7
  #
8
- # Merb routes can often be one-way; if they use a regex to define
9
- # the route, then knowing the controller & action won't be enough
10
- # to reverse-generate the route. However, if you use the default
11
- # /controller/action/id?query route, +default_route+ can generate
12
- # it for you.
8
+ # ==== Examples
13
9
  #
14
- # For easy reverse-routes that use a Regex, be sure to also add
15
- # a name to the route, so +url+ can find it.
16
- #
17
- # Nested resources such as:
18
- # r.resources :blogposts do |post|
19
- # post.resources :comments
20
- # end
21
- #
22
- # Provide the following routes:
23
- # [:blogposts, "/blogposts"]
24
- # [:blogpost, "/blogposts/:id"]
25
- # [:edit_blogpost, "/blogposts/:id/edit"]
26
- # [:new_blogpost, "/blogposts/new"]
27
- # [:custom_new_blogpost, "/blogposts/new/:action"]
28
- # [:comments, "/blogposts/:blogpost_id/comments"]
29
- # [:comment, "/blogposts/:blogpost_id/comments/:id"]
30
- # [:edit_comment, "/blogposts/:blogpost_id/comments/:id/edit"]
31
- # [:new_comment, "/blogposts/:blogpost_id/comments/new"]
32
- # [:custom_new_comment, "/blogposts/:blogpost_id/comments/new/:action"]
33
- #
34
- # Examples:
35
- #
36
- # @post = Post.find(1)
37
- # @comment = @post.comments.find(1)
38
- #
39
- # url(:blogposts) # => /blogposts
40
- # url(:new_post) # => /blogposts/new
41
- # url(:blogpost, @post) # => /blogposts/1
42
- # url(:edit_blogpost, @post) # => /blogposts/1/edit
43
- # url(:custom_new_blogpost, :action => 'alternate') # => /blogposts/new/alternate
44
- #
45
- # url(:comments, :blogpost => @post) # => /blogposts/1/comments
46
- # url(:new_comment, :blogpost => @post) # => /blogposts/1/comments/new
47
- # url(:comment, @comment) # => /blogposts/1/comments/1
48
- # url(:edit_comment, @comment) # => /blogposts/1/comments/1/edit
49
- # url(:custom_new_comment, :blogpost => @post)
50
- #
51
- # url(:page => 2) # => /posts/show/1?page=2
52
- # url(:new_post, :page => 3) # => /posts/new?page=3
53
- # url('/go/here', :page => 3) # => /go/here?page=3
54
- #
55
- # url(:controller => "welcome") # => /welcome
56
- # url(:controller => "welcome", :action => "greet")
57
- # # => /welcome/greet
58
- #
59
- def url(route_name = nil, new_params = {})
60
- if route_name.is_a?(Hash)
61
- new_params = route_name
62
- route_name = nil
63
- end
64
-
65
- url = if new_params.respond_to?(:keys) && route_name.nil? &&
66
- !(new_params.keys & [:controller, :action, :id]).empty?
67
- url_from_default_route(new_params)
68
- elsif route_name.nil? && !route.regexp?
69
- url_from_route(route, new_params)
70
- elsif route_name.nil?
71
- request.path + (new_params.empty? ? "" : "?" + params_to_query_string(new_params))
72
- elsif route_name.is_a?(Symbol)
73
- url_from_route(route_name, new_params)
74
- elsif route_name.is_a?(String)
75
- route_name + (new_params.empty? ? "" : "?" + params_to_query_string(new_params))
76
- else
77
- raise "URL not generated: #{route_name.inspect}, #{new_params.inspect}"
78
- end
79
- url = MerbHandler.path_prefix + url if MerbHandler.path_prefix
80
- url
81
- end
82
-
83
- def url_from_route(symbol, new_params = {})
84
- if new_params.respond_to?(:new_record?) && new_params.new_record?
85
- symbol = "#{symbol}".singularize.to_sym
86
- new_params = {}
87
- end
88
- route = symbol.is_a?(Symbol) ? Merb::Router.named_routes[symbol] : symbol
89
- raise "URL could not be constructed. Route symbol not found: #{symbol.inspect}" unless route
90
- path = route.generate(new_params, params)
91
- keys = route.symbol_segments
92
- if new_params.is_a? Hash
93
- if ext = format_extension(new_params)
94
- new_params.delete(:format)
95
- path += "." + ext
96
- end
97
- extras = new_params.reject{ |k, v| keys.include?(k) }
98
- path += "?" + params_to_query_string(extras) unless extras.empty?
99
- end
100
- path
101
- end
102
-
103
- # this is pretty ugly, but it works. TODO: make this cleaner
104
- def url_from_default_route(new_params)
105
- query_params = new_params.reject do |k,v|
106
- [:controller, :action, :id, :format].include?(k)
107
- end
108
- controller = new_params[:controller] || params[:controller]
109
- controller = params[:controller] if controller == :current
110
- url = "/#{controller}"
111
- if new_params[:action] || new_params[:id] ||
112
- new_params[:format] || !query_params.empty?
113
- action = new_params[:action] || params[:action]
114
- url += "/#{action}"
115
- end
116
- if new_params[:id]
117
- url += "/#{new_params[:id]}"
118
- end
119
- if format = new_params[:format]
120
- format = params[:format] if format == :current
121
- url += ".#{format}"
122
- end
123
- unless query_params.empty?
124
- url += "?" + params_to_query_string(query_params)
125
- end
126
- url
127
- end
128
-
129
- protected
130
-
131
- # Creates query string from params, supporting nested arrays and hashes.
132
- # ==== Example
133
- # params_to_query_string(:user => {:filter => {:name => "quux*"}, :order => ["name"]})
134
- # # => user[filter][name]=quux%2A&user[order][]=name
135
- def params_to_query_string(value, prefix = nil)
136
- case value
137
- when Array
138
- value.map { |v|
139
- params_to_query_string(v, "#{prefix}[]")
140
- } * "&"
141
- when Hash
142
- value.map { |k, v|
143
- params_to_query_string(v, prefix ? "#{prefix}[#{escape(k)}]" : escape(k))
144
- } * "&"
145
- else
146
- "#{prefix}=#{escape(value)}"
147
- end
148
- end
149
-
150
- # +format_extension+ dictates when named route urls generated by #url
151
- # will have a file-extension. It will return false or the format
152
- # extension to append.
153
- #
154
- # url(:post, :id => post, :format => 'xml')
155
- #
156
- # generates:
157
- #
158
- # /posts/34.xml
159
- #
160
- # by default NON-HTML urls will be given an extension. it is posible
161
- # to override this behaviour by setting +:use_format_in_urls+ in your
162
- # server config (merb.yml) to either true/false
163
- #
164
- # +true+ would result in ALL urls (even html) being given extensions
165
- # this is often desirable when you have many formats and dont
166
- # wish to treat .html any differently from
167
- # +false+ would result in NO urls being given extensions, and format
168
- # gets treated just like any other param. leave it unset for
169
- # the default behavior
170
- #
171
- def format_extension(new_params={})
172
- use_format = Merb::Server.config[:use_format_in_urls]
173
- if use_format.nil?
174
- prms = params.merge(new_params)
175
- use_format = prms[:format] != 'html' && prms[:format]
176
- end
177
- use_format
178
- end
179
-
180
- # render using chunked encoding
181
- # def stream
182
- # prefix = '<p>'
183
- # suffix = "</p>\r\n"
184
- # render_chunked do
185
- # IO.popen("cat /tmp/test.log") do |io|
186
- # done = false
187
- # until done
188
- # sleep 0.3
189
- # line = io.gets.chomp
190
- # if line == 'EOF'
191
- # done = true
192
- # else
193
- # send_chunk(prefix + line + suffix)
10
+ # def stream
11
+ # prefix = '<p>'
12
+ # suffix = "</p>\r\n"
13
+ # render_chunked do
14
+ # IO.popen("cat /tmp/test.log") do |io|
15
+ # done = false
16
+ # until done
17
+ # sleep 0.3
18
+ # line = io.gets.chomp
19
+ #
20
+ # if line == 'EOF'
21
+ # done = true
22
+ # else
23
+ # send_chunk(prefix + line + suffix)
24
+ # end
194
25
  # end
195
26
  # end
196
27
  # end
197
28
  # end
198
- # end
29
+ #
199
30
  def render_chunked(&blk)
200
31
  headers['Transfer-Encoding'] = 'chunked'
201
32
  Proc.new {
@@ -206,6 +37,9 @@ module Merb
206
37
  }
207
38
  end
208
39
 
40
+ # Returns a +Proc+ that Mongrel can call later, allowing
41
+ # Merb to release the thread lock and render another request.
42
+ #
209
43
  def render_deferred(&blk)
210
44
  Proc.new {
211
45
  result = blk.call
@@ -215,25 +49,36 @@ module Merb
215
49
  }
216
50
  end
217
51
 
218
- # for use within a render_chunked response
52
+ # Writes a chunk from render_chunked to the response that
53
+ # is sent back to the client.
219
54
  def send_chunk(data)
220
55
  response.write('%x' % data.size + "\r\n")
221
56
  response.write(data + "\r\n")
222
57
  end
223
58
 
224
- # redirect to another url It can be like /foo/bar
225
- # for redirecting within your same app. Or it can
226
- # be a fully qualified url to another site.
59
+ # Redirects to a URL. The +url+ parameter can be either
60
+ # a relative URL (e.g., +/posts/34+) or a fully-qualified URL
61
+ # (e.g., +http://www.merbivore.com/+).
62
+ #
63
+ # ==== Parameters
64
+ #
65
+ # +url+ - URL to redirect to; it can be either a relative or
66
+ # fully-qualified URL.
67
+ #
227
68
  def redirect(url)
228
69
  MERB_LOGGER.info("Redirecting to: #{url}")
229
70
  set_status(302)
230
- headers.merge!({'Location'=> url})
231
- return ''
71
+ headers['Location'] = url
72
+ "<html><body>You are being <a href=\"#{url}\">redirected</a>.</body></html>"
232
73
  end
233
74
 
234
- # pass in a path to a file and this will set the
235
- # right headers and let mongrel do its thang and
236
- # serve the static file directly.
75
+ # Sends a file over HTTP. When given a path to a file, it will set the
76
+ # right headers so that the static file is served directly.
77
+ #
78
+ # ==== Parameters
79
+ #
80
+ # +file+ - Path to file to send to the client.
81
+ #
237
82
  def send_file(file, opts={})
238
83
  opts.update(Merb::Const::DEFAULT_SEND_FILE_OPTIONS.merge(opts))
239
84
  disposition = opts[:disposition].dup || 'attachment'
@@ -247,6 +92,10 @@ module Merb
247
92
  return
248
93
  end
249
94
 
95
+ # Streams a file over HTTP.
96
+ #
97
+ # ==== Example
98
+ #
250
99
  # stream_file( { :filename => file_name,
251
100
  # :type => content_type,
252
101
  # :content_length => content_length }) do
@@ -270,15 +119,24 @@ module Merb
270
119
  end
271
120
 
272
121
 
273
- # This uses nginx X-Accel-Redirect header to send
274
- # a file directly from nginx. See the nginx wiki:
122
+ # Uses the nginx specific +X-Accel-Redirect+ header to send
123
+ # a file directly from nginx. For more information, see the nginx wiki:
275
124
  # http://wiki.codemongers.com/NginxXSendfile
125
+ #
126
+ # ==== Parameters
127
+ #
128
+ # +file+ - Path to file to send to the client.
129
+ #
276
130
  def nginx_send_file(file)
277
131
  headers['X-Accel-Redirect'] = File.expand_path(file)
278
132
  return
279
133
  end
280
134
 
281
- # Sets a cookie to be included in the response.
135
+ # Sets a cookie to be included in the response. This method is used
136
+ # primarily internally in Merb.
137
+ #
138
+ # If you need to set a cookie, then use the +cookies+ hash.
139
+ #
282
140
  def set_cookie(name, value, expires)
283
141
  (headers['Set-Cookie'] ||='') << (Merb::Const::SET_COOKIE % [
284
142
  name.to_s,
@@ -288,35 +146,13 @@ module Merb
288
146
  ])
289
147
  end
290
148
 
291
- # Marks a cookie as deleted. The cookie is given an expires stamp in
292
- # the past.
149
+ # Marks a cookie as deleted and gives it an expires stamp in
150
+ # the past. This method is used primarily internally in Merb.
151
+ #
152
+ # Use the +cookies+ hash to manipulate cookies instead.
153
+ #
293
154
  def delete_cookie(name)
294
155
  set_cookie(name, nil, Merb::Const::COOKIE_EXPIRED_TIME)
295
156
  end
296
-
297
- # creates a random token like:
298
- # "b9a82e011694cc13a4249731b9e83cea"
299
- def make_token
300
- require 'digest/md5'
301
- Digest::MD5.hexdigest("#{inspect}#{Time.now}#{rand}")
302
- end
303
-
304
-
305
- def escape_xml(obj)
306
- obj.to_s.gsub(/[&<>"']/) { |s| Merb::Const::ESCAPE_TABLE[s] }
307
- end
308
- alias h escape_xml
309
- alias html_escape escape_xml
310
-
311
- # does url escaping
312
- def escape(s)
313
- Mongrel::HttpRequest.escape(s)
314
- end
315
-
316
- # does url unescaping
317
- def unescape(s)
318
- Mongrel::HttpRequest.unescape(s)
319
- end
320
-
321
157
  end
322
158
  end