merb 0.4.1 → 0.4.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.
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