picnic 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.txt +3 -0
- data/LICENSE.txt +165 -0
- data/Manifest.txt +28 -0
- data/README.txt +31 -0
- data/Rakefile +58 -0
- data/lib/picnic.rb +122 -0
- data/lib/picnic/authentication.rb +80 -0
- data/lib/picnic/cli.rb +112 -0
- data/lib/picnic/conf.rb +133 -0
- data/lib/picnic/controllers.rb +31 -0
- data/lib/picnic/postambles.rb +227 -0
- data/lib/picnic/service_control.rb +269 -0
- data/lib/picnic/utils.rb +36 -0
- data/lib/picnic/version.rb +9 -0
- data/setup.rb +1585 -0
- data/test/picnic_test.rb +11 -0
- data/test/test_helper.rb +2 -0
- data/vendor/camping-1.5.180/CHANGELOG +99 -0
- data/vendor/camping-1.5.180/COPYING +18 -0
- data/vendor/camping-1.5.180/README +119 -0
- data/vendor/camping-1.5.180/Rakefile +117 -0
- data/vendor/camping-1.5.180/lib/camping-unabridged.rb +762 -0
- data/vendor/camping-1.5.180/lib/camping.rb +55 -0
- data/vendor/camping-1.5.180/lib/camping/db.rb +78 -0
- data/vendor/camping-1.5.180/lib/camping/fastcgi.rb +244 -0
- data/vendor/camping-1.5.180/lib/camping/reloader.rb +163 -0
- data/vendor/camping-1.5.180/lib/camping/session.rb +123 -0
- data/vendor/camping-1.5.180/lib/camping/webrick.rb +65 -0
- metadata +77 -0
data/lib/picnic/cli.rb
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
module Picnic
|
4
|
+
# Provides a command-line interface for your app.
|
5
|
+
# This is useful for creating a 'bin' file for launching your application.
|
6
|
+
#
|
7
|
+
# Usage example (put this in a file called 'foo'):
|
8
|
+
#
|
9
|
+
# #!/usr/bin/env ruby
|
10
|
+
#
|
11
|
+
# require 'rubygems'
|
12
|
+
# require 'picnic'
|
13
|
+
#
|
14
|
+
# require 'picnic/cli'
|
15
|
+
#
|
16
|
+
# cli = Picnic::Cli.new(
|
17
|
+
# 'foo',
|
18
|
+
# :app_path => File.expand_path(File.dirname(File.expand_path(__FILE__)))
|
19
|
+
# )
|
20
|
+
#
|
21
|
+
# cli.handle_cli_input
|
22
|
+
#
|
23
|
+
# Also see the ServiceControl class for info on how to use your cli script
|
24
|
+
# as a service.
|
25
|
+
class Cli
|
26
|
+
attr_accessor :app, :options
|
27
|
+
|
28
|
+
# Creates a new command-line interface handler.
|
29
|
+
#
|
30
|
+
# +app+:: The name of the application. This should match the name of the
|
31
|
+
# binary, which by default is expected to be in the same directory
|
32
|
+
# as the service control script.
|
33
|
+
# +options+:: A hash overriding default options. The options are:
|
34
|
+
# +app_path+:: The path to your application's main Ruby file.
|
35
|
+
# By default this is expected to be <tt>../lib/<app>.rb</tt>
|
36
|
+
# +pid_file+:: Where the app's PID file (containing the app's
|
37
|
+
# process ID) should be placed. By default this is
|
38
|
+
# <tt>/etc/<app>/<app>.pid</tt>
|
39
|
+
# +verbose+:: True if the cli handler should report
|
40
|
+
# everything that it's doing to STDOUT.
|
41
|
+
def initialize(app, options = {})
|
42
|
+
@app = app
|
43
|
+
|
44
|
+
@options = {}
|
45
|
+
@options[:app_path] ||= File.expand_path(File.dirname(File.expand_path(__FILE__))+"/../lib/#{app}.rb")
|
46
|
+
@options[:pid_file] ||= "/etc/#{app}/#{app}.pid"
|
47
|
+
@options[:conf_file] ||= nil
|
48
|
+
@options[:verbose] ||= false
|
49
|
+
|
50
|
+
@options = options
|
51
|
+
end
|
52
|
+
|
53
|
+
# Parses command line options given to the script.
|
54
|
+
def handle_cli_input
|
55
|
+
if File.exists? options[:app_path]
|
56
|
+
# try to use given app base path
|
57
|
+
$: << File.dirname(options[:app_path])
|
58
|
+
path = File.dirname(options[:app_path])+"/"
|
59
|
+
else
|
60
|
+
# fall back to using gem installation
|
61
|
+
path = ""
|
62
|
+
require 'rubygems'
|
63
|
+
gem(app)
|
64
|
+
end
|
65
|
+
|
66
|
+
$PID_FILE = "/etc/#{app}/#{app}.pid"
|
67
|
+
|
68
|
+
OptionParser.new do |opts|
|
69
|
+
opts.banner = "Usage: #{app} [options]"
|
70
|
+
|
71
|
+
opts.on("-c", "--config FILE", "Use config file (default is /etc/#{app}/config.yml)") do |c|
|
72
|
+
puts "Using config file #{c}"
|
73
|
+
$CONFIG_FILE = c
|
74
|
+
end
|
75
|
+
|
76
|
+
opts.on("-d", "--daemonize", "Run as a daemon (only when using webrick or mongrel)") do |c|
|
77
|
+
$DAEMONIZE = true
|
78
|
+
end
|
79
|
+
|
80
|
+
opts.on("-P", "--pid_file FILE", "Use pid file (default is /etc/#{app}/#{app}.pid)") do |c|
|
81
|
+
if $DAEMONIZE && !File.exists?(c)
|
82
|
+
puts "Using pid file '#{c}'"
|
83
|
+
$PID_FILE = c
|
84
|
+
elsif File.exists?(c)
|
85
|
+
puts "The pid file already exists. Is #{app} running?\n" +
|
86
|
+
"You will have to first manually remove the pid file at '#{c}' to start the server as a daemon."
|
87
|
+
exit 1
|
88
|
+
else
|
89
|
+
puts "Not running as daemon. Ignoring pid option"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
94
|
+
puts opts
|
95
|
+
exit
|
96
|
+
end
|
97
|
+
|
98
|
+
opts.on_tail("-V", "--version", "Show version number") do
|
99
|
+
require "#{path}/lib/#{app}/version"
|
100
|
+
puts "#{app}-#{VERSION::STRING}"
|
101
|
+
exit
|
102
|
+
end
|
103
|
+
end.parse!
|
104
|
+
|
105
|
+
$APP_PATH = options[:app_path]
|
106
|
+
|
107
|
+
load "#{path}/lib/#{app}.rb"
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
|
data/lib/picnic/conf.rb
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
module Picnic
|
2
|
+
# Provides an interface for accessing your Picnic app's configuration file.
|
3
|
+
#
|
4
|
+
# Usage example:
|
5
|
+
#
|
6
|
+
# # Load the configuration from /etc/foo/config.yml
|
7
|
+
# Conf.load('foo')
|
8
|
+
#
|
9
|
+
# # The contents of config.yml is now available as follows:
|
10
|
+
# puts Conf[:server]
|
11
|
+
# puts Conf[:authentication][:username]
|
12
|
+
# # ... etc.
|
13
|
+
class Conf
|
14
|
+
$CONF ||= HashWithIndifferentAccess.new
|
15
|
+
$CONF[:log] ||= HashWithIndifferentAccess.new
|
16
|
+
$CONF[:log][:file] ||= STDOUT
|
17
|
+
$CONF[:log][:level] ||= 'DEBUG'
|
18
|
+
$CONF[:uri_path] ||= "/"
|
19
|
+
|
20
|
+
# Read a configuration option.
|
21
|
+
#
|
22
|
+
# For example:
|
23
|
+
# puts Conf[:server]
|
24
|
+
def self.[](key)
|
25
|
+
$CONF[key]
|
26
|
+
end
|
27
|
+
|
28
|
+
# Another way of reading a configuration option.
|
29
|
+
#
|
30
|
+
# The following statements are equivalent:
|
31
|
+
# puts Conf[:server]
|
32
|
+
# puts Conf.server
|
33
|
+
def self.method_missing(method, *args)
|
34
|
+
self[method]
|
35
|
+
end
|
36
|
+
|
37
|
+
# Returns the path to your application's example config file.
|
38
|
+
#
|
39
|
+
# The example config file should be in the root directory of
|
40
|
+
# your application's distribution package and should be called
|
41
|
+
# <tt>config.example.yml</tt>. This file is used as a template
|
42
|
+
# for your app's configuration, to be customized by the end
|
43
|
+
# user.
|
44
|
+
def self.example_config_file_path
|
45
|
+
if $APP_PATH
|
46
|
+
app_path = File.expand_path($APP_PATH)
|
47
|
+
else
|
48
|
+
caller.last =~ /^(.*?):\d+$/
|
49
|
+
app_path = File.dirname(File.expand_path($1))
|
50
|
+
end
|
51
|
+
app_path+'/../config.example.yml'
|
52
|
+
end
|
53
|
+
|
54
|
+
# Copies the example config file into the appropriate
|
55
|
+
# configuration directory.
|
56
|
+
#
|
57
|
+
# +app+:: The name of your application. For example: <tt>foo</tt>
|
58
|
+
# +dest_conf_file:: The path where the example conf file should be copied to.
|
59
|
+
# For example: <tt>/etc/foo/config.yml</tt>
|
60
|
+
def self.copy_example_config_file(app, dest_conf_file)
|
61
|
+
require 'fileutils'
|
62
|
+
|
63
|
+
example_conf_file = example_config_file_path
|
64
|
+
|
65
|
+
puts "\n#{app.to_s.upcase} SERVER HAS NOT YET BEEN CONFIGURED!!!\n"
|
66
|
+
puts "\nAttempting to copy sample configuration from '#{example_conf_file}' to '#{dest_conf_file}'...\n"
|
67
|
+
|
68
|
+
unless File.exists? example_conf_file
|
69
|
+
puts "\nThe example conf file does not exist! The author of #{app} may have forgotten to include it. You'll have to create the config file manually.\n"
|
70
|
+
exit 2
|
71
|
+
end
|
72
|
+
|
73
|
+
begin
|
74
|
+
dest_conf_file_dir = File.dirname(dest_conf_file)
|
75
|
+
FileUtils.mkpath(dest_conf_file_dir) unless File.exists? dest_conf_file_dir
|
76
|
+
FileUtils.cp(example_conf_file, dest_conf_file)
|
77
|
+
rescue Errno::EACCES
|
78
|
+
puts "\nIt appears that you do not have permissions to create the '#{dest_conf_file}' file. Try running this command using sudo (as root).\n"
|
79
|
+
exit 2
|
80
|
+
rescue => e
|
81
|
+
puts "\nFor some reason the '#{dest_conf_file}' file could not be created (#{e})."
|
82
|
+
puts "You'll have to copy the file manually. Use '#{example_conf_file}' as a template.\n"
|
83
|
+
exit 2
|
84
|
+
end
|
85
|
+
|
86
|
+
puts "\nA sample configuration has been created for you in '#{dest_conf_file}'. Please edit this file to" +
|
87
|
+
" suit your needs and then run #{app} again.\n"
|
88
|
+
exit 1
|
89
|
+
end
|
90
|
+
|
91
|
+
# Loads the configuration from the yaml file for the given app.
|
92
|
+
#
|
93
|
+
# <tt>app</tt> should be the name of your app; for example: <tt>foo</tt>.
|
94
|
+
#
|
95
|
+
# By default, the configuration will be loaded from <tt>/etc/<app>/config.yml</tt>.
|
96
|
+
# You can override this by setting a global <tt>$CONFIG_FILE</tt> variable.
|
97
|
+
def self.load(app)
|
98
|
+
|
99
|
+
conf_file = $CONFIG_FILE || "/etc/#{app.to_s.downcase}/config.yml"
|
100
|
+
|
101
|
+
puts "Loading configuration for #{app} from '#{conf_file}'..."
|
102
|
+
|
103
|
+
begin
|
104
|
+
conf_file = etc_conf = conf_file
|
105
|
+
unless File.exists? conf_file
|
106
|
+
# can use local config.yml file in case we're running non-gem installation
|
107
|
+
conf_file = File.dirname(File.expand_path(__FILE__))+"/../../config.yml"
|
108
|
+
end
|
109
|
+
|
110
|
+
unless File.exists? conf_file
|
111
|
+
copy_example_config_file(app, etc_conf)
|
112
|
+
end
|
113
|
+
|
114
|
+
loaded_conf = HashWithIndifferentAccess.new(YAML.load_file(conf_file))
|
115
|
+
|
116
|
+
if $CONF
|
117
|
+
$CONF = HashWithIndifferentAccess.new($CONF)
|
118
|
+
$CONF = $CONF.merge(loaded_conf)
|
119
|
+
else
|
120
|
+
$CONF = loaded_conf
|
121
|
+
end
|
122
|
+
|
123
|
+
$CONF[:log][:file] = STDOUT unless $CONF[:log][:file]
|
124
|
+
|
125
|
+
rescue
|
126
|
+
raise "Your #{app} configuration may be invalid."+
|
127
|
+
" Please double-check check your config.yml file."+
|
128
|
+
" Make sure that you are using spaces instead of tabs for your indentation!!" +
|
129
|
+
"\n\nTHE UNDERLYING ERROR WAS:\n#{$!}"
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Picnic
|
2
|
+
module Controllers
|
3
|
+
# Provides a controller for serving up static content from your app's <tt>/public</tt> directory.
|
4
|
+
# This can be used to serve css, js, jpg, png, and gif files. Anything you put in your app's
|
5
|
+
# '/public' directory will be served up under the '/public' path.
|
6
|
+
#
|
7
|
+
# That is, say you have:
|
8
|
+
# /srv/www/camping/my_app/public/test.jpg
|
9
|
+
# This should be availabe at:
|
10
|
+
# http://myapp.com/public/test.jpg
|
11
|
+
#
|
12
|
+
# This controller is automatically enabled for all Picnic-enabled apps.
|
13
|
+
class Public < Camping::Controllers::R '/public/(.+)'
|
14
|
+
BASE_PATH = ("#{$APP_PATH}/.." || File.expand_path(File.dirname(__FILE__)))+'/lib/public'
|
15
|
+
|
16
|
+
MIME_TYPES = {'.css' => 'text/css', '.js' => 'text/javascript',
|
17
|
+
'.jpg' => 'image/jpeg', '.png' => 'image/png',
|
18
|
+
'.gif' => 'image/gif'}
|
19
|
+
|
20
|
+
def get(path)
|
21
|
+
@headers['Content-Type'] = MIME_TYPES[path[/\.\w+$/, 0]] || "text/plain"
|
22
|
+
unless path.include? ".." # prevent directory traversal attacks
|
23
|
+
@headers['X-Sendfile'] = "#{BASE_PATH}/#{path}"
|
24
|
+
else
|
25
|
+
@status = "403"
|
26
|
+
"403 - Invalid path"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,227 @@
|
|
1
|
+
module Picnic
|
2
|
+
# In Camping, "postambles" are wrappers used to make your application run under
|
3
|
+
# some given web server. They are called "postambles" because traditionally this
|
4
|
+
# was a piece of code included at the bottom of your Camping script. Picnic
|
5
|
+
# provides postambles for two popular Ruby-based web servers: webrick and mongrel.
|
6
|
+
# These postambles take care of all the complications of launching and managing
|
7
|
+
# the web server for you.
|
8
|
+
module Postambles
|
9
|
+
|
10
|
+
# Launches your Camping application using a webrick server.
|
11
|
+
#
|
12
|
+
# It is possible to run using SSL by providing an <tt>:ssl_cert</tt> path in your
|
13
|
+
# app's configuration file, pointing to a valid SSL certificate file.
|
14
|
+
#
|
15
|
+
# If $DAEMONIZE is true, the webrick server will be forked to a background process.
|
16
|
+
# Note that this may have some strange effects, since any open IOs or threads will not
|
17
|
+
# be carried over to the forked daemon process.
|
18
|
+
#
|
19
|
+
# Module#start_picnic automatically calls this method to launch your Picnic app if
|
20
|
+
# your app's <tt>:server</tt> configuration option is set to <tt>'webrick'</tt>.
|
21
|
+
#
|
22
|
+
# Usage example:
|
23
|
+
#
|
24
|
+
# require 'picnic/postambles'
|
25
|
+
# self.extend self::Postambles
|
26
|
+
# webrick
|
27
|
+
#
|
28
|
+
def webrick
|
29
|
+
require 'webrick/httpserver'
|
30
|
+
require 'webrick/https'
|
31
|
+
require 'camping/webrick'
|
32
|
+
|
33
|
+
# TODO: verify the certificate's validity
|
34
|
+
# example of how to do this is here: http://pablotron.org/download/ruri-20050331.rb
|
35
|
+
|
36
|
+
cert_path = Picnic::Conf.ssl_cert
|
37
|
+
key_path = Picnic::Conf.ssl_key || Picnic::Conf.ssl_cert
|
38
|
+
# look for the key in the ssl_cert if no ssl_key is specified
|
39
|
+
|
40
|
+
begin
|
41
|
+
s = WEBrick::HTTPServer.new(
|
42
|
+
:BindAddress => "0.0.0.0",
|
43
|
+
:Port => Picnic::Conf.port
|
44
|
+
)
|
45
|
+
rescue Errno::EACCES
|
46
|
+
puts "\nThe server could not launch. Are you running on a privileged port? (e.g. port 443) If so, you must run the server as root."
|
47
|
+
exit 2
|
48
|
+
end
|
49
|
+
|
50
|
+
self.create
|
51
|
+
s.mount "#{Picnic::Conf.uri_path}", WEBrick::CampingHandler, self
|
52
|
+
|
53
|
+
# This lets Ctrl+C shut down your server
|
54
|
+
trap(:INT) do
|
55
|
+
s.shutdown
|
56
|
+
end
|
57
|
+
trap(:TERM) do
|
58
|
+
s.shutdown
|
59
|
+
end
|
60
|
+
|
61
|
+
if $DAEMONIZE
|
62
|
+
puts "\n** #{self} will run at http://#{ENV['HOSTNAME'] || 'localhost'}:#{Picnic::Conf.port}#{Picnic::Conf.uri_path} and log to #{Picnic::Conf.log[:file].inspect}. "
|
63
|
+
puts "** Check the log file for further messages!\n\n"
|
64
|
+
|
65
|
+
logdev = $LOG.instance_variable_get(:@logdev).instance_variable_get(:@filename)
|
66
|
+
if logdev == 'STDOUT' || logdev == nil
|
67
|
+
puts "\n!!! Warning !!!\nLogging to the console (STDOUT) is not possible once the server daemonizes. "+
|
68
|
+
"You should change the logger configuration to point to a real file."
|
69
|
+
end
|
70
|
+
|
71
|
+
WEBrick::Daemon.start do
|
72
|
+
begin
|
73
|
+
write_pid_file if $PID_FILE
|
74
|
+
$LOG.info "Starting #{self} as a WEBrick daemon with process id #{Process.pid}."
|
75
|
+
self.prestart if self.respond_to? :prestart
|
76
|
+
s.start
|
77
|
+
$LOG.info "Stopping #{self} WEBrick daemon with process id #{Process.pid}."
|
78
|
+
clear_pid_file
|
79
|
+
rescue => e
|
80
|
+
$LOG.error e
|
81
|
+
raise e
|
82
|
+
end
|
83
|
+
end
|
84
|
+
else
|
85
|
+
puts "\n** #{self} is running at http://#{ENV['HOSTNAME'] || 'localhost'}:#{Picnic::Conf.port}#{Picnic::Conf.uri_path} and logging to #{Picnic::Conf.log[:file].inspect}\n\n"
|
86
|
+
self.prestart if self.respond_to? :prestart
|
87
|
+
s.start
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# Launches your Camping application using a mongrel server.
|
92
|
+
#
|
93
|
+
# Mongrel is much faster than webrick, but has two limitations:
|
94
|
+
# 1. You must install the mongrel gem before you can run your server using mongrel.
|
95
|
+
# This is not necessary with webrick, since webrick is included by default with Ruby.
|
96
|
+
# 2. Unlike webrick, mongrel can't be run using SSL. You will have to use a reverse
|
97
|
+
# proxy like Pound or Apache if you want to use mongrel with SSL.
|
98
|
+
#
|
99
|
+
# If $DAEMONIZE is true, the mongrel server will be forked to a background process.
|
100
|
+
# Note that this may have some strange effects, since any open IOs or threads will not
|
101
|
+
# be carried over to the forked daemon process.
|
102
|
+
#
|
103
|
+
# Module#start_picnic automatically calls this method to launch your Picnic app if
|
104
|
+
# your app's <tt>:server</tt> configuration option is set to <tt>'mongrel'</tt>.
|
105
|
+
#
|
106
|
+
# Usage example:
|
107
|
+
#
|
108
|
+
# require 'picnic/postambles'
|
109
|
+
# self.extend self::Postambles
|
110
|
+
# mongrel
|
111
|
+
#
|
112
|
+
def mongrel
|
113
|
+
require 'rubygems'
|
114
|
+
require 'mongrel/camping'
|
115
|
+
|
116
|
+
if $DAEMONIZE
|
117
|
+
# check if log and pid are writable before daemonizing, otherwise we won't be able to notify
|
118
|
+
# the user if we run into trouble later (since once daemonized, we can't write to stdout/stderr)
|
119
|
+
check_pid_writable if $PID_FILE
|
120
|
+
check_log_writable
|
121
|
+
end
|
122
|
+
|
123
|
+
self.create
|
124
|
+
|
125
|
+
puts "\n** #{self} is starting. Look in #{Picnic::Conf.log[:file].inspect} for further notices."
|
126
|
+
|
127
|
+
settings = {:host => "0.0.0.0", :log_file => Picnic::Conf.log[:file], :cwd => $APP_PATH}
|
128
|
+
|
129
|
+
# need to close all IOs before daemonizing
|
130
|
+
$LOG.close if $DAEMONIZE
|
131
|
+
|
132
|
+
begin
|
133
|
+
app_mod = self
|
134
|
+
config = Mongrel::Configurator.new settings do
|
135
|
+
daemonize :log_file => Picnic::Conf.log[:file], :cwd => $APP_PATH if $DAEMONIZE
|
136
|
+
|
137
|
+
listener :port => Picnic::Conf.port do
|
138
|
+
uri Picnic::Conf.uri_path, :handler => Mongrel::Camping::CampingHandler.new(app_mod)
|
139
|
+
setup_signals
|
140
|
+
end
|
141
|
+
end
|
142
|
+
rescue Errno::EADDRINUSE
|
143
|
+
exit 1
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
config.run
|
148
|
+
|
149
|
+
self.init_logger
|
150
|
+
#self.init_db_logger
|
151
|
+
|
152
|
+
if $DAEMONIZE && $PID_FILE
|
153
|
+
write_pid_file
|
154
|
+
unless File.exists? $PID_FILE
|
155
|
+
$LOG.error "#{self} could not start because pid file #{$PID_FILE.inspect} could not be created."
|
156
|
+
exit 1
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
puts "\n** #{self} is running at http://#{ENV['HOSTNAME'] || 'localhost'}:#{Picnic::Conf.port}#{Picnic::Conf.uri_path} and logging to '#{Picnic::Conf.log[:file]}'"
|
161
|
+
|
162
|
+
self.prestart if self.respond_to? :prestart
|
163
|
+
config.join
|
164
|
+
|
165
|
+
clear_pid_file
|
166
|
+
|
167
|
+
puts "\n** #{self} is stopped (#{Time.now})"
|
168
|
+
end
|
169
|
+
|
170
|
+
# Theoretically this should launch your Picnic app as a FastCGI process.
|
171
|
+
# I say "theoretically" because this has never actually been tested.
|
172
|
+
def fastcgi
|
173
|
+
require 'camping/fastcgi'
|
174
|
+
Dir.chdir('.')
|
175
|
+
|
176
|
+
self.create
|
177
|
+
Camping::FastCGI.start(self)
|
178
|
+
end
|
179
|
+
|
180
|
+
# Theoretically this should launch your Picnic app as a CGI process.
|
181
|
+
# I say "theoretically" because this has never actually been tested.
|
182
|
+
def cgi
|
183
|
+
self.create
|
184
|
+
puts self.run
|
185
|
+
end
|
186
|
+
|
187
|
+
private
|
188
|
+
# Prints an error message to stderr if the log file is not writable.
|
189
|
+
def check_log_writable
|
190
|
+
log_file = Picnic::Conf.log['file']
|
191
|
+
begin
|
192
|
+
f = open(log_file, 'w')
|
193
|
+
rescue
|
194
|
+
$stderr.puts "Couldn't write to log file at '#{log_file}' (#{$!})."
|
195
|
+
exit 1
|
196
|
+
end
|
197
|
+
f.close
|
198
|
+
end
|
199
|
+
|
200
|
+
# Prints an error message to stderr if the pid file is not writable.
|
201
|
+
def check_pid_writable
|
202
|
+
$LOG.debug "Checking if pid file #{$PID_FILE.inspect} is writable"
|
203
|
+
begin
|
204
|
+
f = open($PID_FILE, 'w')
|
205
|
+
rescue
|
206
|
+
$stderr.puts "Couldn't write to log at #{$PID_FILE.inspect} (#{$!})."
|
207
|
+
exit 1
|
208
|
+
end
|
209
|
+
f.close
|
210
|
+
end
|
211
|
+
|
212
|
+
# Writes the pid file.
|
213
|
+
def write_pid_file
|
214
|
+
$LOG.debug "Writing pid #{Process.pid.inspect} to pid file #{$PID_FILE.inspect}"
|
215
|
+
open($PID_FILE, "w") { |file| file.write(Process.pid) }
|
216
|
+
end
|
217
|
+
|
218
|
+
# Removes the pid file.
|
219
|
+
def clear_pid_file
|
220
|
+
if $PID_FILE && File.exists?($PID_FILE)
|
221
|
+
$LOG.debug "Clearing pid file #{$PID_FILE.inspect}"
|
222
|
+
File.unlink $PID_FILE
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
end
|
227
|
+
end
|