summaryrefslogtreecommitdiff
path: root/tool/lib/webrick/accesslog.rb
diff options
context:
space:
mode:
Diffstat (limited to 'tool/lib/webrick/accesslog.rb')
-rw-r--r--tool/lib/webrick/accesslog.rb157
1 files changed, 157 insertions, 0 deletions
diff --git a/tool/lib/webrick/accesslog.rb b/tool/lib/webrick/accesslog.rb
new file mode 100644
index 0000000000..e4849637f3
--- /dev/null
+++ b/tool/lib/webrick/accesslog.rb
@@ -0,0 +1,157 @@
+# frozen_string_literal: false
+#--
+# accesslog.rb -- Access log handling utilities
+#
+# Author: IPR -- Internet Programming with Ruby -- writers
+# Copyright (c) 2002 keita yamaguchi
+# Copyright (c) 2002 Internet Programming with Ruby writers
+#
+# $IPR: accesslog.rb,v 1.1 2002/10/01 17:16:32 gotoyuzo Exp $
+
+module WEBrick
+
+ ##
+ # AccessLog provides logging to various files in various formats.
+ #
+ # Multiple logs may be written to at the same time:
+ #
+ # access_log = [
+ # [$stderr, WEBrick::AccessLog::COMMON_LOG_FORMAT],
+ # [$stderr, WEBrick::AccessLog::REFERER_LOG_FORMAT],
+ # ]
+ #
+ # server = WEBrick::HTTPServer.new :AccessLog => access_log
+ #
+ # Custom log formats may be defined. WEBrick::AccessLog provides a subset
+ # of the formatting from Apache's mod_log_config
+ # http://httpd.apache.org/docs/mod/mod_log_config.html#formats. See
+ # AccessLog::setup_params for a list of supported options
+
+ module AccessLog
+
+ ##
+ # Raised if a parameter such as %e, %i, %o or %n is used without fetching
+ # a specific field.
+
+ class AccessLogError < StandardError; end
+
+ ##
+ # The Common Log Format's time format
+
+ CLF_TIME_FORMAT = "[%d/%b/%Y:%H:%M:%S %Z]"
+
+ ##
+ # Common Log Format
+
+ COMMON_LOG_FORMAT = "%h %l %u %t \"%r\" %s %b"
+
+ ##
+ # Short alias for Common Log Format
+
+ CLF = COMMON_LOG_FORMAT
+
+ ##
+ # Referer Log Format
+
+ REFERER_LOG_FORMAT = "%{Referer}i -> %U"
+
+ ##
+ # User-Agent Log Format
+
+ AGENT_LOG_FORMAT = "%{User-Agent}i"
+
+ ##
+ # Combined Log Format
+
+ COMBINED_LOG_FORMAT = "#{CLF} \"%{Referer}i\" \"%{User-agent}i\""
+
+ module_function
+
+ # This format specification is a subset of mod_log_config of Apache:
+ #
+ # %a:: Remote IP address
+ # %b:: Total response size
+ # %e{variable}:: Given variable in ENV
+ # %f:: Response filename
+ # %h:: Remote host name
+ # %{header}i:: Given request header
+ # %l:: Remote logname, always "-"
+ # %m:: Request method
+ # %{attr}n:: Given request attribute from <tt>req.attributes</tt>
+ # %{header}o:: Given response header
+ # %p:: Server's request port
+ # %{format}p:: The canonical port of the server serving the request or the
+ # actual port or the client's actual port. Valid formats are
+ # canonical, local or remote.
+ # %q:: Request query string
+ # %r:: First line of the request
+ # %s:: Request status
+ # %t:: Time the request was received
+ # %T:: Time taken to process the request
+ # %u:: Remote user from auth
+ # %U:: Unparsed URI
+ # %%:: Literal %
+
+ def setup_params(config, req, res)
+ params = Hash.new("")
+ params["a"] = req.peeraddr[3]
+ params["b"] = res.sent_size
+ params["e"] = ENV
+ params["f"] = res.filename || ""
+ params["h"] = req.peeraddr[2]
+ params["i"] = req
+ params["l"] = "-"
+ params["m"] = req.request_method
+ params["n"] = req.attributes
+ params["o"] = res
+ params["p"] = req.port
+ params["q"] = req.query_string
+ params["r"] = req.request_line.sub(/\x0d?\x0a\z/o, '')
+ params["s"] = res.status # won't support "%>s"
+ params["t"] = req.request_time
+ params["T"] = Time.now - req.request_time
+ params["u"] = req.user || "-"
+ params["U"] = req.unparsed_uri
+ params["v"] = config[:ServerName]
+ params
+ end
+
+ ##
+ # Formats +params+ according to +format_string+ which is described in
+ # setup_params.
+
+ def format(format_string, params)
+ format_string.gsub(/\%(?:\{(.*?)\})?>?([a-zA-Z%])/){
+ param, spec = $1, $2
+ case spec[0]
+ when ?e, ?i, ?n, ?o
+ raise AccessLogError,
+ "parameter is required for \"#{spec}\"" unless param
+ (param = params[spec][param]) ? escape(param) : "-"
+ when ?t
+ params[spec].strftime(param || CLF_TIME_FORMAT)
+ when ?p
+ case param
+ when 'remote'
+ escape(params["i"].peeraddr[1].to_s)
+ else
+ escape(params["p"].to_s)
+ end
+ when ?%
+ "%"
+ else
+ escape(params[spec].to_s)
+ end
+ }
+ end
+
+ ##
+ # Escapes control characters in +data+
+
+ def escape(data)
+ data = data.gsub(/[[:cntrl:]\\]+/) {$&.dump[1...-1]}
+ data.untaint if RUBY_VERSION < '2.7'
+ data
+ end
+ end
+end