Preparation for ruby/webrick
This commit is contained in:
parent
0409b47beb
commit
15403cad08
|
@ -0,0 +1,9 @@
|
|||
/.bundle/
|
||||
/.yardoc
|
||||
/Gemfile.lock
|
||||
/_yardoc/
|
||||
/coverage/
|
||||
/doc/
|
||||
/pkg/
|
||||
/spec/reports/
|
||||
/tmp/
|
|
@ -0,0 +1,5 @@
|
|||
sudo: false
|
||||
language: ruby
|
||||
rvm:
|
||||
- 2.5.0
|
||||
before_install: gem install bundler -v 1.14.3
|
|
@ -0,0 +1,4 @@
|
|||
source 'https://rubygems.org'
|
||||
|
||||
# Specify your gem's dependencies in webrick.gemspec
|
||||
gemspec
|
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017 SHIBATA Hiroshi
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
|
@ -0,0 +1,41 @@
|
|||
# Webrick
|
||||
|
||||
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/webrick`. To experiment with that code, run `bin/console` for an interactive prompt.
|
||||
|
||||
TODO: Delete this and the text above, and describe your gem
|
||||
|
||||
## Installation
|
||||
|
||||
Add this line to your application's Gemfile:
|
||||
|
||||
```ruby
|
||||
gem 'webrick'
|
||||
```
|
||||
|
||||
And then execute:
|
||||
|
||||
$ bundle
|
||||
|
||||
Or install it yourself as:
|
||||
|
||||
$ gem install webrick
|
||||
|
||||
## Usage
|
||||
|
||||
TODO: Write usage instructions here
|
||||
|
||||
## Development
|
||||
|
||||
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
||||
|
||||
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
||||
|
||||
## Contributing
|
||||
|
||||
Bug reports and pull requests are welcome on GitHub at https://github.com/SHIBATA Hiroshi/webrick.
|
||||
|
||||
|
||||
## License
|
||||
|
||||
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
require "bundler/gem_tasks"
|
||||
require "rake/testtask"
|
||||
|
||||
Rake::TestTask.new(:test) do |t|
|
||||
t.libs << "test" << "test/lib"
|
||||
t.libs << "lib"
|
||||
t.test_files = FileList['test/**/test_*.rb']
|
||||
end
|
||||
|
||||
task :default => :test
|
|
@ -0,0 +1,14 @@
|
|||
#!/usr/bin/env ruby
|
||||
|
||||
require "bundler/setup"
|
||||
require "webrick"
|
||||
|
||||
# You can add fixtures and/or initialization code here to make experimenting
|
||||
# with your gem easier. You can also use a different console, if you like.
|
||||
|
||||
# (If you use this, don't forget to add pry to your Gemfile!)
|
||||
# require "pry"
|
||||
# Pry.start
|
||||
|
||||
require "irb"
|
||||
IRB.start(__FILE__)
|
|
@ -0,0 +1,8 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
set -vx
|
||||
|
||||
bundle install
|
||||
|
||||
# Do any other automated setup that you need to do here
|
|
@ -0,0 +1,283 @@
|
|||
# -*- coding: us-ascii -*-
|
||||
# frozen_string_literal: false
|
||||
require "open3"
|
||||
require "timeout"
|
||||
require_relative "find_executable"
|
||||
begin
|
||||
require 'rbconfig'
|
||||
rescue LoadError
|
||||
end
|
||||
begin
|
||||
require "rbconfig/sizeof"
|
||||
rescue LoadError
|
||||
end
|
||||
|
||||
module EnvUtil
|
||||
def rubybin
|
||||
if ruby = ENV["RUBY"]
|
||||
return ruby
|
||||
end
|
||||
ruby = "ruby"
|
||||
exeext = RbConfig::CONFIG["EXEEXT"]
|
||||
rubyexe = (ruby + exeext if exeext and !exeext.empty?)
|
||||
3.times do
|
||||
if File.exist? ruby and File.executable? ruby and !File.directory? ruby
|
||||
return File.expand_path(ruby)
|
||||
end
|
||||
if rubyexe and File.exist? rubyexe and File.executable? rubyexe
|
||||
return File.expand_path(rubyexe)
|
||||
end
|
||||
ruby = File.join("..", ruby)
|
||||
end
|
||||
if defined?(RbConfig.ruby)
|
||||
RbConfig.ruby
|
||||
else
|
||||
"ruby"
|
||||
end
|
||||
end
|
||||
module_function :rubybin
|
||||
|
||||
LANG_ENVS = %w"LANG LC_ALL LC_CTYPE"
|
||||
|
||||
DEFAULT_SIGNALS = Signal.list
|
||||
DEFAULT_SIGNALS.delete("TERM") if /mswin|mingw/ =~ RUBY_PLATFORM
|
||||
|
||||
class << self
|
||||
attr_accessor :subprocess_timeout_scale
|
||||
end
|
||||
|
||||
def invoke_ruby(args, stdin_data = "", capture_stdout = false, capture_stderr = false,
|
||||
encoding: nil, timeout: 10, reprieve: 1, timeout_error: Timeout::Error,
|
||||
stdout_filter: nil, stderr_filter: nil,
|
||||
signal: :TERM,
|
||||
rubybin: EnvUtil.rubybin,
|
||||
**opt)
|
||||
if scale = EnvUtil.subprocess_timeout_scale
|
||||
timeout *= scale if timeout
|
||||
reprieve *= scale if reprieve
|
||||
end
|
||||
in_c, in_p = IO.pipe
|
||||
out_p, out_c = IO.pipe if capture_stdout
|
||||
err_p, err_c = IO.pipe if capture_stderr && capture_stderr != :merge_to_stdout
|
||||
opt[:in] = in_c
|
||||
opt[:out] = out_c if capture_stdout
|
||||
opt[:err] = capture_stderr == :merge_to_stdout ? out_c : err_c if capture_stderr
|
||||
if encoding
|
||||
out_p.set_encoding(encoding) if out_p
|
||||
err_p.set_encoding(encoding) if err_p
|
||||
end
|
||||
c = "C"
|
||||
child_env = {}
|
||||
LANG_ENVS.each {|lc| child_env[lc] = c}
|
||||
if Array === args and Hash === args.first
|
||||
child_env.update(args.shift)
|
||||
end
|
||||
args = [args] if args.kind_of?(String)
|
||||
pid = spawn(child_env, rubybin, *args, **opt)
|
||||
in_c.close
|
||||
out_c.close if capture_stdout
|
||||
err_c.close if capture_stderr && capture_stderr != :merge_to_stdout
|
||||
if block_given?
|
||||
return yield in_p, out_p, err_p, pid
|
||||
else
|
||||
th_stdout = Thread.new { out_p.read } if capture_stdout
|
||||
th_stderr = Thread.new { err_p.read } if capture_stderr && capture_stderr != :merge_to_stdout
|
||||
in_p.write stdin_data.to_str unless stdin_data.empty?
|
||||
in_p.close
|
||||
if (!th_stdout || th_stdout.join(timeout)) && (!th_stderr || th_stderr.join(timeout))
|
||||
timeout_error = nil
|
||||
else
|
||||
signals = Array(signal).select do |sig|
|
||||
DEFAULT_SIGNALS[sig.to_s] or
|
||||
DEFAULT_SIGNALS[Signal.signame(sig)] rescue false
|
||||
end
|
||||
signals |= [:ABRT, :KILL]
|
||||
case pgroup = opt[:pgroup]
|
||||
when 0, true
|
||||
pgroup = -pid
|
||||
when nil, false
|
||||
pgroup = pid
|
||||
end
|
||||
while signal = signals.shift
|
||||
begin
|
||||
Process.kill signal, pgroup
|
||||
rescue Errno::EINVAL
|
||||
next
|
||||
rescue Errno::ESRCH
|
||||
break
|
||||
end
|
||||
if signals.empty? or !reprieve
|
||||
Process.wait(pid)
|
||||
else
|
||||
begin
|
||||
Timeout.timeout(reprieve) {Process.wait(pid)}
|
||||
rescue Timeout::Error
|
||||
end
|
||||
end
|
||||
end
|
||||
status = $?
|
||||
end
|
||||
stdout = th_stdout.value if capture_stdout
|
||||
stderr = th_stderr.value if capture_stderr && capture_stderr != :merge_to_stdout
|
||||
out_p.close if capture_stdout
|
||||
err_p.close if capture_stderr && capture_stderr != :merge_to_stdout
|
||||
status ||= Process.wait2(pid)[1]
|
||||
stdout = stdout_filter.call(stdout) if stdout_filter
|
||||
stderr = stderr_filter.call(stderr) if stderr_filter
|
||||
if timeout_error
|
||||
bt = caller_locations
|
||||
msg = "execution of #{bt.shift.label} expired"
|
||||
msg = Test::Unit::Assertions::FailDesc[status, msg, [stdout, stderr].join("\n")].()
|
||||
raise timeout_error, msg, bt.map(&:to_s)
|
||||
end
|
||||
return stdout, stderr, status
|
||||
end
|
||||
ensure
|
||||
[th_stdout, th_stderr].each do |th|
|
||||
th.kill if th
|
||||
end
|
||||
[in_c, in_p, out_c, out_p, err_c, err_p].each do |io|
|
||||
io&.close
|
||||
end
|
||||
[th_stdout, th_stderr].each do |th|
|
||||
th.join if th
|
||||
end
|
||||
end
|
||||
module_function :invoke_ruby
|
||||
|
||||
alias rubyexec invoke_ruby
|
||||
class << self
|
||||
alias rubyexec invoke_ruby
|
||||
end
|
||||
|
||||
def verbose_warning
|
||||
class << (stderr = "")
|
||||
alias write <<
|
||||
end
|
||||
stderr, $stderr, verbose, $VERBOSE = $stderr, stderr, $VERBOSE, true
|
||||
yield stderr
|
||||
return $stderr
|
||||
ensure
|
||||
stderr, $stderr, $VERBOSE = $stderr, stderr, verbose
|
||||
end
|
||||
module_function :verbose_warning
|
||||
|
||||
def default_warning
|
||||
verbose, $VERBOSE = $VERBOSE, false
|
||||
yield
|
||||
ensure
|
||||
$VERBOSE = verbose
|
||||
end
|
||||
module_function :default_warning
|
||||
|
||||
def suppress_warning
|
||||
verbose, $VERBOSE = $VERBOSE, nil
|
||||
yield
|
||||
ensure
|
||||
$VERBOSE = verbose
|
||||
end
|
||||
module_function :suppress_warning
|
||||
|
||||
def under_gc_stress(stress = true)
|
||||
stress, GC.stress = GC.stress, stress
|
||||
yield
|
||||
ensure
|
||||
GC.stress = stress
|
||||
end
|
||||
module_function :under_gc_stress
|
||||
|
||||
def with_default_external(enc)
|
||||
verbose, $VERBOSE = $VERBOSE, nil
|
||||
origenc, Encoding.default_external = Encoding.default_external, enc
|
||||
$VERBOSE = verbose
|
||||
yield
|
||||
ensure
|
||||
verbose, $VERBOSE = $VERBOSE, nil
|
||||
Encoding.default_external = origenc
|
||||
$VERBOSE = verbose
|
||||
end
|
||||
module_function :with_default_external
|
||||
|
||||
def with_default_internal(enc)
|
||||
verbose, $VERBOSE = $VERBOSE, nil
|
||||
origenc, Encoding.default_internal = Encoding.default_internal, enc
|
||||
$VERBOSE = verbose
|
||||
yield
|
||||
ensure
|
||||
verbose, $VERBOSE = $VERBOSE, nil
|
||||
Encoding.default_internal = origenc
|
||||
$VERBOSE = verbose
|
||||
end
|
||||
module_function :with_default_internal
|
||||
|
||||
def labeled_module(name, &block)
|
||||
Module.new do
|
||||
singleton_class.class_eval {define_method(:to_s) {name}; alias inspect to_s}
|
||||
class_eval(&block) if block
|
||||
end
|
||||
end
|
||||
module_function :labeled_module
|
||||
|
||||
def labeled_class(name, superclass = Object, &block)
|
||||
Class.new(superclass) do
|
||||
singleton_class.class_eval {define_method(:to_s) {name}; alias inspect to_s}
|
||||
class_eval(&block) if block
|
||||
end
|
||||
end
|
||||
module_function :labeled_class
|
||||
|
||||
if /darwin/ =~ RUBY_PLATFORM
|
||||
DIAGNOSTIC_REPORTS_PATH = File.expand_path("~/Library/Logs/DiagnosticReports")
|
||||
DIAGNOSTIC_REPORTS_TIMEFORMAT = '%Y-%m-%d-%H%M%S'
|
||||
@ruby_install_name = RbConfig::CONFIG['RUBY_INSTALL_NAME']
|
||||
|
||||
def self.diagnostic_reports(signame, pid, now)
|
||||
return unless %w[ABRT QUIT SEGV ILL TRAP].include?(signame)
|
||||
cmd = File.basename(rubybin)
|
||||
cmd = @ruby_install_name if "ruby-runner#{RbConfig::CONFIG["EXEEXT"]}" == cmd
|
||||
path = DIAGNOSTIC_REPORTS_PATH
|
||||
timeformat = DIAGNOSTIC_REPORTS_TIMEFORMAT
|
||||
pat = "#{path}/#{cmd}_#{now.strftime(timeformat)}[-_]*.crash"
|
||||
first = true
|
||||
30.times do
|
||||
first ? (first = false) : sleep(0.1)
|
||||
Dir.glob(pat) do |name|
|
||||
log = File.read(name) rescue next
|
||||
if /\AProcess:\s+#{cmd} \[#{pid}\]$/ =~ log
|
||||
File.unlink(name)
|
||||
File.unlink("#{path}/.#{File.basename(name)}.plist") rescue nil
|
||||
return log
|
||||
end
|
||||
end
|
||||
end
|
||||
nil
|
||||
end
|
||||
else
|
||||
def self.diagnostic_reports(signame, pid, now)
|
||||
end
|
||||
end
|
||||
|
||||
def self.gc_stress_to_class?
|
||||
unless defined?(@gc_stress_to_class)
|
||||
_, _, status = invoke_ruby(["-e""exit GC.respond_to?(:add_stress_to_class)"])
|
||||
@gc_stress_to_class = status.success?
|
||||
end
|
||||
@gc_stress_to_class
|
||||
end
|
||||
end
|
||||
|
||||
if defined?(RbConfig)
|
||||
module RbConfig
|
||||
@ruby = EnvUtil.rubybin
|
||||
class << self
|
||||
undef ruby if method_defined?(:ruby)
|
||||
attr_reader :ruby
|
||||
end
|
||||
dir = File.dirname(ruby)
|
||||
name = File.basename(ruby, CONFIG['EXEEXT'])
|
||||
CONFIG['bindir'] = dir
|
||||
CONFIG['ruby_install_name'] = name
|
||||
CONFIG['RUBY_INSTALL_NAME'] = name
|
||||
Gem::ConfigMap[:bindir] = dir if defined?(Gem::ConfigMap)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,22 @@
|
|||
# frozen_string_literal: false
|
||||
require "rbconfig"
|
||||
|
||||
module EnvUtil
|
||||
def find_executable(cmd, *args)
|
||||
exts = RbConfig::CONFIG["EXECUTABLE_EXTS"].split | [RbConfig::CONFIG["EXEEXT"]]
|
||||
ENV["PATH"].split(File::PATH_SEPARATOR).each do |path|
|
||||
next if path.empty?
|
||||
path = File.join(path, cmd)
|
||||
exts.each do |ext|
|
||||
cmdline = [path + ext, *args]
|
||||
begin
|
||||
return cmdline if yield(IO.popen(cmdline, "r", err: [:child, :out], &:read))
|
||||
rescue
|
||||
next
|
||||
end
|
||||
end
|
||||
end
|
||||
nil
|
||||
end
|
||||
module_function :find_executable
|
||||
end
|
|
@ -15,6 +15,7 @@ module TestWEBrick
|
|||
|
||||
class WEBrick::HTTPServlet::CGIHandler
|
||||
remove_const :Ruby
|
||||
require "envutil" unless defined?(EnvUtil)
|
||||
Ruby = EnvUtil.rubybin
|
||||
remove_const :CGIRunner
|
||||
CGIRunner = "\"#{Ruby}\" \"#{WEBrick::Config::LIBDIR}/httpservlet/cgi_runner.rb\"" # :nodoc:
|
||||
|
@ -26,6 +27,7 @@ module TestWEBrick
|
|||
RubyBin << " \"-I#{File.dirname(EnvUtil.rubybin)}/.ext/common\""
|
||||
RubyBin << " \"-I#{File.dirname(EnvUtil.rubybin)}/.ext/#{RUBY_PLATFORM}\""
|
||||
|
||||
require "test/unit" unless defined?(Test::Unit)
|
||||
include Test::Unit::Assertions
|
||||
extend Test::Unit::Assertions
|
||||
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
Gem::Specification.new do |s|
|
||||
s.name = "webrick"
|
||||
s.version = '0.0.1'
|
||||
s.date = '2017-01-30'
|
||||
s.summary = "HTTP server toolkit"
|
||||
s.description = "WEBrick is an HTTP server toolkit that can be configured as an HTTPS server, a proxy server, and a virtual-host server."
|
||||
|
||||
s.require_path = %w{lib}
|
||||
s.files = ["lib/webrick.rb", "lib/webrick/accesslog.rb", "lib/webrick/cgi.rb", "lib/webrick/compat.rb", "lib/webrick/config.rb", "lib/webrick/cookie.rb", "lib/webrick/htmlutils.rb", "lib/webrick/httpauth.rb", "lib/webrick/httpauth/authenticator.rb", "lib/webrick/httpauth/basicauth.rb", "lib/webrick/httpauth/digestauth.rb", "lib/webrick/httpauth/htdigest.rb", "lib/webrick/httpauth/htgroup.rb", "lib/webrick/httpauth/htpasswd.rb", "lib/webrick/httpauth/userdb.rb", "lib/webrick/httpauth.rb", "lib/webrick/httpproxy.rb", "lib/webrick/httprequest.rb", "lib/webrick/httpresponse.rb", "lib/webrick/https.rb", "lib/webrick/httpserver.rb", "lib/webrick/httpservlet.rb", "lib/webrick/httpservlet/abstract.rb", "lib/webrick/httpservlet/cgi_runner.rb", "lib/webrick/httpservlet/cgihandler.rb", "lib/webrick/httpservlet/erbhandler.rb", "lib/webrick/httpservlet/filehandler.rb", "lib/webrick/httpservlet/prochandler.rb", "lib/webrick/httpservlet.rb", "lib/webrick/httpstatus.rb", "lib/webrick/httputils.rb", "lib/webrick/httpversion.rb", "lib/webrick/log.rb", "lib/webrick/server.rb", "lib/webrick/ssl.rb", "lib/webrick/utils.rb", "lib/webrick/version.rb"]
|
||||
s.required_ruby_version = ">= 2.5.0dev"
|
||||
|
||||
s.authors = ["TAKAHASHI Masayoshi", "GOTOU YUUZOU"]
|
||||
s.email = [nil, nil]
|
||||
s.homepage = "https://www.ruby-lang.org"
|
||||
s.license = "BSD-2-Clause"
|
||||
|
||||
s.add_development_dependency "test-unit"
|
||||
end
|
Loading…
Reference in New Issue