bmarzolf-picnic 0.8.0.20090420

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/CHANGELOG.txt +1 -0
  2. data/History.txt +78 -0
  3. data/LICENSE.txt +165 -0
  4. data/Manifest.txt +45 -0
  5. data/README.txt +31 -0
  6. data/Rakefile +64 -0
  7. data/lib/picnic/authentication.rb +254 -0
  8. data/lib/picnic/cli.rb +165 -0
  9. data/lib/picnic/conf.rb +135 -0
  10. data/lib/picnic/controllers.rb +4 -0
  11. data/lib/picnic/logger.rb +41 -0
  12. data/lib/picnic/server.rb +99 -0
  13. data/lib/picnic/service_control.rb +274 -0
  14. data/lib/picnic/version.rb +9 -0
  15. data/lib/picnic.rb +11 -0
  16. data/setup.rb +1585 -0
  17. data/test/picnic_test.rb +11 -0
  18. data/test/test_helper.rb +2 -0
  19. data/vendor/camping-2.0.20090420/CHANGELOG +118 -0
  20. data/vendor/camping-2.0.20090420/COPYING +18 -0
  21. data/vendor/camping-2.0.20090420/README +82 -0
  22. data/vendor/camping-2.0.20090420/Rakefile +180 -0
  23. data/vendor/camping-2.0.20090420/bin/camping +97 -0
  24. data/vendor/camping-2.0.20090420/doc/camping.1.gz +0 -0
  25. data/vendor/camping-2.0.20090420/examples/README +5 -0
  26. data/vendor/camping-2.0.20090420/examples/blog.rb +375 -0
  27. data/vendor/camping-2.0.20090420/examples/campsh.rb +629 -0
  28. data/vendor/camping-2.0.20090420/examples/tepee.rb +242 -0
  29. data/vendor/camping-2.0.20090420/extras/Camping.gif +0 -0
  30. data/vendor/camping-2.0.20090420/extras/permalink.gif +0 -0
  31. data/vendor/camping-2.0.20090420/lib/camping/ar/session.rb +132 -0
  32. data/vendor/camping-2.0.20090420/lib/camping/ar.rb +78 -0
  33. data/vendor/camping-2.0.20090420/lib/camping/mab.rb +26 -0
  34. data/vendor/camping-2.0.20090420/lib/camping/reloader.rb +184 -0
  35. data/vendor/camping-2.0.20090420/lib/camping/server.rb +159 -0
  36. data/vendor/camping-2.0.20090420/lib/camping/session.rb +75 -0
  37. data/vendor/camping-2.0.20090420/lib/camping-unabridged.rb +630 -0
  38. data/vendor/camping-2.0.20090420/lib/camping.rb +52 -0
  39. data/vendor/camping-2.0.20090420/setup.rb +1551 -0
  40. data/vendor/camping-2.0.20090420/test/apps/env_debug.rb +65 -0
  41. data/vendor/camping-2.0.20090420/test/apps/forms.rb +95 -0
  42. data/vendor/camping-2.0.20090420/test/apps/misc.rb +86 -0
  43. data/vendor/camping-2.0.20090420/test/apps/sessions.rb +38 -0
  44. data/vendor/camping-2.0.20090420/test/test_camping.rb +54 -0
  45. metadata +140 -0
@@ -0,0 +1,159 @@
1
+ require 'irb'
2
+ require 'rack'
3
+ require 'camping/reloader'
4
+
5
+ # TODO: I guess we should documentate this too...
6
+ class Camping::Server
7
+ attr_reader :reloader
8
+ attr_accessor :conf
9
+
10
+ def initialize(conf, paths)
11
+ @conf = conf
12
+ @paths = paths
13
+ @reloader = Camping::Reloader.new
14
+ connect(@conf.database) if @conf.database
15
+ end
16
+
17
+ def connect(db)
18
+ unless Camping.autoload?(:Models)
19
+ Camping::Models::Base.establish_connection(db)
20
+ end
21
+ end
22
+
23
+ def find_scripts
24
+ scripts = @paths.map do |path|
25
+ case
26
+ when File.file?(path)
27
+ path
28
+ when File.directory?(path)
29
+ Dir[File.join(path, '*.rb')]
30
+ end
31
+ end.flatten.compact
32
+ @reloader.update(*scripts)
33
+ end
34
+
35
+ def index_page(apps)
36
+ welcome = "You are Camping"
37
+ header = <<-HTML
38
+ <html>
39
+ <head>
40
+ <title>#{welcome}</title>
41
+ <style type="text/css">
42
+ body {
43
+ font-family: verdana, arial, sans-serif;
44
+ padding: 10px 40px;
45
+ margin: 0;
46
+ }
47
+ h1, h2, h3, h4, h5, h6 {
48
+ font-family: utopia, georgia, serif;
49
+ }
50
+ </style>
51
+ </head>
52
+ <body>
53
+ <h1>#{welcome}</h1>
54
+ HTML
55
+ footer = '</body></html>'
56
+ main = if apps.empty?
57
+ "<p>Good day. I'm sorry, but I could not find any Camping apps."\
58
+ "You might want to take a look at the console to see if any errors"\
59
+ "have been raised</p>"
60
+ else
61
+ "<p>Good day. These are the Camping apps you've mounted.</p><ul>" +
62
+ apps.map do |mount, app|
63
+ "<li><h3 style=\"display: inline\"><a href=\"/#{mount}\">#{app}</a></h3><small> / <a href=\"/code/#{mount}\">View source</a></small></li>"
64
+ end.join("\n") + '</ul>'
65
+ end
66
+
67
+ header + main + footer
68
+ end
69
+
70
+ def app
71
+ reload!
72
+ all_apps = apps
73
+ rapp = case all_apps.length
74
+ when 0
75
+ proc{|env|[200,{'Content-Type'=>'text/html'},index_page([])]}
76
+ when 1
77
+ apps.values.first
78
+ else
79
+ hash = {
80
+ "/" => proc {|env|[200,{'Content-Type'=>'text/html'},index_page(all_apps)]}
81
+ }
82
+ all_apps.each do |mount, wrapp|
83
+ # We're doing @reloader.reload! ourself, so we don't need the wrapper.
84
+ app = wrapp.app
85
+ hash["/#{mount}"] = app
86
+ hash["/code/#{mount}"] = proc do |env|
87
+ [200,{'Content-Type'=>'text/plain','X-Sendfile'=>wrapp.script.file},'']
88
+ end
89
+ end
90
+ Rack::URLMap.new(hash)
91
+ end
92
+ rapp = Rack::ContentLength.new(rapp)
93
+ rapp = Rack::Lint.new(rapp)
94
+ rapp = XSendfile.new(rapp)
95
+ rapp = Rack::ShowExceptions.new(rapp)
96
+ end
97
+
98
+ def apps
99
+ @reloader.apps.inject({}) do |h, (mount, wrapp)|
100
+ h[mount.to_s.downcase] = wrapp
101
+ h
102
+ end
103
+ end
104
+
105
+ def call(env)
106
+ app.call(env)
107
+ end
108
+
109
+ def start
110
+ handler, conf = case @conf.server
111
+ when "console"
112
+ puts "** Starting console"
113
+ reload!
114
+ this = self; eval("self", TOPLEVEL_BINDING).meta_def(:reload!) { this.reload!; nil }
115
+ ARGV.clear
116
+ IRB.start
117
+ exit
118
+ when "mongrel"
119
+ puts "** Starting Mongrel on #{@conf.host}:#{@conf.port}"
120
+ [Rack::Handler::Mongrel, {:Port => @conf.port, :Host => @conf.host}]
121
+ when "webrick"
122
+ puts "** Starting WEBrick on #{@conf.host}:#{@conf.port}"
123
+ [Rack::Handler::WEBrick, {:Port => @conf.port, :BindAddress => @conf.host}]
124
+ end
125
+
126
+ handler.run(self, conf)
127
+ end
128
+
129
+ def reload!
130
+ find_scripts
131
+ @reloader.reload!
132
+ end
133
+
134
+ # A Rack middleware for reading X-Sendfile. Should only be used in
135
+ # development.
136
+ class XSendfile
137
+
138
+ HEADERS = [
139
+ "X-Sendfile",
140
+ "X-Accel-Redirect",
141
+ "X-LIGHTTPD-send-file"
142
+ ]
143
+
144
+ def initialize(app)
145
+ @app = app
146
+ end
147
+
148
+ def call(env)
149
+ status, headers, body = @app.call(env)
150
+ headers = Rack::Utils::HeaderHash.new(headers)
151
+ if header = HEADERS.detect { |header| headers.include?(header) }
152
+ path = headers[header]
153
+ body = File.read(path)
154
+ headers['Content-Length'] = body.length.to_s
155
+ end
156
+ [status, headers, body]
157
+ end
158
+ end
159
+ end
@@ -0,0 +1,75 @@
1
+ # == About camping/session.rb
2
+ # TODO: Clean everything up. Lots of just plain wrong stuff in here.
3
+ #
4
+ # This file contains two modules which supply basic sessioning to your Camping app.
5
+ # Again, we're dealing with a pretty little bit of code: approx. 60 lines.
6
+ #
7
+ # * Camping::Models::Session is a module which adds a single <tt>sessions</tt> table
8
+ # to your database.
9
+ # * Camping::Session is a module which you will mix into your application (or into
10
+ # specific controllers which require sessions) to supply a <tt>@state</tt> variable
11
+ # you can use in controllers and views.
12
+ #
13
+ # For a basic tutorial, see the *Getting Started* section of the Camping::Session module.
14
+ #require 'camping'
15
+ require 'base64'
16
+ require 'openssl'
17
+
18
+ module Camping
19
+ # The Camping::Session module is designed to be mixed into your application or into specific
20
+ # controllers which require sessions. This module defines a <tt>service</tt> method which
21
+ # intercepts all requests handed to those controllers.
22
+ #
23
+ # == Getting Started
24
+ #
25
+ # To get sessions working for your application:
26
+ #
27
+ # 1. <tt>require 'camping/session'</tt>
28
+ # 2. Mixin the module: <tt>module YourApp; include Camping::Session end</tt>
29
+ # 3. Define a secret (and keep it secret): <tt>module YourApp; @@state_secret = "SECRET!"; end</tt>
30
+ # 4. Throughout your application, use the <tt>@state</tt> var like a hash to store your application's data.
31
+ #
32
+ # == A Few Notes
33
+ #
34
+ # * The session is stored in a cookie. Look in <tt>@cookies.identity</tt>.
35
+ # * Session data is only saved if it has changed.
36
+ module Session
37
+ DIGEST = OpenSSL::Digest::SHA1.new
38
+ # This <tt>service</tt> method, when mixed into controllers, intercepts requests
39
+ # and wraps them with code to start and close the session. If a session isn't found
40
+ # in the cookie it is created. The <tt>@state</tt> variable is set and if it changes,
41
+ # it is saved back into the cookie.
42
+ def service(*a)
43
+ @session_blob = @input.camping_blob || @cookies.camping_blob
44
+ @session_hash = @input.camping_hash || @cookies.camping_hash
45
+ decoded_blob, data = '', {}
46
+ begin
47
+ if @session_blob && @session_hash && secure_blob_hasher(@session_blob) == @session_hash
48
+ decoded_blob = Base64.decode64(@session_blob)
49
+ data = Marshal.restore(decoded_blob)
50
+ end
51
+
52
+ app = C.name
53
+ @state = (data[app] ||= Camping::H[])
54
+ hash_before = decoded_blob.hash
55
+ return super(*a)
56
+ ensure
57
+ data[app] = @state
58
+ decoded_blob = Marshal.dump(data)
59
+ unless hash_before == decoded_blob.hash
60
+ @session_blob = Base64.encode64(decoded_blob).gsub("\n", '').strip
61
+ @session_hash = secure_blob_hasher(@session_blob)
62
+ raise "The session contains to much data" if @session_blob.length > 4096
63
+ @cookies.camping_blob = @session_blob
64
+ @cookies.camping_hash = @session_hash
65
+ end
66
+ end
67
+ end
68
+
69
+ def secure_blob_hasher(data)
70
+ OpenSSL::HMAC.hexdigest(DIGEST, state_secret, "#{@env.REMOTE_ADDR}#{data}")
71
+ end
72
+
73
+ def state_secret; [__FILE__, File.mtime(__FILE__)].join(":") end
74
+ end
75
+ end