public
Rubygem
Description: Merb Core: All you need. None you don't.
Homepage: http://www.merbivore.com
Clone URL: git://github.com/wycats/merb-core.git
Search Repo:
Merge branch 'master' of git@github.com:wycats/merb-core
ivey (author)
Wed Feb 13 20:10:20 -0800 2008
commit  baf74321765d1ab799dc4a51f44766f6ad1a8e45
tree    b889c3cfaf30ac4b3161d6acf6f87523c429bf79
parent  ab721722d8d076c11190330b93f62c85f7f8a074 parent  8abb459d89ccb6061fa9dc59c380823619de1706
...
161
162
163
164
 
165
166
167
...
170
171
172
173
 
174
175
176
...
193
194
195
196
 
197
198
199
...
161
162
163
 
164
165
166
167
...
170
171
172
 
173
174
175
176
...
193
194
195
 
196
197
198
199
0
@@ -161,7 +161,7 @@
0
   #
0
   #---
0
   # @semipublic
0
- def initialize(request, response = StringIO.new, status=200, headers={'Content-Type' => 'text/html; charset=utf-8'})
0
+ def initialize(request, , status=200, headers={'Content-Type' => 'text/html; charset=utf-8'})
0
     super()
0
     if request.params.key?(_session_id_key)
0
       # Checks to see if a route allows fixation:
0
@@ -170,7 +170,7 @@
0
         request.cookies[_session_id_key] = request.params[_session_id_key]
0
       end
0
     end
0
- @request, @response, @status, @headers = request, response, status, headers
0
+ @request, @status, @headers = request, status, headers
0
   end
0
   
0
   # Dispatch the action
0
@@ -193,7 +193,7 @@
0
     @_benchmarks[:action_time] = Time.now - start
0
   end
0
   
0
- attr_reader :request, :response, :headers
0
+ attr_reader :request, :, :headers
0
   attr_accessor :status
0
   
0
   # ==== Returns
...
1
2
3
4
 
 
 
5
6
7
8
...
34
35
36
 
37
38
39
 
 
 
40
41
42
43
...
44
45
46
47
 
 
48
49
50
51
52
53
 
 
54
55
56
...
61
62
63
64
 
 
65
66
67
...
77
78
79
 
80
81
82
83
...
111
112
113
114
115
 
116
117
 
118
119
120
...
122
123
124
125
 
126
127
128
...
140
141
142
 
143
144
145
...
1
2
3
 
4
5
6
7
8
9
10
...
36
37
38
39
40
 
 
41
42
43
44
45
46
47
...
48
49
50
 
51
52
53
54
55
56
 
 
57
58
59
60
61
...
66
67
68
 
69
70
71
72
73
...
83
84
85
86
87
88
89
90
...
118
119
120
 
 
121
122
 
123
124
125
126
...
128
129
130
 
131
132
133
134
...
146
147
148
149
150
151
152
0
@@ -1,7 +1,9 @@
0
 module Merb
0
   # Module that is mixed in to all implemented controllers.
0
   module ControllerMixin
0
-
0
+ def must_support_streaming!
0
+ raise(NotImplemented, "Current Rack adapter does not support streaming") unless request.env['rack.streaming']
0
+ end
0
     # Renders the block given as a parameter using chunked
0
     # encoding.
0
     #
0
0
@@ -34,9 +36,11 @@
0
     # send chunks of data down to the server. The chunking will
0
     # terminate once the block returns.
0
     def render_chunked(&blk)
0
+ must_support_streaming!
0
       headers['Transfer-Encoding'] = 'chunked'
0
- Proc.new {
0
- response.send_status_no_connection_close(0)
0
+ Proc.new { |response|
0
+ @response = response
0
+ response.send_status_no_connection_close('')
0
         response.send_header
0
         blk.call
0
         response.write("0\r\n\r\n")
0
0
@@ -44,13 +48,14 @@
0
     end
0
 
0
     # Writes a chunk from render_chunked to the response that
0
- # is sent back to the client.
0
+ # is sent back to the client. This can only be called within
0
+ # a render_chunked {} block
0
     #
0
     # ==== Parameters
0
     # data<String>:: a chunk of data to return
0
     def send_chunk(data)
0
- response.write('%x' % data.size + "\r\n")
0
- response.write(data + "\r\n")
0
+ @response.write('%x' % data.size + "\r\n")
0
+ @response.write(data + "\r\n")
0
     end
0
     
0
     # Returns a +Proc+ that Mongrel can call later, allowing
0
@@ -61,7 +66,8 @@
0
     # A proc that should get called outside the mutex,
0
     # and which will return the value to render
0
     def render_deferred(&blk)
0
- Proc.new {
0
+ must_support_streaming!
0
+ Proc.new {|response|
0
         result = blk.call
0
         response.send_status(result.length)
0
         response.send_header
0
@@ -77,6 +83,7 @@
0
     # blk<Proc>:: A proc that should get called once the string has
0
     # been returned
0
     def render_then_call(str, &blk)
0
+ must_support_streaming!
0
       Proc.new {
0
         response.send_status(str.length)
0
         response.send_header
0
0
@@ -111,10 +118,9 @@
0
       headers.update(
0
         'Content-Type' => opts[:type].strip, # fixes a problem with extra '\r' with some browsers
0
         'Content-Disposition' => disposition,
0
- 'Content-Transfer-Encoding' => 'binary',
0
- 'X-SENDFILE' => file
0
+ 'Content-Transfer-Encoding' => 'binary'
0
       )
0
- return
0
+ File.open(file)
0
     end
0
     
0
     # Streams a file over HTTP.
0
@@ -122,7 +128,7 @@
0
     # ==== Example
0
     # stream_file( { :filename => file_name,
0
     # :type => content_type,
0
- # :content_length => content_length }) do
0
+ # :content_length => content_length }) do |response|
0
     # AWS::S3::S3Object.stream(user.folder_name + "-" + user_file.unique_id, bucket_name) do |chunk|
0
     # response.write chunk
0
     # end
0
@@ -140,6 +146,7 @@
0
     # :filename<String>:: An acceptable value for the filename= portion
0
     # of headers["Content-Disposition"]
0
     def stream_file(opts={}, &stream)
0
+ must_support_streaming!
0
       opts.update(Merb::Const::DEFAULT_SEND_FILE_OPTIONS.merge(opts))
0
       disposition = opts[:disposition].dup || 'attachment'
0
       disposition << %(; filename="#{opts[:filename]}")
...
23
24
25
26
 
27
28
29
...
67
68
69
70
 
71
72
73
...
77
78
79
80
 
81
82
83
84
...
93
94
95
96
 
97
98
 
99
100
101
102
...
123
124
125
126
 
127
128
129
130
131
132
133
 
134
135
136
137
...
139
140
141
142
 
143
144
 
145
146
147
...
166
167
168
169
170
 
 
171
172
173
...
23
24
25
 
26
27
28
29
...
67
68
69
 
70
71
72
73
...
77
78
79
 
80
81
82
83
84
...
93
94
95
 
96
97
 
98
99
100
101
102
...
123
124
125
 
126
127
128
129
130
131
132
 
133
134
135
136
137
...
139
140
141
 
142
143
 
144
145
146
147
...
166
167
168
 
 
169
170
171
172
173
0
@@ -23,7 +23,7 @@
0
     # ==== Returns
0
     # Array[Merb::Controller, Symbol]::
0
     # An array containing the Merb::Controller and the action that was dispatched to.
0
- def handle(rack_env, response)
0
+ def handle(rack_env)
0
       start = Time.now
0
       request = Merb::Request.new(rack_env)
0
       Merb.logger.info("Params: #{request.params.inspect}")
0
@@ -67,7 +67,7 @@
0
 
0
       action = route_params[:action]
0
 
0
- controller = dispatch_action(klass, action, request, response)
0
+ controller = dispatch_action(klass, action, request)
0
       Merb.logger.info controller._benchmarks.inspect
0
       Merb.logger.flush
0
 
0
@@ -77,7 +77,7 @@
0
     rescue => exception
0
       Merb.logger.error(Merb.exception(exception))
0
       exception = controller_exception(exception)
0
- dispatch_exception(request, response, exception)
0
+ dispatch_exception(request, , exception)
0
     end
0
     
0
     private
0
0
@@ -93,9 +93,9 @@
0
     # ==== Returns
0
     # Array[Merb::Controller, Symbol]::
0
     # An array containing the Merb::Controller and the action that was dispatched to.
0
- def dispatch_action(klass, action, request, response, status=200)
0
+ def dispatch_action(klass, action, request, , status=200)
0
       # build controller
0
- controller = klass.new(request, response, status)
0
+ controller = klass.new(request, , status)
0
       if use_mutex
0
         @@mutex.synchronize { controller._dispatch(action) }
0
       else
0
0
@@ -123,14 +123,14 @@
0
     # An array containing the Merb::Controller and the name of the exception
0
     # that triggrered #dispatch_exception. For instance, a NotFound exception
0
     # will be "not_found".
0
- def dispatch_exception(request, response, exception)
0
+ def dispatch_exception(request, , exception)
0
       klass = ::Exceptions rescue Merb::Controller
0
       request.params[:original_params] = request.params.dup rescue {}
0
       request.params[:original_session] = request.session.dup rescue {}
0
       request.params[:original_cookies] = request.cookies.dup rescue {}
0
       request.params[:exception] = exception
0
       request.params[:action] = exception.name
0
- dispatch_action(klass, exception.name, request, response, exception.class::STATUS)
0
+ dispatch_action(klass, exception.name, request, , exception.class::STATUS)
0
     rescue => dispatch_issue
0
       dispatch_issue = controller_exception(dispatch_issue)
0
       # when no action/template exist for an exception, or an
0
0
@@ -139,9 +139,9 @@
0
       # ControllerExceptions raised from exception actions are
0
       # dispatched back into the Exceptions controller
0
       if dispatch_issue.is_a?(Merb::ControllerExceptions::NotFound)
0
- dispatch_default_exception(klass, request, response, exception)
0
+ dispatch_default_exception(klass, request, , exception)
0
       elsif dispatch_issue.is_a?(Merb::ControllerExceptions::InternalServerError)
0
- dispatch_default_exception(klass, request, response, dispatch_issue)
0
+ dispatch_default_exception(klass, request, , dispatch_issue)
0
       else
0
         exception = dispatch_issue
0
         retry
0
@@ -166,8 +166,8 @@
0
     # An array containing the Merb::Controller that was dispatched to
0
     # and the error's name. For instance, a NotFound error's name is
0
     # "not_found".
0
- def dispatch_default_exception(klass, request, response, e)
0
- controller = klass.new(request, response, e.class::STATUS)
0
+ def dispatch_default_exception(klass, request, e)
0
+ controller = klass.new(request, e.class::STATUS)
0
       if e.is_a? Merb::ControllerExceptions::Redirection
0
         controller.headers.merge!('Location' => e.message)
0
         controller.body = %{ } #fix
...
1
2
 
3
4
5
...
8
9
10
11
 
12
13
14
...
1
 
2
3
4
5
...
8
9
10
 
11
12
13
14
0
@@ -1,5 +1,5 @@
0
 require 'mongrel'
0
-require 'rack/handler/mongrel'
0
+require 'merb-core/rack/handler/mongrel'
0
 module Merb
0
 
0
   module Rack
0
@@ -8,7 +8,7 @@
0
       # start server on given host and port.
0
       def self.start(opts={})
0
         server = ::Mongrel::HttpServer.new(opts[:host], opts[:port])
0
- server.register('/', ::::Rack::Handler::Mongrel.new(opts[:app]))
0
+ server.register('/', ::Merb::Rack::Handler::Mongrel.new(opts[:app]))
0
         server.run.join
0
       end
0
     end
...
11
12
13
14
 
15
16
17
18
19
20
 
 
 
21
22
 
23
24
25
 
26
27
28
...
11
12
13
 
14
15
16
17
18
19
20
21
22
23
24
 
25
26
27
28
29
30
31
32
0
@@ -11,18 +11,22 @@
0
       def call(env)
0
         path = env['PATH_INFO'].chomp('/')
0
         cached_path = (path.empty? ? 'index' : path) + '.html'
0
-
0
+ Merb.logger.info "Request: #{path}"
0
         if file_exist?(path) # Serve the file if it's there
0
           serve_static(env)
0
         elsif file_exist?(cached_path) # Serve the page cache if it's there
0
           env['PATH_INFO'] = cached_path
0
           serve_static(env)
0
         else # No static file, let Merb handle it
0
+ if path =~ /favicon\.ico/
0
+ return [404, {"Content-Type"=>"text/html"}, "404 Not Founds."]
0
+ end
0
           begin
0
- controller = ::Merb::Dispatcher.handle(env, ::Rack::Response.new)
0
+ controller = ::Merb::Dispatcher.handle(env)
0
           rescue Object => e
0
             return [500, {"Content-Type"=>"text/html"}, e.message + "<br/>" + e.backtrace.join("<br/>")]
0
           end
0
+ Merb.logger.info "\n\n"
0
           Merb.logger.flush
0
           [controller.status, controller.headers, controller.body]
0
         end
...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
0
@@ -1 +1,77 @@
0
+require 'mongrel'
0
+require 'stringio'
0
+
0
+class Mongrel::HttpResponse
0
+ NO_CLOSE_STATUS_FORMAT = "HTTP/1.1 %d %s\r\n".freeze
0
+ def send_status_no_connection_close(content_length=@body.length)
0
+ unless @status_sent
0
+ write(NO_CLOSE_STATUS_FORMAT % [@status, Mongrel::HTTP_STATUS_CODES[@status]])
0
+ @status_sent = true
0
+ end
0
+ end
0
+end
0
+
0
+module Merb
0
+ module Rack
0
+ module Handler
0
+ class Mongrel < ::Mongrel::HttpHandler
0
+ def self.run(app, options={})
0
+ server = ::Mongrel::HttpServer.new(options[:Host] || '0.0.0.0',
0
+ options[:Port] || 8080)
0
+ server.register('/', ::Merb::Rack::Handler::Mongrel.new(app))
0
+ yield server if block_given?
0
+ server.run.join
0
+ end
0
+
0
+ def initialize(app)
0
+ @app = app
0
+ end
0
+
0
+ def process(request, response)
0
+ env = {}.replace(request.params)
0
+ env.delete "HTTP_CONTENT_TYPE"
0
+ env.delete "HTTP_CONTENT_LENGTH"
0
+
0
+ env["SCRIPT_NAME"] = "" if env["SCRIPT_NAME"] == "/"
0
+
0
+ env.update({"rack.version" => [0,1],
0
+ "rack.input" => request.body || StringIO.new(""),
0
+ "rack.errors" => STDERR,
0
+
0
+ "rack.multithread" => true,
0
+ "rack.multiprocess" => false, # ???
0
+ "rack.run_once" => false,
0
+
0
+ "rack.url_scheme" => "http",
0
+ "rack.streaming" => true
0
+ })
0
+ env["QUERY_STRING"] ||= ""
0
+ env.delete "PATH_INFO" if env["PATH_INFO"] == ""
0
+
0
+ status, headers, body = @app.call(env)
0
+
0
+ begin
0
+ response.status = status.to_i
0
+ headers.each { |k, vs|
0
+ vs.each { |v|
0
+ response.header[k] = v
0
+ }
0
+ }
0
+
0
+ if body.respond_to?(:call)
0
+ body.call(response)
0
+ else
0
+ body.each { |part|
0
+ response.body << part
0
+ }
0
+ end
0
+ response.finished
0
+ ensure
0
+ body.close if body.respond_to? :close
0
+ end
0
+ end
0
+ end
0
+ end
0
+ end
0
+end
...
9
10
11
12
 
13
14
15
...
9
10
11
 
12
13
14
15
0
@@ -9,7 +9,7 @@
0
 
0
   it "should handle return an Exceptions controller for a bad route request" do
0
     env = Rack::MockRequest.env_for("/notreal")
0
- Merb::Dispatcher.handle(env, StringIO.new).should be_kind_of Exceptions
0
+ Merb::Dispatcher.handle(env).should be_kind_of Exceptions
0
   end
0
 
0
 end
...
9
10
11
12
 
13
14
15
...
9
10
11
 
12
13
14
15
0
@@ -9,7 +9,7 @@
0
   before(:each) do
0
     env = Rack::MockRequest.env_for("/foo/bar/54")
0
     env['REQUEST_URI'] = "/foo/bar/54" # MockRequest doesn't set this
0
- @controller = Merb::Dispatcher.handle(env, StringIO.new)
0
+ @controller = Merb::Dispatcher.handle(env)
0
   end
0
 
0
   it "should properly set the route params" do

Comments

    No one has commented yet.