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_TYPELIB
objects represent OLE tyblib information.
Implementation of an X.509 certificate as specified in RFC 5280. Provides access to a certificate’s attributes and allows certificates to be read from a string, but also supports the creation of new certificates from scratch.
Certificate
is capable of handling DER-encoded certificates and certificates encoded in OpenSSL’s PEM format.
raw = File.read "cert.cer" # DER- or PEM-encoded certificate = OpenSSL::X509::Certificate.new raw
A certificate may be encoded in DER format
cert = ... File.open("cert.cer", "wb") { |f| f.print cert.to_der }
or in PEM format
cert = ... File.open("cert.pem", "wb") { |f| f.print cert.to_pem }
X.509 certificates are associated with a private/public key pair, typically a RSA, DSA or ECC key (see also OpenSSL::PKey::RSA
, OpenSSL::PKey::DSA
and OpenSSL::PKey::EC
), the public key itself is stored within the certificate and can be accessed in form of an OpenSSL::PKey
. Certificates are typically used to be able to associate some form of identity with a key pair, for example web servers serving pages over HTTPs use certificates to authenticate themselves to the user.
The public key infrastructure (PKI) model relies on trusted certificate authorities (“root CAs”) that issue these certificates, so that end users need to base their trust just on a selected few authorities that themselves again vouch for subordinate CAs issuing their certificates to end users.
The OpenSSL::X509
module provides the tools to set up an independent PKI, similar to scenarios where the ‘openssl’ command line tool is used for issuing certificates in a private PKI.
First, we need to create a “self-signed” root certificate. To do so, we need to generate a key first. Please note that the choice of “1” as a serial number is considered a security flaw for real certificates. Secure choices are integers in the two-digit byte range and ideally not sequential but secure random numbers, steps omitted here to keep the example concise.
root_key = OpenSSL::PKey::RSA.new 2048 # the CA's public/private key root_ca = OpenSSL::X509::Certificate.new root_ca.version = 2 # cf. RFC 5280 - to make it a "v3" certificate root_ca.serial = 1 root_ca.subject = OpenSSL::X509::Name.parse "/DC=org/DC=ruby-lang/CN=Ruby CA" root_ca.issuer = root_ca.subject # root CA's are "self-signed" root_ca.public_key = root_key.public_key root_ca.not_before = Time.now root_ca.not_after = root_ca.not_before + 2 * 365 * 24 * 60 * 60 # 2 years validity ef = OpenSSL::X509::ExtensionFactory.new ef.subject_certificate = root_ca ef.issuer_certificate = root_ca root_ca.add_extension(ef.create_extension("basicConstraints","CA:TRUE",true)) root_ca.add_extension(ef.create_extension("keyUsage","keyCertSign, cRLSign", true)) root_ca.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false)) root_ca.add_extension(ef.create_extension("authorityKeyIdentifier","keyid:always",false)) root_ca.sign(root_key, OpenSSL::Digest::SHA256.new)
The next step is to create the end-entity certificate using the root CA certificate.
key = OpenSSL::PKey::RSA.new 2048 cert = OpenSSL::X509::Certificate.new cert.version = 2 cert.serial = 2 cert.subject = OpenSSL::X509::Name.parse "/DC=org/DC=ruby-lang/CN=Ruby certificate" cert.issuer = root_ca.subject # root CA is the issuer cert.public_key = key.public_key cert.not_before = Time.now cert.not_after = cert.not_before + 1 * 365 * 24 * 60 * 60 # 1 years validity ef = OpenSSL::X509::ExtensionFactory.new ef.subject_certificate = cert ef.issuer_certificate = root_ca cert.add_extension(ef.create_extension("keyUsage","digitalSignature", true)) cert.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false)) cert.sign(root_key, OpenSSL::Digest::SHA256.new)
An OpenSSL::OCSP::CertificateId
identifies a certificate to the CA so that a status check can be performed.
A Gem::Security::Policy
object encapsulates the settings for verifying signed gem files. This is the base class. You can either declare an instance of this or use one of the preset security policies in Gem::Security::Policies.
Used internally to indicate that a dependency conflicted with a spec that would be activated.
Raised if a parameter such as %e, %i, %o or %n is used without fetching a specific field.
Raised by Encoding
and String
methods when the source encoding is incompatible with the target encoding.
This exception is raised if the required unicode support is missing on the system. Usually this means that the iconv library is not installed.
Generic error, common for all classes under OpenSSL
module
Document-class: OpenSSL::HMAC
OpenSSL::HMAC
allows computing Hash-based Message Authentication Code (HMAC
). It is a type of message authentication code (MAC) involving a hash function in combination with a key. HMAC
can be used to verify the integrity of a message as well as the authenticity.
OpenSSL::HMAC
has a similar interface to OpenSSL::Digest
.
key = "key" data = "message-to-be-authenticated" mac = OpenSSL::HMAC.hexdigest("SHA256", key, data) #=> "cddb0db23f469c8bf072b21fd837149bd6ace9ab771cceef14c9e517cc93282e"
data1 = File.read("file1") data2 = File.read("file2") key = "key" digest = OpenSSL::Digest::SHA256.new hmac = OpenSSL::HMAC.new(key, digest) hmac << data1 hmac << data2 mac = hmac.digest