lots of documentation
This commit is contained in:
parent
71681c7336
commit
faa6654b3f
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,4 +1,6 @@
|
|||||||
.loadpath
|
.loadpath
|
||||||
.project
|
.project
|
||||||
coverage/*
|
coverage/*
|
||||||
|
docs/*
|
||||||
|
|
||||||
|
|
||||||
|
1
CHANGELOG
Normal file
1
CHANGELOG
Normal file
@ -0,0 +1 @@
|
|||||||
|
v0.1. Initial release, support for many of the Apache config basics.
|
13
Rakefile
13
Rakefile
@ -2,6 +2,12 @@ $LOAD_PATH << 'lib'
|
|||||||
|
|
||||||
require 'apache'
|
require 'apache'
|
||||||
require 'spec/rake/spectask'
|
require 'spec/rake/spectask'
|
||||||
|
require 'sdoc'
|
||||||
|
require 'sdoc_helpers/markdown'
|
||||||
|
require 'echoe'
|
||||||
|
require 'pp'
|
||||||
|
|
||||||
|
pp RDoc::TopLevel
|
||||||
|
|
||||||
namespace :apache do
|
namespace :apache do
|
||||||
desc "Generate the configs"
|
desc "Generate the configs"
|
||||||
@ -21,3 +27,10 @@ namespace :spec do
|
|||||||
t.spec_opts = ['-b']
|
t.spec_opts = ['-b']
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Rake::RDocTask.new do |rdoc|
|
||||||
|
rdoc.template = 'direct'
|
||||||
|
rdoc.rdoc_files.add('lib')
|
||||||
|
rdoc.main = "lib/apache/config.rb"
|
||||||
|
rdoc.rdoc_dir = 'docs'
|
||||||
|
end
|
||||||
|
@ -3,6 +3,53 @@ require 'fileutils'
|
|||||||
Dir[File.join(File.dirname(__FILE__), '*.rb')].each { |f| require f }
|
Dir[File.join(File.dirname(__FILE__), '*.rb')].each { |f| require f }
|
||||||
|
|
||||||
module Apache
|
module Apache
|
||||||
|
# The core class of Apache Config Generator.
|
||||||
|
#
|
||||||
|
# Configuration is built by calling either build or build_if:
|
||||||
|
#
|
||||||
|
# Ex: Build a config file regardless of current environment:
|
||||||
|
#
|
||||||
|
# Apache::Config.build('my-config.conf') do
|
||||||
|
# document_root '/my/document/root'
|
||||||
|
# ...
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# Ex: Build a config file only if you're in the development environment:
|
||||||
|
#
|
||||||
|
# Apache::Config.build_if('my-config.conf', :development) do
|
||||||
|
# document_root '/my/document/root'
|
||||||
|
# ...
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# By default, methods called within the block are NerdCapsed to match the Apache config directive format:
|
||||||
|
#
|
||||||
|
# document_root #=> DocumentRoot
|
||||||
|
# options #=> Options
|
||||||
|
# allow_override #=> AllowOverride
|
||||||
|
#
|
||||||
|
# Parameters passed into the methods are quoted if they're Strings or Integers, and not quoted if they're Symbols:
|
||||||
|
#
|
||||||
|
# document_root '/my/document/root' #=> DocumentRoot "/my/document/root"
|
||||||
|
# document_root '/my/document/root'.to_sym #=> DocumentRoot /my/document/root
|
||||||
|
# accept_path_info :off #=> AcceptPathInfo off
|
||||||
|
#
|
||||||
|
# Suffixing the method name with an exclamation point turns off quoting for all parameters:
|
||||||
|
#
|
||||||
|
# document_root! '/my/document/root' #=> DocumentRoot /my/document/root
|
||||||
|
#
|
||||||
|
# Block-level directives work the same as the top-level build method:
|
||||||
|
#
|
||||||
|
# directory '/my/site' do
|
||||||
|
# allow_from_all
|
||||||
|
# satisfy :any
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# Directives that require a regular expression take a Regexp:
|
||||||
|
#
|
||||||
|
# location_match %r{^/my/site} do
|
||||||
|
# set_env 'this_is_my_site', 'yes'
|
||||||
|
# end
|
||||||
|
|
||||||
class Config
|
class Config
|
||||||
class << self
|
class << self
|
||||||
attr_accessor :line_indent, :rotate_logs_path
|
attr_accessor :line_indent, :rotate_logs_path
|
||||||
@ -69,6 +116,10 @@ module Apache
|
|||||||
# Apachify a string
|
# Apachify a string
|
||||||
#
|
#
|
||||||
# Split the provided name on underscores and capitalize the individual parts
|
# Split the provided name on underscores and capitalize the individual parts
|
||||||
|
# Certain character strings are capitalized to match Apache directive names:
|
||||||
|
# * Cgi => CGI
|
||||||
|
# * Ssl => SSL
|
||||||
|
# * Ldap => LDAP
|
||||||
def apachify(name)
|
def apachify(name)
|
||||||
case name
|
case name
|
||||||
when String, Symbol
|
when String, Symbol
|
||||||
@ -79,6 +130,8 @@ module Apache
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Handle options that aren't specially handled
|
# Handle options that aren't specially handled
|
||||||
|
#
|
||||||
|
# Method names are NerdCapsed and paramters are quoted, unless the method ends with !
|
||||||
def method_missing(method, *args)
|
def method_missing(method, *args)
|
||||||
if method.to_s[-1..-1] == "!"
|
if method.to_s[-1..-1] == "!"
|
||||||
method = method.to_s[0..-2].to_sym
|
method = method.to_s[0..-2].to_sym
|
||||||
@ -90,6 +143,11 @@ module Apache
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Handle creating block methods
|
# Handle creating block methods
|
||||||
|
#
|
||||||
|
# Methods created this way are:
|
||||||
|
# * virtual_host
|
||||||
|
# * location
|
||||||
|
# * files
|
||||||
def block_methods(*methods)
|
def block_methods(*methods)
|
||||||
methods.each do |method|
|
methods.each do |method|
|
||||||
self.class.class_eval <<-EOT
|
self.class.class_eval <<-EOT
|
||||||
@ -100,23 +158,44 @@ module Apache
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# If the given module is loaded, process the directives within.
|
||||||
|
#
|
||||||
|
# The provided module name is converted into Apache module name format:
|
||||||
|
# if_module(:php5) do #=> <IfModule mod_php5>
|
||||||
def if_module(mod, &block)
|
def if_module(mod, &block)
|
||||||
blockify(apachify('if_module'), "#{mod}_module".to_sym, &block)
|
blockify(apachify('if_module'), "#{mod}_module".to_sym, &block)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Create a directory block, checking to see if the source directory exists.
|
||||||
def directory(dir, &block)
|
def directory(dir, &block)
|
||||||
directory? dir
|
directory? dir
|
||||||
blockify(apachify('directory'), dir, &block)
|
blockify(apachify('directory'), dir, &block)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Create a LocationMatch block with the provided Regexp:
|
||||||
|
# location_match %r{^/my/location/[a-z0-9]+\.html} do #=> <LocationMatch "^/my/location/[a-z0-9]+\.html">
|
||||||
def location_match(regexp, &block)
|
def location_match(regexp, &block)
|
||||||
blockify(apachify('location_match'), regexp.source, &block)
|
blockify(apachify('location_match'), regexp.source, &block)
|
||||||
end
|
end
|
||||||
|
|
||||||
def if_environment(env, &block)
|
# Create a FilesMatch block with the provied Regexp:
|
||||||
self.instance_eval(&block) if APACHE_ENV == env
|
# files_match %r{\.html$} do #=> FilesMatch "\.html$">
|
||||||
|
def files_match(regexp, &block)
|
||||||
|
blockify(apachify('files_match'), regexp.source, &block)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Only execute the provided block if APACHE_ENV matches one of the provided enviroment symbols:
|
||||||
|
# if_environment(:production) do
|
||||||
|
def if_environment(*env, &block)
|
||||||
|
self.instance_eval(&block) if env.include?(APACHE_ENV)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Blockify the second parameter of a block
|
||||||
|
#
|
||||||
|
# The name is processed differently based on input object type:
|
||||||
|
# * String - the name is quoteized
|
||||||
|
# * Array - all of the array members are quoteized
|
||||||
|
# * Symbol - the name is to_s
|
||||||
def blockify_name(name)
|
def blockify_name(name)
|
||||||
case name
|
case name
|
||||||
when String
|
when String
|
||||||
@ -139,7 +218,14 @@ module Apache
|
|||||||
self << ""
|
self << ""
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Build a string that invokes Apache's rotatelogs command
|
||||||
def rotatelogs(path, time)
|
def rotatelogs(path, time)
|
||||||
|
begin
|
||||||
|
time = time.to_i
|
||||||
|
rescue
|
||||||
|
raise "Time should be an integer: #{path} #{time}"
|
||||||
|
end
|
||||||
|
|
||||||
"|#{@rotate_logs_path} #{path} #{time}"
|
"|#{@rotate_logs_path} #{path} #{time}"
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -157,6 +243,6 @@ module Apache
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
block_methods :virtual_host, :files_match, :location, :files
|
block_methods :virtual_host, :location, :files
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,9 +1,18 @@
|
|||||||
module Apache
|
module Apache
|
||||||
|
# Methods to handle directory settings
|
||||||
module Directories
|
module Directories
|
||||||
|
# Create an Options directive
|
||||||
|
#
|
||||||
|
# The options passed into this method are Apachified:
|
||||||
|
# options :exec_cgi, :follow_sym_links #=> Options ExecCGI FollowSymLinks
|
||||||
def options(*opt)
|
def options(*opt)
|
||||||
create_options_list('Options', *opt)
|
create_options_list('Options', *opt)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Create an IndexOptions directive
|
||||||
|
#
|
||||||
|
# The options passed into this method are Apachified:
|
||||||
|
# index_options :fancy_indexing, :suppress_description #=> IndexOptions FancyIndexing SuppressDescription
|
||||||
def index_options(*opt)
|
def index_options(*opt)
|
||||||
create_options_list('IndexOptions', *opt)
|
create_options_list('IndexOptions', *opt)
|
||||||
end
|
end
|
||||||
|
@ -1,4 +1,20 @@
|
|||||||
module Apache
|
module Apache
|
||||||
|
# Methods to handle logging configuration are defined here.
|
||||||
|
#
|
||||||
|
# For each of the four main log types (Custom, Error, Script, and Rewrite), the following two methods are created:
|
||||||
|
#
|
||||||
|
# * (type)_log: A non-rotated log file
|
||||||
|
# * rotate_(type)_log: A rotated log file
|
||||||
|
#
|
||||||
|
# Non-rotated logs work as such:
|
||||||
|
# custom_log "/path/to/log/file.log", :common #=> CustomLog "/path/to/log/file.log" common
|
||||||
|
#
|
||||||
|
# Rotated logs work as such:
|
||||||
|
# rotate_custom_log "/path/to/log/file-%Y%m%d.log", 86400, :common
|
||||||
|
# #=> CustomLog "|/path/to/rotatelogs /path/to/log/file-%Y%m%d.jpg 86400" common
|
||||||
|
#
|
||||||
|
# Both variations check to make sure the log file diretory exists during generation.
|
||||||
|
# The rotate_ variations need @rotate_logs_path set to work.
|
||||||
module Logging
|
module Logging
|
||||||
[ :custom, :error, :script, :rewrite ].each do |type|
|
[ :custom, :error, :script, :rewrite ].each do |type|
|
||||||
class_eval <<-EOT
|
class_eval <<-EOT
|
||||||
|
@ -1,20 +1,32 @@
|
|||||||
module Apache
|
module Apache
|
||||||
|
# Options that aren't specific to a particular purpose go here. Once enough like methods for a
|
||||||
|
# particular purpose exist, break them out into a separate module.
|
||||||
module Master
|
module Master
|
||||||
|
# Build a module list.
|
||||||
|
# Wraps around Modules.build
|
||||||
def modules(*modules, &block)
|
def modules(*modules, &block)
|
||||||
@config += Modules.build(*modules, &block)
|
@config += Modules.build(*modules, &block)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Add a User/Group block
|
||||||
|
# runner('www', 'www-data') #=>
|
||||||
|
# User www
|
||||||
|
# Group www-data
|
||||||
def runner(user, group = nil)
|
def runner(user, group = nil)
|
||||||
user! user
|
user! user
|
||||||
group! group if group
|
group! group if group
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Enable Passenger on this server
|
||||||
|
#
|
||||||
|
# This assumes that Passenger was installed via the gem. This may or may not work for you, but it works for me.
|
||||||
def passenger(ruby_root, ruby_version, passenger_version)
|
def passenger(ruby_root, ruby_version, passenger_version)
|
||||||
load_module 'passenger_module', "#{ruby_root}/lib/ruby/gems/#{ruby_version}/gems/passenger-#{passenger_version}/ext/apache2/mod_passenger.so"
|
load_module 'passenger_module', "#{ruby_root}/lib/ruby/gems/#{ruby_version}/gems/passenger-#{passenger_version}/ext/apache2/mod_passenger.so"
|
||||||
passenger_root "#{ruby_root}/lib/ruby/gems/#{ruby_version}/gems/passenger-#{passenger_version}"
|
passenger_root "#{ruby_root}/lib/ruby/gems/#{ruby_version}/gems/passenger-#{passenger_version}"
|
||||||
passenger_ruby "#{ruby_root}/bin/ruby"
|
passenger_ruby "#{ruby_root}/bin/ruby"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Enable gzip compression server-wide on pretty much everything that can be gzip compressed
|
||||||
def enable_gzip!
|
def enable_gzip!
|
||||||
directory '/' do
|
directory '/' do
|
||||||
add_output_filter_by_type! :DEFLATE, 'text/html', 'text/plain', 'text/css', 'text/javascript', 'application/javascript'
|
add_output_filter_by_type! :DEFLATE, 'text/html', 'text/plain', 'text/css', 'text/javascript', 'application/javascript'
|
||||||
@ -24,10 +36,12 @@ module Apache
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Set the TCP timeout. Defined here to get around various other timeout methods.
|
||||||
def timeout(t)
|
def timeout(t)
|
||||||
self << "Timeout #{t}"
|
self << "Timeout #{t}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Add a comment to the Apache config. Can pass in either a String or Array of comment lines.
|
||||||
def comment(c)
|
def comment(c)
|
||||||
out = [ '' ]
|
out = [ '' ]
|
||||||
case c
|
case c
|
||||||
@ -40,6 +54,7 @@ module Apache
|
|||||||
self + out.collect { |line| "# #{line.strip}".strip }
|
self + out.collect { |line| "# #{line.strip}".strip }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Create a ScriptAlias, checking to make sure the filesystem path exists.
|
||||||
def script_alias(uri, path)
|
def script_alias(uri, path)
|
||||||
directory? path
|
directory? path
|
||||||
self << %{ScriptAlias #{quoteize(uri, path) * ' '}}
|
self << %{ScriptAlias #{quoteize(uri, path) * ' '}}
|
||||||
@ -47,6 +62,9 @@ module Apache
|
|||||||
|
|
||||||
alias :script_alias! :script_alias
|
alias :script_alias! :script_alias
|
||||||
|
|
||||||
|
# Add a MIME type, potentially also adding handlers and encodings
|
||||||
|
# add_type! 'text/html', '.shtml', :handler => 'server-parsed'
|
||||||
|
# add_type! 'text/html', '.gz', :encoding => 'gzip'
|
||||||
def add_type!(mime, extension, options = {})
|
def add_type!(mime, extension, options = {})
|
||||||
self << "AddType #{mime} #{extension}"
|
self << "AddType #{mime} #{extension}"
|
||||||
options.each do |type, value|
|
options.each do |type, value|
|
||||||
@ -54,14 +72,23 @@ module Apache
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Include other config files or directories.
|
||||||
|
# Used to get around reserved Ruby keyword.
|
||||||
def apache_include(*opts)
|
def apache_include(*opts)
|
||||||
self << "Include #{opts * " "}"
|
self << "Include #{opts * " "}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Alias a URL to a directory in the filesystem.
|
||||||
|
# Used to get around reserved Ruby keyword.
|
||||||
def apache_alias(*opts)
|
def apache_alias(*opts)
|
||||||
self << "Alias #{quoteize(*opts) * " "}"
|
self << "Alias #{quoteize(*opts) * " "}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Set multiple headers to be delivered for a particular section
|
||||||
|
# set_header 'Content-type' => 'application/octet-stream',
|
||||||
|
# 'Content-disposition' => [ 'attachment', 'env=only-for-downloads' ] #=>
|
||||||
|
# Header set "Content-type" "application/octet-stream"
|
||||||
|
# Header set "Content-dispoaition" "attachment" env=only-for-downloads
|
||||||
def set_header(hash)
|
def set_header(hash)
|
||||||
hash.each do |key, value|
|
hash.each do |key, value|
|
||||||
output = "Header set #{quoteize(key)}"
|
output = "Header set #{quoteize(key)}"
|
||||||
|
@ -1,16 +1,29 @@
|
|||||||
require 'apache/quoteize'
|
require 'apache/quoteize'
|
||||||
|
|
||||||
module Apache
|
module Apache
|
||||||
|
# Create lists of modules to load in the Apache 2.2 style (with LoadModule only)
|
||||||
class Modules
|
class Modules
|
||||||
class << self
|
class << self
|
||||||
include Apache::Quoteize
|
include Apache::Quoteize
|
||||||
|
|
||||||
attr_accessor :modules
|
attr_accessor :modules
|
||||||
|
|
||||||
|
# Reset the list of modules to output
|
||||||
def reset!
|
def reset!
|
||||||
@modules = []
|
@modules = []
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Build a block of LoadModule commands
|
||||||
|
#
|
||||||
|
# Apache::Modules.build(:expires, :headers) do
|
||||||
|
# funky "/path/to/funky/module.so"
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# becomes:
|
||||||
|
#
|
||||||
|
# LoadModule "expires_module" "modules/mod_expires.so"
|
||||||
|
# LoadModule "headers_module" "modules/mod_headers.so"
|
||||||
|
# LoadModule "funky_module" "/path/to/funky/module.so"
|
||||||
def build(*modules, &block)
|
def build(*modules, &block)
|
||||||
reset!
|
reset!
|
||||||
|
|
||||||
@ -20,6 +33,7 @@ module Apache
|
|||||||
[ '' ] + @modules + [ '' ]
|
[ '' ] + @modules + [ '' ]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# The method name becomes the module core name
|
||||||
def method_missing(method, *args)
|
def method_missing(method, *args)
|
||||||
module_name = "#{method}_module"
|
module_name = "#{method}_module"
|
||||||
module_path = args[0] || "modules/mod_#{method}.so"
|
module_path = args[0] || "modules/mod_#{method}.so"
|
||||||
|
@ -2,16 +2,29 @@ module Apache
|
|||||||
module MPM
|
module MPM
|
||||||
# Set up the Prefork MPM
|
# Set up the Prefork MPM
|
||||||
#
|
#
|
||||||
# The block you pass in to this can take the following methods:
|
# prefork_config do
|
||||||
# * start(num) - StartServers
|
# start 5
|
||||||
# * spares(min, max) - Min and MaxSpareServers
|
# spares 5, 20
|
||||||
# * limit(num) - ServerLimit
|
# limit 100
|
||||||
# * clients(num) - MaxClients
|
# clients 100
|
||||||
# * max_requests(num) - MaxRequestsPerChild
|
# max_requests 1000
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# becomes:
|
||||||
|
#
|
||||||
|
# StartServers 5
|
||||||
|
# MinSpareServers 5
|
||||||
|
# MaxSpareServers 20
|
||||||
|
# ServerLimit 100
|
||||||
|
# MaxClients 100
|
||||||
|
# MaxRequestsPerChild 1000
|
||||||
|
#
|
||||||
def prefork_config(&block)
|
def prefork_config(&block)
|
||||||
self + Apache::MPM::Prefork.build(&block)
|
self + Apache::MPM::Prefork.build(&block)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Builder for Prefork MPM
|
||||||
|
# See Apache::MPM::prefork_config for usage.
|
||||||
class Prefork
|
class Prefork
|
||||||
class << self
|
class << self
|
||||||
def build(&block)
|
def build(&block)
|
||||||
|
@ -1,5 +1,12 @@
|
|||||||
module Apache
|
module Apache
|
||||||
|
# Options to adjust server performance beyond MPM settings
|
||||||
module Performance
|
module Performance
|
||||||
|
# Activate KeepAlive, optionally tweaking max requests and timeout
|
||||||
|
#
|
||||||
|
# activate_keepalive :requests => 100, :timeout => 5 #=>
|
||||||
|
# KeepAlive on
|
||||||
|
# MaxKeepAliveRequests 100
|
||||||
|
# KeepAliveTimeout 5
|
||||||
def activate_keepalive(options)
|
def activate_keepalive(options)
|
||||||
self << "KeepAlive On"
|
self << "KeepAlive On"
|
||||||
options.each do |option, value|
|
options.each do |option, value|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
module Apache
|
module Apache
|
||||||
|
# Configure server access permissions
|
||||||
module Permissions
|
module Permissions
|
||||||
|
# Shortcut for denying all access to a block
|
||||||
def deny_from_all
|
def deny_from_all
|
||||||
order :deny, :allow
|
order :deny, :allow
|
||||||
deny :from_all
|
deny :from_all
|
||||||
@ -7,6 +9,7 @@ module Apache
|
|||||||
|
|
||||||
alias :deny_from_all! :deny_from_all
|
alias :deny_from_all! :deny_from_all
|
||||||
|
|
||||||
|
# Shortcut for allowing all access to a block
|
||||||
def allow_from_all
|
def allow_from_all
|
||||||
order :allow, :deny
|
order :allow, :deny
|
||||||
allow :from_all
|
allow :from_all
|
||||||
@ -14,14 +17,23 @@ module Apache
|
|||||||
|
|
||||||
alias :allow_from_all! :allow_from_all
|
alias :allow_from_all! :allow_from_all
|
||||||
|
|
||||||
|
# Define IP block restrictions
|
||||||
|
#
|
||||||
|
# allow_from '127.0.0.1' #=> Allow from "127.0.0.1"
|
||||||
def allow_from(*where)
|
def allow_from(*where)
|
||||||
self << "Allow from #{quoteize(*where) * " "}"
|
self << "Allow from #{quoteize(*where) * " "}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Specify default access order
|
||||||
|
#
|
||||||
|
# order :allow, :deny #=> Order allow,deny
|
||||||
def order(*args)
|
def order(*args)
|
||||||
self << "Order #{args * ','}"
|
self << "Order #{args * ','}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
alias :order! :order
|
||||||
|
|
||||||
|
# Set up default restrictive permissions
|
||||||
def default_restrictive!
|
def default_restrictive!
|
||||||
directory '/' do
|
directory '/' do
|
||||||
options :follow_sym_links
|
options :follow_sym_links
|
||||||
@ -30,15 +42,20 @@ module Apache
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Block all .ht* files
|
||||||
def no_htfiles!
|
def no_htfiles!
|
||||||
files_match '^\.ht' do
|
files_match %{^\.ht} do
|
||||||
deny_from_all
|
deny_from_all
|
||||||
satisfy :all
|
satisfy :all
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
alias :order! :order
|
# Set up basic authentication
|
||||||
|
#
|
||||||
|
# Check to make sure the defined users_file exists
|
||||||
|
#
|
||||||
|
# basic_authentication "My secret", '/my.users', 'valid-user' => true
|
||||||
|
# basic_authentication "My other secret", '/my.users', :user => [ :john ]
|
||||||
def basic_authentication(zone, users_file, requires = {})
|
def basic_authentication(zone, users_file, requires = {})
|
||||||
exist? users_file
|
exist? users_file
|
||||||
auth_type :basic
|
auth_type :basic
|
||||||
@ -51,6 +68,7 @@ module Apache
|
|||||||
|
|
||||||
alias :basic_authentication! :basic_authentication
|
alias :basic_authentication! :basic_authentication
|
||||||
|
|
||||||
|
# Set up LDAP authentication
|
||||||
def ldap_authentication(zone, url, requires = {})
|
def ldap_authentication(zone, url, requires = {})
|
||||||
auth_type :basic
|
auth_type :basic
|
||||||
auth_name zone
|
auth_name zone
|
||||||
@ -64,6 +82,8 @@ module Apache
|
|||||||
|
|
||||||
alias :ldap_authentication! :ldap_authentication
|
alias :ldap_authentication! :ldap_authentication
|
||||||
|
|
||||||
|
# Create an Apache require directive.
|
||||||
|
# Used to get around Ruby reserved word.
|
||||||
def apache_require(*opts)
|
def apache_require(*opts)
|
||||||
self << "Require #{opts * " "}"
|
self << "Require #{opts * " "}"
|
||||||
end
|
end
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
module Apache
|
module Apache
|
||||||
|
# Add quotes around parameters as needed
|
||||||
module Quoteize
|
module Quoteize
|
||||||
|
# Add quotes around most parameters, and don't add quotes around Symbols
|
||||||
def quoteize(*args)
|
def quoteize(*args)
|
||||||
args.collect do |arg|
|
args.collect do |arg|
|
||||||
case arg
|
case arg
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
module Apache
|
module Apache
|
||||||
|
# Handle the creation of RewriteRules, RewriteConds, Redirects, and RedirectMatches
|
||||||
module Rewrites
|
module Rewrites
|
||||||
|
# Enable the rewrite engine, optionally setting the logging level
|
||||||
|
#
|
||||||
|
# enable_rewrite_engine :log_level => 1 #=>
|
||||||
|
# RewriteEngine on
|
||||||
|
# RewriteLogLevel 1
|
||||||
def enable_rewrite_engine(options)
|
def enable_rewrite_engine(options)
|
||||||
self << ''
|
self << ''
|
||||||
rewrite_engine! :on
|
rewrite_engine! :on
|
||||||
@ -12,24 +18,31 @@ module Apache
|
|||||||
self << ''
|
self << ''
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Pass the block to RewriteManager.build
|
||||||
def rewrites(&block)
|
def rewrites(&block)
|
||||||
self + indent(RewriteManager.build(&block))
|
self + indent(RewriteManager.build(&block))
|
||||||
self << ''
|
self << ''
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Create a permanent Redirect
|
||||||
|
#
|
||||||
|
# r301 '/here', '/there' #=> Redirect permanent "/here" "/there"
|
||||||
def r301(*opt)
|
def r301(*opt)
|
||||||
self << "Redirect permanent #{quoteize(*opt) * " "}"
|
self << "Redirect permanent #{quoteize(*opt) * " "}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Handle the creation of Rewritable things
|
||||||
class RewriteManager
|
class RewriteManager
|
||||||
class << self
|
class << self
|
||||||
attr_accessor :rewrites
|
attr_accessor :rewrites
|
||||||
|
|
||||||
|
# Reset the current list of rewrites
|
||||||
def reset!
|
def reset!
|
||||||
@rewrites = []
|
@rewrites = []
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Build rewritable things from the provided block
|
||||||
def build(&block)
|
def build(&block)
|
||||||
reset!
|
reset!
|
||||||
|
|
||||||
@ -38,15 +51,21 @@ module Apache
|
|||||||
@rewrites.collect(&:to_a).flatten
|
@rewrites.collect(&:to_a).flatten
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Commit the latest rewritable thing to the list of rewrites
|
||||||
def commit!
|
def commit!
|
||||||
@rewrites << @rewrite
|
@rewrites << @rewrite
|
||||||
@rewrite = nil
|
@rewrite = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Ensure that there's a RewriteRule to be worked with
|
||||||
def ensure_rewrite!
|
def ensure_rewrite!
|
||||||
@rewrite = RewriteRule.new if !@rewrite
|
@rewrite = RewriteRule.new if !@rewrite
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Create a RewriteRule with the given options
|
||||||
|
#
|
||||||
|
# rewrite %r{/here(.*)}, '/there$1', :last => true #=>
|
||||||
|
# RewriteRule "/here(.*)" "/there$1" [L]
|
||||||
def rewrite(*opts)
|
def rewrite(*opts)
|
||||||
ensure_rewrite!
|
ensure_rewrite!
|
||||||
@rewrite.rule(*opts)
|
@rewrite.rule(*opts)
|
||||||
@ -55,11 +74,19 @@ module Apache
|
|||||||
|
|
||||||
alias :rule :rewrite
|
alias :rule :rewrite
|
||||||
|
|
||||||
|
# Create a RewriteCond with the given options
|
||||||
|
#
|
||||||
|
# cond "%{REQUEST_FILENAME}", "^/here" #=>
|
||||||
|
# RewriteCond "%{REQUEST_FILENAME}", "^/here"
|
||||||
def cond(*opts)
|
def cond(*opts)
|
||||||
ensure_rewrite!
|
ensure_rewrite!
|
||||||
@rewrite.cond(*opts)
|
@rewrite.cond(*opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Create a permanent RedirectMatch
|
||||||
|
#
|
||||||
|
# r301 %r{/here(.*)}, "/there$1" #=>
|
||||||
|
# RedirectMatch permanent "/here(.*)" "/there$1"
|
||||||
def r301(*opts)
|
def r301(*opts)
|
||||||
redirect = RedirectMatchPermanent.new
|
redirect = RedirectMatchPermanent.new
|
||||||
redirect.rule(*opts)
|
redirect.rule(*opts)
|
||||||
@ -67,6 +94,7 @@ module Apache
|
|||||||
@rewrites << redirect
|
@rewrites << redirect
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Test the rewritable things defined in this block
|
||||||
def rewrite_test(from, to, opts = {})
|
def rewrite_test(from, to, opts = {})
|
||||||
orig_from = from.dup
|
orig_from = from.dup
|
||||||
@rewrites.each do |r|
|
@rewrites.each do |r|
|
||||||
@ -81,12 +109,15 @@ module Apache
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Common methods for testing rewritable things that use regular expressions
|
||||||
module RegularExpressionMatcher
|
module RegularExpressionMatcher
|
||||||
|
# Test this rewritable thing
|
||||||
def test(from, opts = {})
|
def test(from, opts = {})
|
||||||
from = from.gsub(@from, @to.gsub(/\$([0-9])/) { |m| '\\' + $1 })
|
from = from.gsub(@from, @to.gsub(/\$([0-9])/) { |m| '\\' + $1 })
|
||||||
replace_placeholders(from, opts)
|
replace_placeholders(from, opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Replace the placeholders in this rewritable thing
|
||||||
def replace_placeholders(s, opts)
|
def replace_placeholders(s, opts)
|
||||||
opts.each do |opt, value|
|
opts.each do |opt, value|
|
||||||
case value
|
case value
|
||||||
@ -98,9 +129,11 @@ module Apache
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# A matchable thing to be extended
|
||||||
class MatchableThing
|
class MatchableThing
|
||||||
include Apache::Quoteize
|
include Apache::Quoteize
|
||||||
|
|
||||||
|
# The Apache directive tag for this thing
|
||||||
def tag; raise 'Override this method'; end
|
def tag; raise 'Override this method'; end
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
@ -122,6 +155,7 @@ module Apache
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# A RewriteRule definition
|
||||||
class RewriteRule < MatchableThing
|
class RewriteRule < MatchableThing
|
||||||
include RegularExpressionMatcher
|
include RegularExpressionMatcher
|
||||||
|
|
||||||
@ -133,6 +167,9 @@ module Apache
|
|||||||
@options = nil
|
@options = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Define the rule, passing in additional options
|
||||||
|
#
|
||||||
|
# rule %r{^/here}, '/there', { :last => true, :preserve_query_string => true }
|
||||||
def rule(from, to,options = {})
|
def rule(from, to,options = {})
|
||||||
super(from, to)
|
super(from, to)
|
||||||
|
|
||||||
@ -150,6 +187,7 @@ module Apache
|
|||||||
@options = !options.empty? ? "[#{options * ','}]" : nil
|
@options = !options.empty? ? "[#{options * ','}]" : nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Add a RewriteCondition to this RewriteRule
|
||||||
def cond(from, to, *opts)
|
def cond(from, to, *opts)
|
||||||
rewrite_cond = RewriteCondition.new
|
rewrite_cond = RewriteCondition.new
|
||||||
rewrite_cond.cond(from, to, *opts)
|
rewrite_cond.cond(from, to, *opts)
|
||||||
@ -162,13 +200,10 @@ module Apache
|
|||||||
end
|
end
|
||||||
|
|
||||||
def to_a
|
def to_a
|
||||||
output = @conditions.collect(&:to_s)
|
[ @conditions.collect(&:to_s), super ].flatten
|
||||||
|
|
||||||
output += super
|
|
||||||
|
|
||||||
output
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Test this RewriteRule, ensuring the RewriteConds also match
|
||||||
def test(from, opts = {})
|
def test(from, opts = {})
|
||||||
ok = true
|
ok = true
|
||||||
@conditions.each do |c|
|
@conditions.each do |c|
|
||||||
@ -183,21 +218,33 @@ module Apache
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# A permanent RedirectMatch
|
||||||
class RedirectMatchPermanent < MatchableThing
|
class RedirectMatchPermanent < MatchableThing
|
||||||
include RegularExpressionMatcher
|
include RegularExpressionMatcher
|
||||||
|
|
||||||
def tag; 'RedirectMatch permanent'; end
|
def tag; 'RedirectMatch permanent'; end
|
||||||
|
|
||||||
|
def rule(from, to)
|
||||||
|
super(from, to)
|
||||||
|
|
||||||
|
raise "from must be a Regexp" if !from.kind_of?(Regexp)
|
||||||
|
end
|
||||||
|
|
||||||
def to_s
|
def to_s
|
||||||
"#{tag} #{[quoteize(@from.source), quoteize(@to)].compact.flatten * " "}"
|
"#{tag} #{[quoteize(@from.source), quoteize(@to)].compact.flatten * " "}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# A RewriteCond
|
||||||
class RewriteCondition < MatchableThing
|
class RewriteCondition < MatchableThing
|
||||||
include RegularExpressionMatcher
|
include RegularExpressionMatcher
|
||||||
|
|
||||||
def tag; 'RewriteCond'; end
|
def tag; 'RewriteCond'; end
|
||||||
|
|
||||||
|
# Define a RewriteCond
|
||||||
|
#
|
||||||
|
# rule "%{REQUEST_FILENAME}", "^/here", :case_insensitive #=>
|
||||||
|
# RewriteCond "%{REQUEST_FILENAME}" "^/here" [NC]
|
||||||
def rule(from, to, *opts)
|
def rule(from, to, *opts)
|
||||||
super(from, to)
|
super(from, to)
|
||||||
|
|
||||||
@ -226,6 +273,7 @@ module Apache
|
|||||||
"#{tag} #{[quoteize(@from), quoteize(@to), @options].compact.flatten * " "}"
|
"#{tag} #{[quoteize(@from), quoteize(@to), @options].compact.flatten * " "}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Test this RewriteCond
|
||||||
def test(from, opts = {})
|
def test(from, opts = {})
|
||||||
super(from, opts)
|
super(from, opts)
|
||||||
source = replace_placeholders(@from, opts)
|
source = replace_placeholders(@from, opts)
|
||||||
|
Loading…
Reference in New Issue
Block a user