Include the English
library file in a Ruby script, and you can reference the global variables such as VAR{$_} using less cryptic names, listed in the following table.% vref{tab:english}.
Without ‘English’:
$\ = ' -- ' "waterbuffalo" =~ /buff/ print $', $$, "\n"
With English:
require "English" $OUTPUT_FIELD_SEPARATOR = ' -- ' "waterbuffalo" =~ /buff/ print $POSTMATCH, $PID, "\n"
Below is a full list of descriptive aliases and their associated global variable:
$!
$@
$;
$;
$,
$,
$/
$/
$\
$\
$.
$.
$_
$>
$<
$$
$$
$?
$~
$=
$*
$&
$‘
$‘
$+
The Find
module supports the top-down traversal of a set of file paths.
For example, to total the size of all files under your home directory, ignoring anything in a “dot” directory (e.g. $HOME/.ssh):
require 'find' total_size = 0 Find.find(ENV["HOME"]) do |path| if FileTest.directory?(path) if File.basename(path)[0] == ?. Find.prune # Don't look any further into this directory. else next end else total_size += FileTest.size(path) end end
In concurrent programming, a monitor is an object or module intended to be used safely by more than one thread. The defining characteristic of a monitor is that its methods are executed with mutual exclusion. That is, at each point in time, at most one thread may be executing any of its methods. This mutual exclusion greatly simplifies reasoning about the implementation of monitors compared to reasoning about parallel code that updates a data structure.
You can read more about the general principles on the Wikipedia page for Monitors
require 'monitor.rb' buf = [] buf.extend(MonitorMixin) empty_cond = buf.new_cond # consumer Thread.start do loop do buf.synchronize do empty_cond.wait_while { buf.empty? } print buf.shift end end end # producer while line = ARGF.gets buf.synchronize do buf.push(line) empty_cond.signal end end
The consumer thread waits for the producer thread to push a line to buf while buf.empty?
. The producer thread (main thread) reads a line from ARGF
and pushes it into buf then calls empty_cond.signal
to notify the consumer thread of new data.
Class
include require 'monitor' class SynchronizedArray < Array include MonitorMixin def initialize(*args) super(*args) end alias :old_shift :shift alias :old_unshift :unshift def shift(n=1) self.synchronize do self.old_shift(n) end end def unshift(item) self.synchronize do self.old_unshift(item) end end # other methods ... end
SynchronizedArray
implements an Array
with synchronized access to items. This Class
is implemented as subclass of Array
which includes the MonitorMixin
module.
URI
is a module providing classes to handle Uniform Resource Identifiers (RFC2396).
Uniform way of handling URIs.
Flexibility to introduce custom URI
schemes.
Flexibility to have an alternate URI::Parser
(or just different patterns and regexp’s).
require 'uri' uri = URI("http://foo.com/posts?id=30&limit=5#time=1305298413") #=> #<URI::HTTP http://foo.com/posts?id=30&limit=5#time=1305298413> uri.scheme #=> "http" uri.host #=> "foo.com" uri.path #=> "/posts" uri.query #=> "id=30&limit=5" uri.fragment #=> "time=1305298413" uri.to_s #=> "http://foo.com/posts?id=30&limit=5#time=1305298413"
module URI class RSYNC < Generic DEFAULT_PORT = 873 end @@schemes['RSYNC'] = RSYNC end #=> URI::RSYNC URI.scheme_list #=> {"FILE"=>URI::File, "FTP"=>URI::FTP, "HTTP"=>URI::HTTP, # "HTTPS"=>URI::HTTPS, "LDAP"=>URI::LDAP, "LDAPS"=>URI::LDAPS, # "MAILTO"=>URI::MailTo, "RSYNC"=>URI::RSYNC} uri = URI("rsync://rsync.foo.com") #=> #<URI::RSYNC rsync://rsync.foo.com>
A good place to view an RFC spec is www.ietf.org/rfc.html.
Here is a list of all related RFC’s:
Class
tree URI::Generic
(in uri/generic.rb)
URI::File
- (in uri/file.rb)
URI::FTP
- (in uri/ftp.rb)
URI::HTTP
- (in uri/http.rb)
URI::HTTPS
- (in uri/https.rb)
URI::LDAP
- (in uri/ldap.rb)
URI::LDAPS
- (in uri/ldaps.rb)
URI::MailTo
- (in uri/mailto.rb)
URI::Parser
- (in uri/common.rb)
URI::REGEXP
- (in uri/common.rb)
URI::REGEXP::PATTERN - (in uri/common.rb)
URI::Util - (in uri/common.rb)
URI::Escape
- (in uri/common.rb)
URI::Error
- (in uri/common.rb)
URI::InvalidURIError
- (in uri/common.rb)
URI::InvalidComponentError
- (in uri/common.rb)
URI::BadURIError
- (in uri/common.rb)
Akira Yamada <akira@ruby-lang.org>
Akira Yamada <akira@ruby-lang.org> Dmitry V. Sabanin <sdmitry@lrn.ru> Vincent Batts <vbatts@hashbangbash.com>
Copyright © 2001 akira yamada <akira@ruby-lang.org> You can redistribute it and/or modify it under the same term as Ruby.
$Id: uri.rb 63228 2018-04-21 20:04:05Z stomar $
OpenURI
is an easy-to-use wrapper for Net::HTTP
, Net::HTTPS and Net::FTP
.
It is possible to open an http, https or ftp URL as though it were a file:
open("http://www.ruby-lang.org/") {|f| f.each_line {|line| p line} }
The opened file has several getter methods for its meta-information, as follows, since it is extended by OpenURI::Meta
.
open("http://www.ruby-lang.org/en") {|f| f.each_line {|line| p line} p f.base_uri # <URI::HTTP:0x40e6ef2 URL:http://www.ruby-lang.org/en/> p f.content_type # "text/html" p f.charset # "iso-8859-1" p f.content_encoding # [] p f.last_modified # Thu Dec 05 02:45:02 UTC 2002 }
Additional header fields can be specified by an optional hash argument.
open("http://www.ruby-lang.org/en/", "User-Agent" => "Ruby/#{RUBY_VERSION}", "From" => "foo@bar.invalid", "Referer" => "http://www.ruby-lang.org/") {|f| # ... }
The environment variables such as http_proxy, https_proxy and ftp_proxy are in effect by default. Here we disable proxy:
open("http://www.ruby-lang.org/en/", :proxy => nil) {|f| # ... }
See OpenURI::OpenRead.open
and Kernel#open
for more on available options.
URI
objects can be opened in a similar way.
uri = URI.parse("http://www.ruby-lang.org/en/") uri.open {|f| # ... }
URI
objects can be read directly. The returned string is also extended by OpenURI::Meta
.
str = uri.read p str.base_uri
Tanaka Akira <akr@m17n.org>
WEBrick
is an HTTP server toolkit that can be configured as an HTTPS server, a proxy server, and a virtual-host server. WEBrick
features complete logging of both server operations and HTTP access. WEBrick
supports both basic and digest authentication in addition to algorithms not in RFC 2617.
A WEBrick
server can be composed of multiple WEBrick
servers or servlets to provide differing behavior on a per-host or per-path basis. WEBrick
includes servlets for handling CGI
scripts, ERB
pages, Ruby blocks and directory listings.
WEBrick
also includes tools for daemonizing a process and starting a process at a higher privilege level and dropping permissions.
To create a new WEBrick::HTTPServer
that will listen to connections on port 8000 and serve documents from the current user’s public_html folder:
require 'webrick' root = File.expand_path '~/public_html' server = WEBrick::HTTPServer.new :Port => 8000, :DocumentRoot => root
To run the server you will need to provide a suitable shutdown hook as starting the server blocks the current thread:
trap 'INT' do server.shutdown end server.start
The easiest way to have a server perform custom operations is through WEBrick::HTTPServer#mount_proc
. The block given will be called with a WEBrick::HTTPRequest
with request info and a WEBrick::HTTPResponse
which must be filled in appropriately:
server.mount_proc '/' do |req, res| res.body = 'Hello, world!' end
Remember that server.mount_proc
must precede server.start
.
Advanced custom behavior can be obtained through mounting a subclass of WEBrick::HTTPServlet::AbstractServlet
. Servlets provide more modularity when writing an HTTP server than mount_proc allows. Here is a simple servlet:
class Simple < WEBrick::HTTPServlet::AbstractServlet def do_GET request, response status, content_type, body = do_stuff_with request response.status = 200 response['Content-Type'] = 'text/plain' response.body = 'Hello, World!' end end
To initialize the servlet you mount it on the server:
server.mount '/simple', Simple
See WEBrick::HTTPServlet::AbstractServlet
for more details.
A server can act as a virtual host for multiple host names. After creating the listening host, additional hosts that do not listen can be created and attached as virtual hosts:
server = WEBrick::HTTPServer.new # ... vhost = WEBrick::HTTPServer.new :ServerName => 'vhost.example', :DoNotListen => true, # ... vhost.mount '/', ... server.virtual_host vhost
If no :DocumentRoot
is provided and no servlets or procs are mounted on the main server it will return 404 for all URLs.
To create an HTTPS server you only need to enable SSL and provide an SSL certificate name:
require 'webrick' require 'webrick/https' cert_name = [ %w[CN localhost], ] server = WEBrick::HTTPServer.new(:Port => 8000, :SSLEnable => true, :SSLCertName => cert_name)
This will start the server with a self-generated self-signed certificate. The certificate will be changed every time the server is restarted.
To create a server with a pre-determined key and certificate you can provide them:
require 'webrick' require 'webrick/https' require 'openssl' cert = OpenSSL::X509::Certificate.new File.read '/path/to/cert.pem' pkey = OpenSSL::PKey::RSA.new File.read '/path/to/pkey.pem' server = WEBrick::HTTPServer.new(:Port => 8000, :SSLEnable => true, :SSLCertificate => cert, :SSLPrivateKey => pkey)
WEBrick
can act as a proxy server:
require 'webrick' require 'webrick/httpproxy' proxy = WEBrick::HTTPProxyServer.new :Port => 8000 trap 'INT' do proxy.shutdown end
See WEBrick::HTTPProxy for further details including modifying proxied responses.
Digest
authentication WEBrick
provides both Basic and Digest
authentication for regular and proxy servers. See WEBrick::HTTPAuth
, WEBrick::HTTPAuth::BasicAuth
and WEBrick::HTTPAuth::DigestAuth
.
WEBrick
as a Production Web Server WEBrick
can be run as a production server for small loads.
To start a WEBrick
server as a daemon simple run WEBrick::Daemon.start
before starting the server.
WEBrick
can be started as one user to gain permission to bind to port 80 or 443 for serving HTTP or HTTPS traffic then can drop these permissions for regular operation. To listen on all interfaces for HTTP traffic:
sockets = WEBrick::Utils.create_listeners nil, 80
Then drop privileges:
WEBrick::Utils.su 'www'
Then create a server that does not listen by default:
server = WEBrick::HTTPServer.new :DoNotListen => true, # ...
Then overwrite the listening sockets with the port 80 sockets:
server.listeners.replace sockets
WEBrick
can separately log server operations and end-user access. For server operations:
log_file = File.open '/var/log/webrick.log', 'a+' log = WEBrick::Log.new log_file
For user access logging:
access_log = [ [log_file, WEBrick::AccessLog::COMBINED_LOG_FORMAT], ] server = WEBrick::HTTPServer.new :Logger => log, :AccessLog => access_log
See WEBrick::AccessLog
for further log formats.
Log
Rotation To rotate logs in WEBrick
on a HUP signal (like syslogd can send), open the log file in ‘a+’ mode (as above) and trap ‘HUP’ to reopen the log file:
trap 'HUP' do log_file.reopen '/path/to/webrick.log', 'a+'
Author: IPR – Internet Programming with Ruby – writers
Copyright © 2000 TAKAHASHI Masayoshi, GOTOU YUUZOU Copyright © 2002 Internet Programming with Ruby writers. All rights reserved.
WIN32OLE_EVENT
objects controls OLE event.
WIN32OLE_METHOD
objects represent OLE method information.
WIN32OLE_PARAM
objects represent param information of the OLE method.
WIN32OLE_RECORD
objects represents VT_RECORD OLE variant. Win32OLE returns WIN32OLE_RECORD
object if the result value of invoking OLE methods.
If COM server in VB.NET ComServer project is the following:
Imports System.Runtime.InteropServices Public Class ComClass Public Structure Book <MarshalAs(UnmanagedType.BStr)> _ Public title As String Public cost As Integer End Structure Public Function getBook() As Book Dim book As New Book book.title = "The Ruby Book" book.cost = 20 Return book End Function End Class
then, you can retrieve getBook return value from the following Ruby script:
require 'win32ole' obj = WIN32OLE.new('ComServer.ComClass') book = obj.getBook book.class # => WIN32OLE_RECORD book.title # => "The Ruby Book" book.cost # => 20
WIN32OLE_TYPE
objects represent OLE type libarary information.
WIN32OLE_TYPELIB
objects represent OLE tyblib information.
Enumerator::Chain
is a subclass of Enumerator
, which represents a chain of enumerables that works as a single enumerator.
This type of objects can be created by Enumerable#chain
and Enumerator#+
.
Enumerator::ArithmeticSequence
is a subclass of Enumerator
, that is a representation of sequences of numbers with common difference. Instances of this class can be generated by the Range#step
and Numeric#step
methods.
Fiddle::Pointer
is a class to handle C pointers
This class is used as a return value from ObjectSpace::reachable_objects_from
.
When ObjectSpace::reachable_objects_from
returns an object with references to an internal object, an instance of this class is returned.
You can use the type
method to check the type of the internal object.
OpenSSL::Digest
allows you to compute message digests (sometimes interchangeably called “hashes”) of arbitrary data that are cryptographically secure, i.e. a Digest
implements a secure one-way function.
One-way functions offer some useful properties. E.g. given two distinct inputs the probability that both yield the same output is highly unlikely. Combined with the fact that every message digest algorithm has a fixed-length output of just a few bytes, digests are often used to create unique identifiers for arbitrary data. A common example is the creation of a unique id for binary documents that are stored in a database.
Another useful characteristic of one-way functions (and thus the name) is that given a digest there is no indication about the original data that produced it, i.e. the only way to identify the original input is to “brute-force” through every possible combination of inputs.
These characteristics make one-way functions also ideal companions for public key signature algorithms: instead of signing an entire document, first a hash of the document is produced with a considerably faster message digest algorithm and only the few bytes of its output need to be signed using the slower public key algorithm. To validate the integrity of a signed document, it suffices to re-compute the hash and verify that it is equal to that in the signature.
Among the supported message digest algorithms are:
SHA, SHA1, SHA224, SHA256, SHA384 and SHA512
MD2, MD4, MDC2 and MD5
RIPEMD160
DSS, DSS1 (Pseudo algorithms to be used for DSA signatures. DSS is equal to SHA and DSS1 is equal to SHA1)
For each of these algorithms, there is a sub-class of Digest
that can be instantiated as simply as e.g.
digest = OpenSSL::Digest::SHA1.new
Digest
class and sn/ln The sn (short names) and ln (long names) are defined in <openssl/object.h> and <openssl/obj_mac.h>. They are textual representations of ASN.1 OBJECT IDENTIFIERs. Each supported digest algorithm has an OBJECT IDENTIFIER associated to it and those again have short/long names assigned to them. E.g. the OBJECT IDENTIFIER for SHA-1 is 1.3.14.3.2.26 and its sn is “SHA1” and its ln is “sha1”.
sn: MD2
ln: md2
sn: MD4
ln: md4
sn: MD5
ln: md5
sn: SHA
ln: SHA
sn: SHA1
ln: sha1
sn: SHA224
ln: sha224
sn: SHA256
ln: sha256
sn: SHA384
ln: sha384
sn: SHA512
ln: sha512
“Breaking” a message digest algorithm means defying its one-way function characteristics, i.e. producing a collision or finding a way to get to the original data by means that are more efficient than brute-forcing etc. Most of the supported digest algorithms can be considered broken in this sense, even the very popular MD5 and SHA1 algorithms. Should security be your highest concern, then you should probably rely on SHA224, SHA256, SHA384 or SHA512.
data = File.read('document') sha256 = OpenSSL::Digest::SHA256.new digest = sha256.digest(data)
data1 = File.read('file1') data2 = File.read('file2') data3 = File.read('file3') sha256 = OpenSSL::Digest::SHA256.new sha256 << data1 sha256 << data2 sha256 << data3 digest = sha256.digest
Digest
instance data1 = File.read('file1') sha256 = OpenSSL::Digest::SHA256.new digest1 = sha256.digest(data1) data2 = File.read('file2') sha256.reset digest2 = sha256.digest(data2)