Module: PhusionPassenger::Utils
- Extended by:
- Utils
- Included in:
- AnalyticsLogger, MessageClient, RequestHandler, RequestHandler::ThreadHandler, Utils
- Defined in:
- lib/phusion_passenger/utils.rb,
lib/phusion_passenger/utils/json.rb,
lib/phusion_passenger/utils/tmpio.rb,
lib/phusion_passenger/utils/tmpdir.rb,
lib/phusion_passenger/utils/tee_input.rb,
lib/phusion_passenger/utils/ansi_colors.rb,
lib/phusion_passenger/utils/hosts_file_parser.rb,
lib/phusion_passenger/utils/unseekable_socket.rb,
lib/phusion_passenger/utils/file_system_watcher.rb
Overview
Utility functions.
Defined Under Namespace
Modules: AnsiColors Classes: FileSystemWatcher, GeneratorTest, HostsFileParser, JSON, ParserTest, TeeInput, TmpIO, UnseekableSocket
Constant Summary collapse
- NULL =
"\0".freeze
Class Method Summary collapse
- .included(klass) ⇒ Object
-
.mktmpdir(prefix_suffix = nil, tmpdir = nil) ⇒ Object
Like Dir.mktmpdir, but creates shorter filenames.
Instance Method Summary collapse
- #connect_to_server(address) ⇒ Object
-
#generate_random_id(method) ⇒ Object
Generate a long, cryptographically secure random ID string, which is also a valid filename.
- #get_socket_address_type(address) ⇒ Object
-
#global_backtrace_report ⇒ Object
Returns a string which reports the backtraces for all threads, or if that’s not supported the backtrace for the current thread.
- #install_options_as_ivars(object, options, *keys) ⇒ Object
- #local_socket_address?(address) ⇒ Boolean
-
#print_exception(current_location, exception, destination = nil) ⇒ Object
Print the given exception, including the stack trace, to STDERR.
-
#process_is_alive?(pid) ⇒ Boolean
Checks whether the given process exists.
- #require_option(hash, key) ⇒ Object
-
#split_by_null_into_hash(data) ⇒ Object
Split the given string into an hash.
Class Method Details
.included(klass) ⇒ Object
37 38 39 40 41 42 43 |
# File 'lib/phusion_passenger/utils.rb', line 37 def self.included(klass) # When included into another class, make sure that Utils # methods are made private. public_instance_methods(false).each do |method_name| klass.send(:private, method_name) end end |
.mktmpdir(prefix_suffix = nil, tmpdir = nil) ⇒ Object
Like Dir.mktmpdir, but creates shorter filenames.
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/phusion_passenger/utils/tmpio.rb', line 34 def self.mktmpdir(prefix_suffix=nil, tmpdir=nil) case prefix_suffix when nil prefix = "d" suffix = "" when String prefix = prefix_suffix suffix = "" when Array prefix = prefix_suffix[0] suffix = prefix_suffix[1] else raise ArgumentError, "unexpected prefix_suffix: #{prefix_suffix.inspect}" end tmpdir ||= Dir.tmpdir begin path = "#{tmpdir}/#{prefix}#{rand(0x100000000).to_s(36)}" path << suffix Dir.mkdir(path, 0700) rescue Errno::EEXIST retry end if block_given? begin yield path ensure FileUtils.remove_entry_secure path end else path end end |
Instance Method Details
#connect_to_server(address) ⇒ Object
93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/phusion_passenger/utils.rb', line 93 def connect_to_server(address) case get_socket_address_type(address) when :unix return UNIXSocket.new(address.sub(/^unix:/, '')) when :tcp host, port = address.sub(%r{^tcp://}, '').split(':', 2) port = port.to_i return TCPSocket.new(host, port) else raise ArgumentError, "Unknown socket address type for '#{address}'." end end |
#generate_random_id(method) ⇒ Object
Generate a long, cryptographically secure random ID string, which is also a valid filename.
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/phusion_passenger/utils.rb', line 47 def generate_random_id(method) data = File.open("/dev/urandom", "rb") do |f| f.read(64) end case method when :base64 data = [data].pack('m') data.gsub!("\n", '') data.gsub!("+", '') data.gsub!("/", '') data.gsub!(/==$/, '') return data when :hex return data.unpack('H*')[0] else raise ArgumentError, "Invalid method #{method.inspect}" end end |
#get_socket_address_type(address) ⇒ Object
83 84 85 86 87 88 89 90 91 |
# File 'lib/phusion_passenger/utils.rb', line 83 def get_socket_address_type(address) if address =~ %r{^unix:.} return :unix elsif address =~ %r{^tcp://.} return :tcp else return :unknown end end |
#global_backtrace_report ⇒ Object
Returns a string which reports the backtraces for all threads, or if that’s not supported the backtrace for the current thread.
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/phusion_passenger/utils.rb', line 146 def global_backtrace_report if Kernel.respond_to?(:caller_for_all_threads) all_thread_stacks = caller_for_all_threads elsif Thread.respond_to?(:list) && Thread.public_method_defined?(:backtrace) all_thread_stacks = {} Thread.list.each do |thread| all_thread_stacks[thread] = thread.backtrace end end output = "========== Process #{Process.pid}: backtrace dump ==========\n" if all_thread_stacks all_thread_stacks.each_pair do |thread, stack| if thread_name = thread[:name] thread_name = "(#{thread_name})" end output << ("-" * 60) << "\n" output << "# Thread: #{thread.inspect}#{thread_name}, " if thread == Thread.main output << "[main thread], " end if thread == Thread.current output << "[current thread], " end output << "alive = #{thread.alive?}\n" output << ("-" * 60) << "\n" output << " " << stack.join("\n ") output << "\n\n" end else output << ("-" * 60) << "\n" output << "# Current thread: #{Thread.current.inspect}\n" output << ("-" * 60) << "\n" output << " " << caller.join("\n ") end return output end |
#install_options_as_ivars(object, options, *keys) ⇒ Object
138 139 140 141 142 |
# File 'lib/phusion_passenger/utils.rb', line 138 def (object, , *keys) keys.each do |key| object.instance_variable_set("@#{key}", [key]) end end |
#local_socket_address?(address) ⇒ Boolean
106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/phusion_passenger/utils.rb', line 106 def local_socket_address?(address) case get_socket_address_type(address) when :unix return true when :tcp host, port = address.sub(%r{^tcp://}, '').split(':', 2) return host == "127.0.0.1" || host == "::1" || host == "localhost" else raise ArgumentError, "Unknown socket address type for '#{address}'." end end |
#print_exception(current_location, exception, destination = nil) ⇒ Object
Print the given exception, including the stack trace, to STDERR.
current_location
is a string which describes where the code is currently at. Usually the current class name will be enough.
70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/phusion_passenger/utils.rb', line 70 def print_exception(current_location, exception, destination = nil) if !exception.is_a?(SystemExit) data = exception.backtrace_string(current_location) if defined?(DebugLogging) && self.is_a?(DebugLogging) error(data) else destination ||= STDERR destination.puts(data) destination.flush if destination.respond_to?(:flush) end end end |
#process_is_alive?(pid) ⇒ Boolean
Checks whether the given process exists.
119 120 121 122 123 124 125 126 127 128 |
# File 'lib/phusion_passenger/utils.rb', line 119 def process_is_alive?(pid) begin Process.kill(0, pid) return true rescue Errno::ESRCH return false rescue SystemCallError => e return true end end |
#require_option(hash, key) ⇒ Object
130 131 132 133 134 135 136 |
# File 'lib/phusion_passenger/utils.rb', line 130 def require_option(hash, key) if hash.has_key?(key) return hash[key] else raise ArgumentError, "Option #{key.inspect} required" end end |
#split_by_null_into_hash(data) ⇒ Object
Split the given string into an hash. Keys and values are obtained by splitting the string using the null character as the delimitor.
187 188 189 |
# File 'lib/phusion_passenger/utils.rb', line 187 def split_by_null_into_hash(data) return PhusionPassenger::NativeSupport.split_by_null_into_hash(data) end |