raw 0.49.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (148) hide show
  1. data/doc/CONTRIBUTORS +106 -0
  2. data/doc/LICENSE +32 -0
  3. data/doc/coding_conventions.txt +11 -0
  4. data/lib/raw.rb +42 -0
  5. data/lib/raw/adapter.rb +113 -0
  6. data/lib/raw/adapter/cgi.rb +41 -0
  7. data/lib/raw/adapter/fastcgi.rb +48 -0
  8. data/lib/raw/adapter/mongrel.rb +146 -0
  9. data/lib/raw/adapter/script.rb +94 -0
  10. data/lib/raw/adapter/webrick.rb +144 -0
  11. data/lib/raw/adapter/webrick/vcr.rb +91 -0
  12. data/lib/raw/cgi.rb +323 -0
  13. data/lib/raw/cgi/cookie.rb +47 -0
  14. data/lib/raw/cgi/http.rb +62 -0
  15. data/lib/raw/compiler.rb +138 -0
  16. data/lib/raw/compiler/filter/cleanup.rb +21 -0
  17. data/lib/raw/compiler/filter/elements.rb +166 -0
  18. data/lib/raw/compiler/filter/elements/element.rb +210 -0
  19. data/lib/raw/compiler/filter/localization.rb +23 -0
  20. data/lib/raw/compiler/filter/markup.rb +32 -0
  21. data/lib/raw/compiler/filter/morph.rb +123 -0
  22. data/lib/raw/compiler/filter/morph/each.rb +34 -0
  23. data/lib/raw/compiler/filter/morph/for.rb +11 -0
  24. data/lib/raw/compiler/filter/morph/if.rb +26 -0
  25. data/lib/raw/compiler/filter/morph/selected_if.rb +43 -0
  26. data/lib/raw/compiler/filter/morph/standard.rb +55 -0
  27. data/lib/raw/compiler/filter/morph/times.rb +27 -0
  28. data/lib/raw/compiler/filter/script.rb +116 -0
  29. data/lib/raw/compiler/filter/squeeze.rb +16 -0
  30. data/lib/raw/compiler/filter/static_include.rb +74 -0
  31. data/lib/raw/compiler/filter/template.rb +121 -0
  32. data/lib/raw/compiler/reloader.rb +96 -0
  33. data/lib/raw/context.rb +154 -0
  34. data/lib/raw/context/flash.rb +157 -0
  35. data/lib/raw/context/global.rb +88 -0
  36. data/lib/raw/context/request.rb +338 -0
  37. data/lib/raw/context/response.rb +57 -0
  38. data/lib/raw/context/session.rb +198 -0
  39. data/lib/raw/context/session/drb.rb +11 -0
  40. data/lib/raw/context/session/file.rb +15 -0
  41. data/lib/raw/context/session/memcached.rb +13 -0
  42. data/lib/raw/context/session/memory.rb +12 -0
  43. data/lib/raw/context/session/og.rb +15 -0
  44. data/lib/raw/context/session/pstore.rb +13 -0
  45. data/lib/raw/control.rb +18 -0
  46. data/lib/raw/control/attribute.rb +91 -0
  47. data/lib/raw/control/attribute/checkbox.rb +25 -0
  48. data/lib/raw/control/attribute/datetime.rb +21 -0
  49. data/lib/raw/control/attribute/file.rb +20 -0
  50. data/lib/raw/control/attribute/fixnum.rb +26 -0
  51. data/lib/raw/control/attribute/float.rb +26 -0
  52. data/lib/raw/control/attribute/options.rb +38 -0
  53. data/lib/raw/control/attribute/password.rb +16 -0
  54. data/lib/raw/control/attribute/text.rb +16 -0
  55. data/lib/raw/control/attribute/textarea.rb +16 -0
  56. data/lib/raw/control/none.rb +16 -0
  57. data/lib/raw/control/relation.rb +59 -0
  58. data/lib/raw/control/relation/belongs_to.rb +0 -0
  59. data/lib/raw/control/relation/has_many.rb +97 -0
  60. data/lib/raw/control/relation/joins_many.rb +0 -0
  61. data/lib/raw/control/relation/many_to_many.rb +0 -0
  62. data/lib/raw/control/relation/refers_to.rb +29 -0
  63. data/lib/raw/controller.rb +37 -0
  64. data/lib/raw/controller/publishable.rb +160 -0
  65. data/lib/raw/dispatcher.rb +209 -0
  66. data/lib/raw/dispatcher/format.rb +108 -0
  67. data/lib/raw/dispatcher/format/atom.rb +31 -0
  68. data/lib/raw/dispatcher/format/css.rb +0 -0
  69. data/lib/raw/dispatcher/format/html.rb +42 -0
  70. data/lib/raw/dispatcher/format/json.rb +31 -0
  71. data/lib/raw/dispatcher/format/rss.rb +33 -0
  72. data/lib/raw/dispatcher/format/xoxo.rb +31 -0
  73. data/lib/raw/dispatcher/mounter.rb +60 -0
  74. data/lib/raw/dispatcher/router.rb +111 -0
  75. data/lib/raw/errors.rb +19 -0
  76. data/lib/raw/helper.rb +86 -0
  77. data/lib/raw/helper/benchmark.rb +23 -0
  78. data/lib/raw/helper/buffer.rb +60 -0
  79. data/lib/raw/helper/cookie.rb +32 -0
  80. data/lib/raw/helper/debug.rb +28 -0
  81. data/lib/raw/helper/default.rb +16 -0
  82. data/lib/raw/helper/feed.rb +451 -0
  83. data/lib/raw/helper/form.rb +284 -0
  84. data/lib/raw/helper/javascript.rb +59 -0
  85. data/lib/raw/helper/layout.rb +40 -0
  86. data/lib/raw/helper/navigation.rb +87 -0
  87. data/lib/raw/helper/pager.rb +305 -0
  88. data/lib/raw/helper/table.rb +247 -0
  89. data/lib/raw/helper/xhtml.rb +218 -0
  90. data/lib/raw/helper/xml.rb +125 -0
  91. data/lib/raw/mixin/magick.rb +35 -0
  92. data/lib/raw/mixin/sweeper.rb +71 -0
  93. data/lib/raw/mixin/thumbnails.rb +1 -0
  94. data/lib/raw/mixin/webfile.rb +165 -0
  95. data/lib/raw/render.rb +271 -0
  96. data/lib/raw/render/builder.rb +26 -0
  97. data/lib/raw/render/caching.rb +81 -0
  98. data/lib/raw/render/call.rb +43 -0
  99. data/lib/raw/render/send_file.rb +46 -0
  100. data/lib/raw/render/stream.rb +39 -0
  101. data/lib/raw/scaffold.rb +13 -0
  102. data/lib/raw/scaffold/controller.rb +25 -0
  103. data/lib/raw/scaffold/model.rb +157 -0
  104. data/lib/raw/test.rb +5 -0
  105. data/lib/raw/test/assertions.rb +169 -0
  106. data/lib/raw/test/context.rb +55 -0
  107. data/lib/raw/test/testcase.rb +79 -0
  108. data/lib/raw/util/attr.rb +128 -0
  109. data/lib/raw/util/encode_uri.rb +149 -0
  110. data/lib/raw/util/html_filter.rb +538 -0
  111. data/lib/raw/util/markup.rb +130 -0
  112. data/test/glue/tc_webfile.rb +1 -0
  113. data/test/nitro/CONFIG.rb +3 -0
  114. data/test/nitro/adapter/raw_post1.bin +9 -0
  115. data/test/nitro/adapter/tc_webrick.rb +16 -0
  116. data/test/nitro/cgi/tc_cookie.rb +14 -0
  117. data/test/nitro/cgi/tc_request.rb +61 -0
  118. data/test/nitro/compiler/tc_client_morpher.rb +47 -0
  119. data/test/nitro/compiler/tc_compiler.rb +25 -0
  120. data/test/nitro/dispatcher/tc_mounter.rb +47 -0
  121. data/test/nitro/helper/tc_feed.rb +135 -0
  122. data/test/nitro/helper/tc_navbar.rb +74 -0
  123. data/test/nitro/helper/tc_pager.rb +35 -0
  124. data/test/nitro/helper/tc_table.rb +68 -0
  125. data/test/nitro/helper/tc_xhtml.rb +19 -0
  126. data/test/nitro/tc_caching.rb +19 -0
  127. data/test/nitro/tc_cgi.rb +222 -0
  128. data/test/nitro/tc_context.rb +17 -0
  129. data/test/nitro/tc_controller.rb +103 -0
  130. data/test/nitro/tc_controller_aspect.rb +32 -0
  131. data/test/nitro/tc_controller_params.rb +885 -0
  132. data/test/nitro/tc_dispatcher.rb +109 -0
  133. data/test/nitro/tc_element.rb +85 -0
  134. data/test/nitro/tc_flash.rb +59 -0
  135. data/test/nitro/tc_helper.rb +47 -0
  136. data/test/nitro/tc_render.rb +119 -0
  137. data/test/nitro/tc_router.rb +61 -0
  138. data/test/nitro/tc_server.rb +35 -0
  139. data/test/nitro/tc_session.rb +66 -0
  140. data/test/nitro/tc_template.rb +71 -0
  141. data/test/nitro/util/tc_encode_url.rb +87 -0
  142. data/test/nitro/util/tc_markup.rb +31 -0
  143. data/test/public/blog/another/very_litle/index.xhtml +1 -0
  144. data/test/public/blog/inc1.xhtml +2 -0
  145. data/test/public/blog/inc2.xhtml +1 -0
  146. data/test/public/blog/list.xhtml +9 -0
  147. data/test/public/dummy_mailer/registration.xhtml +5 -0
  148. metadata +244 -0
@@ -0,0 +1,106 @@
1
+ LEAD DEVELOPER:
2
+
3
+ * George K. Moschovitis <george.moschovitis@gmail.com>
4
+ Project leader, architecture and design, main coder,
5
+ documentation, maintainer (http://www.gmosx.com).
6
+
7
+
8
+ TEAM NITRO:
9
+
10
+ Team Nitro is group of important contributors to the project.
11
+
12
+ * Jonas Pfenniger <zimba.tm@gmail.com>
13
+ Patches, new features, bug fixes.
14
+
15
+ * Bryan Soto <bryan.a.soto@gmail.com>
16
+ Patches, bug fixes, docs, quality assurance, community
17
+ management.
18
+
19
+ * Guillaume Pierronnet <guillaume.pierronnet@laposte.net>
20
+ Patches, new features, bug fixes.
21
+
22
+ * Thomas Sawyer <transfire@gmail.com>
23
+ Small bug fixes, patches.
24
+
25
+ * Jonathan Buch <jonathan.buch@gmail.net>
26
+ Patches, documentation.
27
+
28
+ * Fabian Buch <fabian@fabian-buch.de>
29
+ FeedHelper, various patches.
30
+
31
+ * Michael Fellinger <m.fellinger@gmail.com>
32
+ Patches, bug fixes.
33
+
34
+ IDEAS, ADDITIONAL CODING, SUPPORT:
35
+
36
+ * Rob Pitt <rob@motionpath.co.uk>
37
+ Patches, Bug fixes, Scaffolding improvements.
38
+
39
+ * Chris Farmiloe <chris.farmiloe@farmiloe.com>
40
+ Patches, new features, bug fixes.
41
+
42
+ * Aidan Rogers <aidan@infurious.com>
43
+ Documentation, Bug reports, patches.
44
+
45
+ * James Britt <james_b@neurogami.com>
46
+ Evangelising, documentation, design, additional code, bug reports.
47
+
48
+ * Aleksi Niemela <Aleksi.Niemela@cs.helsinki.fi>
49
+ Bug fixes, patches, documentation.
50
+
51
+ * Brian Bugh <brian@xsi-design.com>
52
+ Fixes, Patches.
53
+
54
+ * Gabriele Renzi <surrender_it@yahoo.it>
55
+ Patches, new features.
56
+
57
+ * Fang Sun <nusgnaf@gmail.com>
58
+ Patches.
59
+
60
+ * <neokolor@gmx.de>
61
+ Patches.
62
+
63
+ * Zed A. Shaw <zedshaw@zedshaw.com>
64
+ SCGI adapter.
65
+
66
+ * Peter Abrahamsen <rainhead@gmail.com>
67
+ Documentation, small patches.
68
+
69
+ * Massimo Maria Ghisalberti
70
+ Patches.
71
+
72
+ * John A. Lambert
73
+ Patches.
74
+
75
+ * Dan Yoder <dan@zeraweb.com>
76
+ Original 'Elements' implementation, bug reports.
77
+
78
+ * Joshua Hoke
79
+ Patches.
80
+
81
+ * Michael Neumann <mneumann@ntecs.de>
82
+ Wee integration, patches.
83
+
84
+ * Alexander Lazic <al-nitrogen@none.at>
85
+ Patches, bug reports.
86
+
87
+ * Darrick W <darrick@innatesoftware.com>
88
+ Patches.
89
+
90
+ * Anastasios Koutoumanos <ak@navel.gr>
91
+ Ideas, bug reports.
92
+
93
+ * Kostas Nasis <kostas@nasis.com>
94
+ Ideas and bug reports.
95
+
96
+
97
+ DONATIONS:
98
+
99
+ The following people have genereously donated money for the
100
+ advancement of the Nitro project:
101
+
102
+ * Jonas Pfenniger <zimba.tm@gmail.com>
103
+
104
+ * Emmanuel Piperakis
105
+
106
+ * Matt Bowen <matt.bowen@farweststeel.com>
@@ -0,0 +1,32 @@
1
+ The BSD License
2
+
3
+ Copyright (c) 2004-2007, George K. Moschovitis. (http://www.gmosx.com)
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are
8
+ met:
9
+
10
+ * Redistributions of source code must retain the above copyright
11
+ notice, this list of conditions and the following disclaimer.
12
+
13
+ * Redistributions in binary form must reproduce the above copyright
14
+ notice, this list of conditions and the following disclaimer in the
15
+ documentation and/or other materials provided with the distribution.
16
+
17
+ * Neither the name of Nitro nor the names of its contributors may be
18
+ used to endorse or promote products derived from this software
19
+ without specific prior written permission.
20
+
21
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27
+ TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
+
@@ -0,0 +1,11 @@
1
+ Coding conventions:
2
+
3
+ * Use two spaces for identation.
4
+ * Try to make the source code lines less than 64 chars wide. This
5
+ improves the visibility. But please, do not go out of the way
6
+ (artificially breaking your code) to enforce this rule.
7
+ * Use "" as delimeter for both static and dynamic strings.
8
+ * Use
9
+ alias :new :old
10
+ instead of
11
+ alias_method :new, :old
@@ -0,0 +1,42 @@
1
+ # = Raw, Rapid Applications for the Web
2
+ #
3
+ # Copyright (c) 2004-2007, George Moschovitis (http://www.gmosx.com)
4
+ #
5
+ # Raw (http://www.nitroproject.org) is copyrighted free software
6
+ # created and maintained by George Moschovitis
7
+ # (mailto:george.moschovitis@gmail.com) and released under the
8
+ # standard BSD Licence. For details consult the file doc/LICENCE.
9
+
10
+ module Raw
11
+ # The version of Raw.
12
+
13
+ Version = "0.50.0"
14
+
15
+ # Library path.
16
+
17
+ LibPath = File.dirname(__FILE__)
18
+
19
+ # The Mixin namespace
20
+
21
+ module Mixin; end
22
+
23
+ # Include the Mixin namespace.
24
+
25
+ include Mixin
26
+ end
27
+
28
+ # Include Raw::Mixin in the TopLevel for extra convienience.
29
+
30
+ include Raw::Mixin unless $NITRO_DONT_INCLUDE_MIXINS
31
+
32
+ #--
33
+ # gmosx: leave them here.
34
+ #++
35
+
36
+ require "raw/errors"
37
+ require "raw/context"
38
+ require "raw/context/global"
39
+ require "raw/controller"
40
+ require "raw/dispatcher"
41
+ require "raw/render"
42
+ require "raw/scaffold"
@@ -0,0 +1,113 @@
1
+ require "cgi"
2
+ require "socket"
3
+
4
+ require "facets/core/string/demodulize"
5
+ require "facets/core/string/underscore"
6
+ require "facets/core/string/humanize"
7
+
8
+ require "raw/cgi"
9
+
10
+ # Speeds things up, more compatible with OSX.
11
+
12
+ Socket.do_not_reverse_lookup = true
13
+
14
+ module Raw
15
+
16
+ # The base Adapter class. All other adapters extend this class.
17
+ # An adapter conceptually connects Nitro with a Front Web Server.
18
+ # Please notice that many Adapters (for example Webrick and
19
+ # Mongrel implement an 'inline' Front Web Server).
20
+ #
21
+ # The Adapter typically initializes a Handler to handle the
22
+ # http requests.
23
+
24
+ class Adapter
25
+
26
+ # Initialize the adapter.
27
+
28
+ def initialize
29
+ end
30
+
31
+ # Setup the adapter (used as a hook).
32
+
33
+ def setup(app)
34
+ end
35
+
36
+ # Start the adapter.
37
+
38
+ def start(app)
39
+ info "Starting #{self.class.name.demodulize.underscore.humanize} on #{app.address}:#{app.port}"
40
+ info "Press Ctrl-C to shutdown; Run with --help for options."
41
+
42
+ setup(app)
43
+ end
44
+
45
+ # Stop the adapter.
46
+
47
+ def stop
48
+ info "Stoping #{self.class.name.demodulize.underscore.humanize}."
49
+ end
50
+
51
+ end
52
+
53
+ # This mixin provides default functionality to adapter handlers.
54
+
55
+ module AdapterHandlerMixin
56
+
57
+ # Handle a context. Returns the generated output.
58
+
59
+ def handle_context(context)
60
+ Cgi.parse_params(context)
61
+ Cgi.parse_cookies(context)
62
+
63
+ controller, action, query, params, ext = @application.dispatcher.dispatch_context(context)
64
+ context.content_type = context.format.content_type
65
+
66
+ Thread.current[:CURRENT_CONTROLLER] = controller
67
+ controller = controller.new(context)
68
+
69
+ controller.send(action, params)
70
+ # res.chunked = true if controller.out.is_a?(IO) and context["SERVER_PROTOCOL"] == "HTTP/1.1"
71
+ rescue RenderExit, ActionExit => e1
72
+ # Just stop rendering.
73
+
74
+ rescue ActionError => e2
75
+ # Client Error family of errors, typically send 4XX
76
+ # status code.
77
+ debug e2.to_s if $DBG
78
+
79
+ rescue Object => e3
80
+ # Server Error family of errors, typically send 5XX
81
+ # status code.
82
+ error "Error while handling '#{context.uri}'"
83
+ error pp_exception(e3)
84
+
85
+ ensure
86
+ Og.manager.put_store if defined?(Og) and Og.respond_to?(:manager) and Og.manager
87
+ return context.output_buffer
88
+ end
89
+
90
+ # Try to rewrite the path to a filename.
91
+
92
+ def rewrite(req)
93
+ if req.path_info == "/"
94
+ req.path_info = "/index.html"
95
+ elsif req.path_info =~ /^([^.]+)$/
96
+ req.path_info = "#{$1}.html"
97
+ end
98
+ end
99
+
100
+ # Rewrite back to the original path.
101
+
102
+ def unrewrite(req)
103
+ if req.path_info == "/index.html"
104
+ req.path_info = "/"
105
+ elsif req.path_info =~ /^([^.]+)\.html$/
106
+ req.path_info = $1
107
+ end
108
+ end
109
+
110
+ end
111
+
112
+
113
+ end
@@ -0,0 +1,41 @@
1
+ require "cgi"
2
+ require "stringio"
3
+ require "tempfile"
4
+
5
+ require "raw/adapter"
6
+
7
+ #--
8
+ # Adapt the default CGI object to suit Nitro.
9
+ #++
10
+
11
+ class CGI # :nodoc: all
12
+ def env
13
+ ENV
14
+ end
15
+ end
16
+
17
+ # No multi-threading.
18
+
19
+ Og.thread_safe = false if defined?(Og) and Og.respond_to?(:thread_safe)
20
+
21
+ module Raw
22
+
23
+ # A plain CGI adapter. To be used only in development
24
+ # environments, this adapter is *extremely* slow for
25
+ # live/production environments. This adapter is provided for
26
+ # the sake of completeness.
27
+
28
+ class CgiAdapter
29
+ #--
30
+ # No need for connection pooling, CGI uses process.
31
+ #++
32
+
33
+ def self.start(server)
34
+ cgi = CGI.new
35
+ Router.strip_path = cgi.env["SCRIPT_NAME"]
36
+ Cgi.process(server, cgi, $stdin, $stdout)
37
+ end
38
+
39
+ end
40
+
41
+ end
@@ -0,0 +1,48 @@
1
+ require 'cgi'
2
+ require 'fcgi'
3
+
4
+ require "raw/context"
5
+ require "raw/dispatcher"
6
+ require "raw/cgi"
7
+
8
+ # Speeds things up, more comaptible with OSX.
9
+
10
+ Socket.do_not_reverse_lookup = true
11
+
12
+ # No multi-threading.
13
+
14
+ Og.thread_safe = false if defined?(Og) and Og.respond_to?(:thread_safe)
15
+
16
+ module Raw
17
+
18
+ # FastCGI Adaptor. FastCGI is a language independent,
19
+ # scalable, open extension to CGI that provides high
20
+ # performance without the limitations of server
21
+ # specific APIs.
22
+ #
23
+ # === Sessions
24
+ #
25
+ # As FCGI is process based, you have can't use the default
26
+ # in-memory session store. For production web sites you should
27
+ # use the drb session store. Moreover, there is no need for
28
+ # DB connection pooling in Og.
29
+ #
30
+ #--
31
+ # gmosx: I always thought that the concept of FastCGI is stupid!
32
+ # Why don't you use a proxy setup? (For example Apache + Mongrel)
33
+ #++
34
+
35
+ class FastCGI
36
+
37
+ def self.start(server)
38
+ FCGI.each do |cgi|
39
+ begin
40
+ Cgi.process(server, cgi, cgi.in, cgi.out)
41
+ cgi.finish
42
+ end
43
+ end
44
+ end
45
+
46
+ end
47
+
48
+ end
@@ -0,0 +1,146 @@
1
+ require "stringio"
2
+
3
+ require "mongrel"
4
+ require "mongrel/handlers"
5
+
6
+ require "raw/adapter"
7
+
8
+ #--
9
+ # Customize Mongrel to make compatible with Nitro.
10
+ #++
11
+
12
+ module Mongrel # :nodoc: all
13
+
14
+ class HttpRequest
15
+ def method_missing(name, *args)
16
+ if @params.has_key?(name.to_s.upcase)
17
+ return @params[name.to_s.upcase]
18
+ elsif name.to_s =~ /\A(.*)=\Z/ && @params.has_key?($1.upcase)
19
+ @params[$1.upcase] = args[0]
20
+ else
21
+ super
22
+ end
23
+ end
24
+ end
25
+
26
+ end
27
+
28
+ module Raw
29
+
30
+ # A Mongrel Adapter.
31
+ #
32
+ # Mongrel is a fast HTTP library and server for Ruby that is
33
+ # intended for hosting Ruby web applications of any kind using
34
+ # plain HTTP rather than FastCGI or SCGI.
35
+ #
36
+ # This is the preferred adapter for production Nitro
37
+ # applications.
38
+
39
+ class MongrelAdapter < Adapter
40
+
41
+ def start(application)
42
+ super
43
+
44
+ @mongrel = Mongrel::Configurator.new(:host => application.address) do
45
+ listener(:port => application.port) do
46
+ uri "/", :handler => MongrelHandler.new(application)
47
+ trap("INT") { stop(application) }
48
+ run
49
+ end
50
+ end
51
+
52
+ @mongrel.join()
53
+ end
54
+
55
+ def stop
56
+ super
57
+ @mongrel.stop()
58
+ end
59
+
60
+ end
61
+
62
+ # The Mongrel Handler, handles an HTTP request.
63
+
64
+ class MongrelHandler < Mongrel::HttpHandler
65
+ include AdapterHandlerMixin
66
+
67
+ def initialize(application)
68
+ @application = application
69
+ end
70
+
71
+ # Handle a static file. Also handles cached pages. Typically
72
+ # *not* used in production applications.
73
+
74
+ def handle_file(req, res)
75
+ return false unless @application.handle_static_files
76
+
77
+ filename = File.join(@application.public_dir, req.path_info).squeeze("/")
78
+
79
+ File.open(filename, "rb") do |f|
80
+ # TODO: check whether path circumvents public_root directory?
81
+ res.status = 200
82
+ res.body << f.read # XXX inefficient for large files, may cause leaks
83
+ end
84
+
85
+ return true
86
+ rescue Errno::ENOENT => ex # TODO: Lookup Win32 error for 'file missing'
87
+ return false
88
+ end
89
+
90
+ # Handle the request.
91
+ #--
92
+ # TODO: recode this like the camping mongrel handler.
93
+ #++
94
+
95
+ def process(req, res)
96
+ # Perform default rewriting rules.
97
+
98
+ rewrite(req)
99
+
100
+ # First, try to serve a static file from disk.
101
+
102
+ return if handle_file(req, res)
103
+
104
+ context = Context.new(@application)
105
+
106
+ if req.body.is_a? String
107
+ context.in = StringIO.new(req.body)
108
+ else
109
+ context.in = req.body
110
+ end
111
+
112
+ context.headers = {}
113
+ req.params.each { |h, v|
114
+ if h =~ /\AHTTP_(.*)\Z/
115
+ context.headers[$1.gsub("_", "-")] = v
116
+ end
117
+ context.headers[h] = v
118
+ }
119
+
120
+ # hackfix: make it behave like webrick and fcgi
121
+ context.headers["REQUEST_URI"] << "?#{context.headers['QUERY_STRING']}" if context.headers["QUERY_STRING"]
122
+ context.headers["QUERY_STRING"] ||= ""
123
+
124
+ output = handle_context(context)
125
+
126
+ # THINK: what is the error code if a request without a handler
127
+ # is comming?!
128
+
129
+ res.start(context.status, true) do |head, out|
130
+ context.response_headers.each do |key, value|
131
+ head[key] = value
132
+ end
133
+
134
+ context.response_cookies.each do |cookie|
135
+ head["Set-Cookie"] = cookie
136
+ end if context.response_cookies
137
+
138
+ out.write(output)
139
+ end
140
+
141
+ context.close
142
+ end
143
+
144
+ end
145
+
146
+ end