From 2c933b7837ea1c4419f143293636acaa7e0294c7 Mon Sep 17 00:00:00 2001 From: John Bintz Date: Wed, 5 May 2010 12:25:07 -0400 Subject: [PATCH] a bunch more real-world work --- lib/apache/config.rb | 41 ++++++++++++++++--- lib/apache/directory.rb | 7 +++- lib/apache/logging.rb | 24 +++++++++-- lib/apache/master.rb | 23 +++++++++++ lib/apache/mpm_prefork.rb | 34 ++++++++++++++++ lib/apache/performance.rb | 19 +++++++++ lib/apache/permissions.rb | 4 ++ lib/apache/rake/create.rb | 2 + lib/apache/rewrites.rb | 85 +++++++++++++++++++++++++++++++++++++++ 9 files changed, 227 insertions(+), 12 deletions(-) create mode 100644 lib/apache/mpm_prefork.rb create mode 100644 lib/apache/performance.rb create mode 100644 lib/apache/rewrites.rb diff --git a/lib/apache/config.rb b/lib/apache/config.rb index 45e85f0..26943cc 100644 --- a/lib/apache/config.rb +++ b/lib/apache/config.rb @@ -1,22 +1,29 @@ +require 'fileutils' + Dir[File.join(File.dirname(__FILE__), '*.rb')].each { |f| require f } module Apache class Config class << self - attr_accessor :line_indent, :config + attr_accessor :line_indent, :config, :rotate_logs_path include Apache::Master include Apache::Quoteize include Apache::Permissions include Apache::Directories include Apache::Logging + include Apache::Performance + include Apache::Rewrites def build(target = nil, &block) reset! self.instance_eval(&block) - File.open(target, 'w') { |f| f.puts @config * "\n" } if target + if target + FileUtils.mkdir_p File.split(target).first + File.open(target, 'w') { |f| f.puts @config * "\n" } + end @config end @@ -28,8 +35,13 @@ module Apache end # Indent the string by the current @line_indent level - def indent(string) - " " * (@line_indent * 2) + string + def indent(string_or_array) + case string_or_array + when Array + string_or_array.collect { |s| indent(s) } + else + " " * (@line_indent * 2) + string_or_array.to_s + end end # Add the string to the current config @@ -37,11 +49,20 @@ module Apache @config << indent(string) end + def +(other) + @config += other + end + # Apachify a string # # Split the provided name on underscores and capitalize the individual parts def apachify(name) - name.to_s.split("_").collect(&:capitalize).join.gsub('Ssl', 'SSL') + case name + when String, Symbol + name.to_s.split("_").collect(&:capitalize).join.gsub('Ssl', 'SSL') + when Array + name.collect { |n| apachify(n) } + end end # Handle options that aren't specially handled @@ -75,6 +96,10 @@ module Apache blockify(apachify('directory'), dir, &block) end + def if_environment(env, &block) + self.instance_eval(&block) if APACHE_ENV == env + end + # Handle the blockification of a provided block def blockify(tag_name, name, &block) start = [ tag_name ] @@ -102,6 +127,10 @@ module Apache self << "Include #{opts * " "}" end + def rotatelogs(path, time) + "|#{@rotate_logs_path} #{path} #{time}" + end + private def writable?(path) if !File.directory? File.split(path).first @@ -117,6 +146,6 @@ module Apache end - block_methods :virtual_host, :files_match + block_methods :virtual_host, :files_match, :location end end diff --git a/lib/apache/directory.rb b/lib/apache/directory.rb index 383c52c..0fcf28f 100644 --- a/lib/apache/directory.rb +++ b/lib/apache/directory.rb @@ -1,8 +1,11 @@ module Apache module Directories def options(*opt) - opt = opt.collect { |o| apachify(o) } - self << "Options #{opt * " "}" + self << "Options #{apachify(opt) * " "}" + end + + def index_options(*opt) + self << "IndexOptions #{apachify(opt) * " "}" end end end diff --git a/lib/apache/logging.rb b/lib/apache/logging.rb index 5766131..8d0e6e1 100644 --- a/lib/apache/logging.rb +++ b/lib/apache/logging.rb @@ -1,13 +1,23 @@ module Apache module Logging def error_log(*opts) - writable? opts.first - self << "ErrorLog #{opts * " "}" + handle_log 'ErrorLog', opts.first, opts.first, opts[1..-1] end def custom_log(*opts) - writable? opts.first - self << "CustomLog #{opts * " "}" + handle_log 'CustomLog', opts.first, opts.first, opts[1..-1] + end + + def rotate_custom_log(*opts) + handle_log 'CustomLog', opts.first, quoteize(rotatelogs(*opts[0..1])), opts[2..-1] + end + + def rotate_error_log(*opts) + handle_log 'ErrorLog', opts.first, quoteize(rotatelogs(*opts[0..1])), opts[2..-1] + end + + def rotate_script_log(*opts) + handle_log 'ScriptLog', opts.first, quoteize(rotatelogs(*opts[0..1])), opts[2..-1] end def combined_log_format(name = 'combined') @@ -17,5 +27,11 @@ module Apache def common_log_format(name = 'common') log_format '%h %l %u %t \"%r\" %>s %b', name.to_sym end + + private + def handle_log(tag, path, real_path, *opts) + writable? path + self << "#{tag} #{[real_path, opts].flatten * " "}" + end end end diff --git a/lib/apache/master.rb b/lib/apache/master.rb index 4a87120..7af27a9 100644 --- a/lib/apache/master.rb +++ b/lib/apache/master.rb @@ -23,5 +23,28 @@ module Apache browser_match! '\bMSIE', '!no-gzip', '!gzip-only-text/html' end end + + def timeout(t) + self << "Timeout #{t}" + end + + def comment(c) + out = [ '' ] + case c + when String + out += c.split("\n") + when Array + out = c + end + out << '' + self + out.collect { |line| "# #{line.strip}" } + end + + def script_alias(uri, path) + directory? path + self << %{ScriptAlias "#{uri}" "#{path}"} + end + + alias :script_alias! :script_alias end end diff --git a/lib/apache/mpm_prefork.rb b/lib/apache/mpm_prefork.rb new file mode 100644 index 0000000..a2ef301 --- /dev/null +++ b/lib/apache/mpm_prefork.rb @@ -0,0 +1,34 @@ +module Apache + module MPM + class Prefork + class << self + def build(&block) + @config = ['', '# Prefork config', ''] + + self.instance_eval(&block) + + @config + end + + def method_missing(method, *opts) + if which = { + :start => 'StartServers', + :spares => [ 'MinSpareServers', 'MaxSpareServers' ], + :limit => 'ServerLimit', + :clients => 'MaxClients', + :max_requests => 'MaxRequestsPerChild' + }[method] + case which + when String + @config << "#{which} #{opts * " "}" + when Array + which.each do |w| + @config << "#{w} #{opts.shift}" + end + end + end + end + end + end + end +end diff --git a/lib/apache/performance.rb b/lib/apache/performance.rb new file mode 100644 index 0000000..f749b6a --- /dev/null +++ b/lib/apache/performance.rb @@ -0,0 +1,19 @@ +module Apache + module Performance + def activate_keepalive(options) + self << "KeepAlive On" + options.each do |option, value| + case option + when :requests + self << "MaxKeepAliveRequests #{value}" + when :timeout + self << "KeepAliveTimeout #{value}" + end + end + end + + def prefork_config(&block) + self + Apache::MPM::Prefork.build(&block) + end + end +end diff --git a/lib/apache/permissions.rb b/lib/apache/permissions.rb index 3b62645..19e7d05 100644 --- a/lib/apache/permissions.rb +++ b/lib/apache/permissions.rb @@ -10,6 +10,10 @@ module Apache allow :from_all end + def allow_from(where) + allow "from_#{where}".to_sym + end + def order(*args) self << "Order #{args * ','}" end diff --git a/lib/apache/rake/create.rb b/lib/apache/rake/create.rb index b13e358..d1ea5d4 100644 --- a/lib/apache/rake/create.rb +++ b/lib/apache/rake/create.rb @@ -13,6 +13,8 @@ namespace :apache do CONFIG['source_path'] = File.expand_path(CONFIG['source']) CONFIG['dest_path'] = File.expand_path(CONFIG['destination']) + Apache::Config.rotate_logs_path = CONFIG['rotate_logs_path'] + FileUtils.mkdir_p CONFIG['dest_path'] Dir.chdir CONFIG['dest_path'] diff --git a/lib/apache/rewrites.rb b/lib/apache/rewrites.rb new file mode 100644 index 0000000..8904f28 --- /dev/null +++ b/lib/apache/rewrites.rb @@ -0,0 +1,85 @@ +module Apache + module Rewrites + def enable_rewrite_engine(options) + rewrite_engine! :on + options.each do |option, value| + case option + when :log_level + rewrite_log_level! value + end + end + end + + def rewrites(&block) + self + indent(RewriteManager.build(&block)) + end + end + + class RewriteManager + class << self + attr_accessor :rewrites + + def build(&block) + @rewrites = [] + + self.instance_eval(&block) + + @rewrites + end + + def rewrite(*opts) + @rewrite = RewriteRule.new + @rewrite.rule(*opts) + + @rewrites << @rewrite + end + + def rewrite_test(from, to, opts = {}) + orig_from = from.dup + @rewrites.each do |r| + from = r.test(from, opts) + end + + if from != to + puts "[warn] #{orig_from} >> #{to} failed!" + puts "[warn] Result: #{from}" + end + end + end + end + + class RewriteRule + def initialize + @from = nil + @to = nil + @options = nil + @conditions = [] + end + + def rule(from, to, *opts) + @from = from + @to = to + @options = opts + end + + def test(from, opts) + from = from.gsub(@from, @to.gsub(/\$([0-9])/) { |m| '\\' + $1 }) + opts.each do |opt, value| + from = from.gsub('%{' + opt.to_s.upcase + '}', value) + end + from + end + + def to_s + output = [] + + @conditions.each do |condition| + + end + + output << "RewriteRule #{[@from.source, @to, @options].flatten * " "}" + + output * "\n" + end + end +end