Programming Ruby: The Pragmatic Programmer's Guide

# Programming Ruby ### The Pragmatic Programmer's Guide
Previous < | Contents ^ | Next >

# Network and Web Libraries

Ruby provides two levels of access to network services. At a low level, you can access the basic socket support in the underlying operating system, which allows you to implement clients and servers for both connection-oriented and connectionless protocols. These are documented in the next section.

Ruby also has libraries that provide higher-level access to specific application-level network protocols, such as FTP, HTTP, and so on. These are documented starting on page 482.

Finally, the `CGI` libraries, documented beginning on page 497, provide server-side developers with a convenient interface for developing Web applications.

## Socket-Level Access

Sockets are the endpoints of a bidirectional communications channel. Sockets may communicate within a process, between processes on the same machine, or between processes on different continents. Sockets may be implemented over a number of different channel types: Unix domain sockets, TCP, UDP, and so on. The socket library provides specific classes for handling the common transports as well as a generic interface for handling the rest. All functionality in the socket library is accessible through a single extension library. Access it using

    require 'socket'

Sockets have their own vocabulary:

domain
  The family of protocols that will be used as the transport mechanism. These values are constants such as `PF_INET`, `PF_UNIX`, `PF_X25`, and so on.
type
  The type of communications between the two endpoints, typically `SOCK_STREAM` for connection-oriented protocols and `SOCK_DGRAM` for connectionless protocols.
protocol
  Typically zero, this may be used to identify a variant of a protocol within a domain and type.
hostName
  The identifier of a network interface:
  - a string, which can be a host name, a dotted-quad address, or an IPV6 address in colon (and possibly dot) notation,
  - the string ``<broadcast>'', which specifies an `INADDR_BROADCAST` address,
  - a zero-length string, which specifies `INADDR_ANY`, or
  - an `Integer`, interpreted as a binary address in host byte order.
port
  (sometimes called service) Each server listens for clients calling on one or more ports. A port may be a `Fixnum` port number, a string containing a port number, or the name of a service.

Sockets are children of class `IO`. Once a socket has been successfully opened, the conventional I/O methods may be used. However, greater efficiency is sometimes obtained by using socket-specific methods. As with other I/O classes, socket I/O blocks by default. The hierarchy of the socket classes is shown in Figure 26.1 on page 471.

For more information on the use of sockets, see your operating system documentation. You'll also find a comprehensive treatment in W. Richard Stevens, Unix Network Programming, Volumes 1 and 2 .

class BasicSocket |
Parent: | IO
Version: | 1.6

### Index:

do_not_reverse_lookup do_not_reverse_lookup= lookup_order lookup_order= close_read close_write getpeername getsockname getsockopt recv send setsockopt shutdown

`BasicSocket` is an abstract base class for all other socket classes.

This class and its subclasses often manipulate addresses using something called a `struct sockaddr`, which is effectively an opaque binary string.[In reality, it maps onto the underlying C-language `struct sockaddr` set of structures, documented in the man pages and in the books by Stevens.]

class methods
do_not_reverse_lookup | BasicSocket.do_not_reverse_lookup -> `true` or `false`
|  | Returns the value of the global reverse lookup flag. If set to `true`, queries on remote addresses will return the numeric address but not the host name.
do_not_reverse_lookup= | BasicSocket.do_not_reverse_lookup = `true` or `false`
|  | Sets the global reverse lookup flag.
lookup_order | BasicSocket.lookup_order -> aFixnum
|  | Returns the global address lookup order, one of:
Order | Families Searched
`LOOKUP_UNSP` | `AF_UNSPEC`
`LOOKUP_INET` | `AF_INET`, `AF_INET6`, `AF_UNSPEC`
`LOOKUP_INET6` | `AF_INET6`, `AF_INET`, `AF_UNSPEC`
lookup_order= | BasicSocket.lookup_order = aFixnum
|  | Sets the global address lookup order.

instance methods
close_read | aSession.close_read -> `nil`
|  | Closes the readable connection on this socket.
close_write | aSession.close_write -> `nil`
|  | Closes the writable connection on this socket.
getpeername | aSession.getpeername -> aString
|  | Returns the `struct sockaddr` structure associated with the other end of this socket connection.
getsockname | aSession.getsockname -> aString
|  | Returns the `struct sockaddr` structure associated with aSession.
getsockopt | aSession.getsockopt( level, optname ) -> aString
|  | Returns the value of the specified option.
recv | aSession.recv( len, [, flags ] ) -> aString
|  | Receives up to len bytes from aSession.
send | aSession.send( aString, flags, [, to ] ) -> aFixnum
|  | Sends aString over aSession. If specified, to is a `struct sockaddr` specifying the recipient address. flags are the sum or one or more of the `MSG_` options (listed on page 478). Returns the number of characters sent.
setsockopt | aSession.setsockopt( level, optname, optval ) -> 0
|  | Sets a socket option. level is one of the socket-level options (listed on page 478). optname and optval are protocol specific---see your system documentation for details.
shutdown | aSession.shutdown( how=2 ) -> 0
|  | Shuts down the receive (how == 0), or send (how == 1), or both (how == 2), parts of this socket.

class IPSocket |
Parent: | BasicSocket
Version: | 1.6

### Index:

getaddress addr peeraddr

Class `IPSocket` is a base class for sockets using IP as their transport. `TCPSocket` and `UDPSocket` are based on this class.

class methods
getaddress | IPSocket.getaddress( hostName ) -> aString
|  | Returns the dotted-quad IP address of hostName.
`a = IPSocket.getaddress('www.ruby-lang.org')`
`a` | » | `"210.251.121.214"`

instance methods
addr | aSession.addr -> anArray
|  | Returns the domain, port, name, and IP address of aSession as a four-element array. The name will be returned as an address if the `do_not_reverse_lookup` flag is `true`.
`u = UDPSocket.new`
`u.bind('localhost', 8765)`
`u.addr` | » | `["AF_INET", 8765, "localhost", "127.0.0.1"]`
`BasicSocket.do_not_reverse_lookup = true`
`u.addr` | » | `["AF_INET", 8765, "127.0.0.1", "127.0.0.1"]`
peeraddr | aSession.peeraddr -> anArray
|  | Returns the domain, port, name, and IP address of the peer.

class TCPSocket |
Parent: | IPSocket
Version: | 1.6

### Index:

gethostbyname new open recvfrom

`t = TCPSocket.new('localhost', 'ftp')`
`t.gets` | » | `"220 zip.local.thomases.com FTP server (Version 6.5/OpenBSD, linux port 0.3.2) ready.\r\n"`
`t.close` | » | `nil`

class methods
gethostbyname | TCPSocket.gethostbyname( hostName ) -> anArray
|  | Looks up hostName and returns its canonical name, an array containing any aliases, the address type (`AF_INET`), and the dotted-quad IP address.
`a = TCPSocket.gethostbyname('ns.pragprog.com')`
`a` | » | `["pragprog.com", [], 2, "216.87.136.211"]`
new | TCPSocket.new( hostName, port ) -> aSession
|  | Opens a TCP connection to hostName on the port.
open | TCPSocket.open( hostName, port ) -> aSession
|  | Synonym for `TCPSocket.new`.

instance methods
recvfrom | aSession.recvfrom( len [, flags ] ) -> anArray
|  | Receives up to len bytes on the connection. flags is zero or more of the `MSG_` options (listed on page 478). Returns a two-element array. The first element is the received data, the second is an array containing information about the peer.
    t = TCPSocket.new('localhost', 'ftp')
    data = t.recvfrom(30)
    data

class SOCKSSocket |
Parent: | TCPSocket
Version: | 1.6

### Index:

new open close

Class `SOCKSSocket` supports connections based on the SOCKS protocol.

class methods
new | SOCKSSocket.new( hostName, port ) -> aSession
|  | Opens a SOCKS connection to port on hostName.
open | SOCKSSocket.open( hostName, port ) -> aSession
|  | Synonym for `SOCKSSocket.new`.

instance methods
close | aSession.close -> `nil`
|  | Closes this SOCKS connection.

class TCPServer |
Parent: | TCPSocket
Version: | 1.6

### Index:

new open accept

A `TCPServer` accepts incoming TCP connections. Here is a Web server that listens on a given port and returns the time.

    require 'socket'
    port = (ARGV[0] || 80).to_i
    server = TCPServer.new('localhost', port)
    while (session = server.accept)
      puts "Request: #{session.gets}"
      session.print "HTTP/1.1 200/OK\r\nContent-type: text/html\r\n\r\n"
      session.print "<html><body><h1>#{Time.now}</h1></body></html>\r\n"
      session.close
    end

class methods
new | TCPServer.new( [ hostName,] port ) -> aSession
|  | Creates a new socket on the given interface (identified by hostName and port). If hostName is omitted, the server will listen on all interfaces on the current host (equivalent to an address of 0.0.0.0).
open | TCPServer.open( [ hostName,] port ) -> aSession
|  | Synonym for `TCPServer.new`.

instance methods
accept | aSession.accept -> aTCPSocket
|  | Waits for a connection on aSession, and returns a new `TCPSocket` connected to the caller. See the example on page 474.

class UDPSocket |
Parent: | IPSocket
Version: | 1.6

### Index:

new open bind connect recvfrom send

UDP sockets send and receive datagrams. In order to receive data, a socket must be bound to a particular port. You have two choices when sending data: you can connect to a remote UDP socket and thereafter send datagrams to that port, or you can specify a host and port for use with every packet you send. This example is a UDP server that prints the message it receives. It is called by both connectionless and connection-based clients.

    require 'socket'

    $port = 4321

    sThread = Thread.start do     # run server in a thread
      server = UDPSocket.open
      server.bind(nil, $port)
      2.times { p server.recvfrom(64) }
    end

    # Ad-hoc client
    UDPSocket.open.send("ad hoc", 0, 'localhost', $port)

    # Connection based client
    sock = UDPSocket.open
    sock.connect('localhost', $port)
    sock.send("connection-based", 0)
    sThread.join

produces:

    ["ad hoc", ["AF_INET", 32893, "localhost", "127.0.0.1"]]
    ["connection-based", ["AF_INET", 32894, "localhost", "127.0.0.1"]]

class methods
new | UDPSocket.new( family = `AF_INET` ) -> aSession
|  | Creates an endpoint for UDP communications, optionally specifying the address family.
open | UDPSocket.open( family = `AF_INET` ) -> aSession
|  | Synonym for `UDPSocket.new`.

instance methods
bind | aSession.bind( hostName, port ) -> 0
|  | Associates the local end of the UDP connection with a given hostName and port. Must be used by servers to establish an accessible endpoint.
connect | aSession.connect( hostName, port ) -> 0
|  | Creates a connection to the given hostName and port. Subsequent `UDPSocket#send` requests that don't override the recipient will use this connection. Multiple `connect` requests may be issued on aSession: the most recent will be used by `send`.
recvfrom | aSession.recvfrom( len [, flags ] ) -> anArray
|  | Receives up to len bytes from aSession. flags is zero or more of the `MSG_` options (listed on page 478). The result is a two-element array containing the received data and information on the sender. See the example on page 475.
send | aSession.send( aString, flags ) -> aFixnum aSession.send( aString, flags, hostName, port ) -> aFixnum
|  | The two-parameter form sends aString on an existing connection. The four-parameter form sends aString to port on hostName.

class UNIXSocket |
Parent: | BasicSocket
Version: | 1.6

### Index:

new open addr path peeraddr recvfrom

Class `UNIXSocket` supports interprocess communications using the Unix domain protocol. Although the underlying protocol supports both datagram and stream connections, the Ruby library provides only a stream-based connection.

    require 'socket'

    $path = "/tmp/sample"

    sThread = Thread.start do        # run server in a thread
      sock = UNIXServer.open($path)
      s1 = sock.accept
      p s1.recvfrom(124)
    end

    client = UNIXSocket.open($path)
    client.send("hello", 0)
    client.close

    sThread.join

produces:

    ["hello", ["AF_UNIX", ""]]

class methods
new | UNIXSocket.new( path ) -> aSession
|  | Opens a new domain socket on path, which must be a pathname.
open | UNIXSocket.open( path ) -> aSession
|  | Synonym for `UNIXSocket.new`.

instance methods
addr | aSession.addr -> anArray
|  | Returns the address family and path of this socket.
path | aSession.path -> aString
|  | Returns the path of this domain socket.
peeraddr | aSession.peeraddr -> anArray
|  | Returns the address family and path of the server end of the connection.
recvfrom | aSession.recvfrom( len [, flags ] ) -> anArray
|  | Receives up to len bytes from aSession. flags is zero or more of the `MSG_` options (listed on page 478). The first element of the returned array is the received data, and the second contains (minimal) information on the sender.

class UNIXServer |
Parent: | UNIXSocket
Version: | 1.6

### Index:

new open accept

Class `UNIXServer` provides a simple Unix domain socket server. See `UNIXSocket` for example code.

class methods
new | UNIXServer.new( path ) -> aSession
|  | Creates a server on the given path. The corresponding file must not exist at the time of the call.
open | UNIXServer.open( path ) -> aSession
|  | Synonym for `UNIXServer.new`.

instance methods
accept | aSession.accept -> aUnixSocket
|  | Waits for a connection on the server socket and returns a new socket object for that connection. See the example for `UNIXSocket` on page 476.

class Socket |
Parent: | BasicSocket
Version: | 1.6

### Index:

for_fd getaddrinfo gethostbyaddr gethostbyname gethostname getnameinfo getservbyname new open pair socketpair accept bind connect listen recvfrom

Class `Socket` provides access to the underlying operating system socket implementation. It can be used to provide more operating system-specific functionality than the protocol-specific socket classes, but at the expense of greater complexity. In particular, the class handles addresses using `struct sockaddr` structures packed into Ruby strings, which can be a joy to manipulate.

constants

Class `Socket` defines constants for use throughout the socket library. Individual constants are available only on architectures that support the related facility.

Types:
  `SOCK_DGRAM`, `SOCK_PACKET`, `SOCK_RAW`, `SOCK_RDM`, `SOCK_SEQPACKET`, `SOCK_STREAM`.

Protocol families:
  `PF_APPLETALK`, `PF_AX25`, `PF_INET6`, `PF_INET`, `PF_IPX`, `PF_UNIX`, `PF_UNSPEC`.

Address families:
  `AF_APPLETALK`, `AF_AX25`, `AF_INET6`, `AF_INET`, `AF_IPX`, `AF_UNIX`, `AF_UNSPEC`.

Lookup-order options:
  `LOOKUP_INET6`, `LOOKUP_INET`, `LOOKUP_UNSPEC`.

Send/receive options:
  `MSG_DONTROUTE`, `MSG_OOB`, `MSG_PEEK`.

Socket-level options:
  `SOL_ATALK`, `SOL_AX25`, `SOL_IPX`, `SOL_IP`, `SOL_SOCKET`, `SOL_TCP`, `SOL_UDP`.

Socket options:
  `SO_BROADCAST`, `SO_DEBUG`, `SO_DONTROUTE`, `SO_ERROR`, `SO_KEEPALIVE`, `SO_LINGER`, `SO_NO_CHECK`, `SO_OOBINLINE`, `SO_PRIORITY`, `SO_RCVBUF`, `SO_REUSEADDR`, `SO_SNDBUF`, `SO_TYPE`.

QOS options:
  `SOPRI_BACKGROUND`, `SOPRI_INTERACTIVE`, `SOPRI_NORMAL`.

Multicast options:
  `IP_ADD_MEMBERSHIP`, `IP_DEFAULT_MULTICAST_LOOP`, `IP_DEFAULT_MULTICAST_TTL`, `IP_MAX_MEMBERSHIPS`, `IP_MULTICAST_IF`, `IP_MULTICAST_LOOP`, `IP_MULTICAST_TTL`.

TCP options:
  `TCP_MAXSEG`, `TCP_NODELAY`.

`getaddrinfo` error codes:
  `EAI_ADDRFAMILY`, `EAI_AGAIN`, `EAI_BADFLAGS`, `EAI_BADHINTS`, `EAI_FAIL`, `EAI_FAMILY`, `EAI_MAX`, `EAI_MEMORY`, `EAI_NODATA`, `EAI_NONAME`, `EAI_PROTOCOL`, `EAI_SERVICE`, `EAI_SOCKTYPE`, `EAI_SYSTEM`.

`ai_flags` values:
  `AI_ALL`, `AI_CANONNAME`, `AI_MASK`, `AI_NUMERICHOST`, `AI_PASSIVE`, `AI_V4MAPPED_CFG`.

class methods
for_fd | Socket.for_fd( anFD ) -> aSession
|  | Wraps an already open file descriptor into a socket object.
getaddrinfo | Socket.getaddrinfo( hostName, port, [ family [ socktype [ protocol [ flags ] ] ] ] ) -> anArray
|  | Returns an array of arrays describing the given host and port (optionally qualified as shown). Each subarray contains the address family, port number, host name, host IP address, protocol family, socket type, and protocol.
    for line in Socket.getaddrinfo('www.microsoft.com', 'http')
      puts line.join(", ")
    end
produces:
    AF_INET, 80, microsoft.net, 207.46.130.149, 2, 1, 6
    AF_INET, 80, microsoft.net, 207.46.131.137, 2, 1, 6
    AF_INET, 80, microsoft.com, 207.46.230.218, 2, 1, 6
    AF_INET, 80, microsoft.com, 207.46.230.219, 2, 1, 6
    AF_INET, 80, microsoft.net, 207.46.130.14, 2, 1, 6
gethostbyaddr | Socket.gethostbyaddr( addr, type=`AF_INET` ) -> anArray
|  | Returns the host name, address family, and `sockaddr` component for the given address.
`a = Socket.gethostbyname("216.87.136.211")`
`res = Socket.gethostbyaddr(a[3], a[2])`
`res.join(', ')` | » | `"pragprog.com, , 2, \330W\210\323"`
gethostbyname | Socket.gethostbyname( hostName ) -> anArray
|  | Returns a four-element array containing the canonical host name, a subarray of host aliases, the address family, and the address portion of the `sockaddr` structure.
`a = Socket.gethostbyname("216.87.136.211")`
`a.join(', ')` | » | `"pragprog.com, , 2, \330W\210\323"`
gethostname | aSession.gethostname -> aString
|  | Returns the name of the current host.
getnameinfo | Socket.getnameinfo( addr [, flags ] ) -> anArray
|  | Looks up the given address, which may be either a string containing a sockaddr or a three- or four-element array. If sockaddr is an array, it should contain the string address family, the port (or nil), and the host name or IP address. If a fourth element is present and not `nil`, it will be used as the host name. Returns a canonical hostname (or address) and port number as an array.
`a = Socket.getnameinfo(["AF_INET", '23', 'www.ruby-lang.org'])`
`a` | » | `["helium.ruby-lang.org", "telnet"]`
getservbyname | Socket.getservbyname( service, proto=`'tcp'` ) -> aFixnum
|  | Returns the port corresponding to the given service and protocol.
`Socket.getservbyname("telnet")` | » | `23`
new | Socket.new( domain, type, protocol ) -> aSession
|  | Creates a socket using the given parameters.
open | Socket.open( domain, type, protocol ) -> aSession
|  | Synonym for `Socket.new`.
pair | Socket.pair( domain, type, protocol ) -> anArray
|  | Returns a pair of connected, anonymous sockets of the given domain, type, and protocol.
socketpair | Socket.socketpair( domain, type, protocol ) -> anArray
|  | Synonym for `Socket.pair`.

instance methods
accept | aSession.accept -> anArray
|  | Accepts an incoming connection returning an array containing a new `Socket` object and a string holding the `struct sockaddr` information about the caller.
bind | aSession.bind( sockaddr ) -> 0
|  | Binds to the given `struct sockaddr`, contained in a string.
connect | aSession.connect( sockaddr ) -> 0
|  | Connects to the given `struct sockaddr`, contained in a string.
listen | aSession.listen( aFixnum ) -> 0
|  | Listens for connections, using the specified aFixnum as the backlog.
recvfrom | aSession.recvfrom( len [, flags ] ) -> anArray
|  | Receives up to len bytes from aSession. flags is zero or more of the `MSG_` options. The first element of the result is the data received. The second element contains protocol-specific information on the sender.

## Higher-Level Access

Ruby provides a set of classes to facilitate writing clients for:

- File Transfer Protocol (FTP)
- HyperText Transfer Protocol (HTTP)
- Post Office Protocol (POP)
- Simple Mail Transfer Protocol (SMTP)
- Telnet

HTTP, POP, and SMTP are layered on top of a helper class, `lib/net/protocol`. Although we don't document the `Protocol` class here, you should probably study it if you are considering writing your own network client.

class Net::FTP |
Parent: | Object
Version: | 1.6

### Index:

new open Server commands close closed? connect debug_mode debug_mode= dir getbinaryfile gettextfile lastresp list login ls mtime passive passive= putbinaryfile puttextfile resume resume= retrbinary retrlines return_code storbinary storlines welcome

    require 'net/ftp'

    ftp = Net::FTP.new('ftp.netlab.co.jp')
    ftp.login
    files = ftp.chdir('pub/lang/ruby/contrib')
    files = ftp.list('n*')
    ftp.getbinaryfile('nif.rb-0.91.gz', 'nif.gz', 1024)
    ftp.close

The `net/ftp` library implements a File Transfer Protocol (FTP) client.

constants

`FTP_PORT` |  | Default port for FTP connections (21).

class methods
new | FTP.new( host=`nil`, user=`nil`, passwd=`nil`, acct=`nil`) -> aSession
|  | Creates and returns a new `FTP` object. If the host parameter is not `nil`, a connection is made to that host. Additionally, if the user parameter is not `nil`, the given user name, password, and (optionally) account are used to log in. See the description of `FTP#login` on page 484.
open | FTP.open( host, user=`nil`, passwd=`nil`, acct=`nil`) -> aSession
|  | A synonym for `FTP.new`, but with a mandatory host parameter.

instance methods
Server commands | aSession.acct( account ) aSession.chdir( dir ) aSession.delete( remoteFile ) aSession.mdtm( remoteFile ) -> aString aSession.mkdir( dir ) aSession.nlst( dir=`nil` ) -> anArray aSession.rename( fromname, toname ) aSession.rmdir( dir ) aSession.pwd -> aString aSession.size( remoteFile ) -> anInteger aSession.status -> aString aSession.system -> aString
|  | Issues the corresponding server command and returns the result.
close | aSession.close
|  | Closes the current connection.
closed? | aSession.closed? -> `true` or `false`
|  | Returns `true` if the current connection is closed.
connect | aSession.connect( host, port=FTP_PORT )
|  | Establishes an FTP connection to host, optionally overriding the default port. If the environment variable `SOCKS_SERVER` is set, sets up the connection through a SOCKS proxy. Raises an exception (typically `Errno::ECONNREFUSED`) if the connection cannot be established.
debug_mode | aSession.debug_mode -> `true` or `false`
|  | Returns the current debug mode.
debug_mode= | aSession.debug_mode = `true` or `false`
|  | If the debug mode is `true`, all traffic to and from the server is written to `$stdout`.
dir | aSession.dir( [pattern]* ) -> anArray aSession.dir( [pattern]* ) {| line | block }
|  | Synonym for `FTP#list`.
getbinaryfile | aSession.getbinaryfile( remotefile, localfile, blocksize, callback=`nil`) aSession.getbinaryfile( remotefile, localfile, blocksize ) {| data | block }
|  | Retrieves remotefile in binary mode, storing the result in localfile. If callback or an associated block is supplied, calls it, passing in the retrieved data in blocksize chunks.
gettextfile | aSession.gettextfile( remotefile, localfile, callback=`nil`) aSession.gettextfile( remotefile, localfile ) {| data | block }
|  | Retrieves remotefile in ASCII (text) mode, storing the result in localfile. If callback or an associated block is supplied, calls it, passing in the retrieved data one line at a time.
lastresp | aSession.lastresp -> aString
|  | Returns the host's last response.
list | aSession.list( [pattern]* ) -> anArray aSession.list( [pattern]* ) {| line | block }
|  | Fetches a directory listing of files matching the given pattern(s). If a block is associated with the call, invokes it with each line of the result. Otherwise, returns the result as an array of strings.
login | aSession.login( user="anonymous", passwd=`nil`, acct=`nil` ) -> aString
|  | Logs into the remote host. aSession must have been previously connected. If user is the string ``anonymous'' and the password is `nil`, a password of user@host is synthesized. If the acct parameter is not `nil`, an FTP `ACCT` command is sent following the successful login. Raises an exception on error (typically `Net::FTPPermError`).
ls | aSession.ls( [pattern]* ) -> anArray aSession.ls( [pattern]* ) {| line | block }
|  | Synonym for `FTP#list`.
mtime | aSession.mtime( remoteFile, local=`false` ) -> aTime
|  | Returns the last-modified time of remoteFile, interpreting the server's response as a GMT time if local is `false`, or as a local time otherwise.
passive | aSession.passive -> `true` or `false`
|  | Returns the state of the `passive` flag.
passive= | aSession.passive = `true` or `false`
|  | Puts the connection into passive mode if `true`.
putbinaryfile | aSession.putbinaryfile( localfile, remotefile, blocksize, callback=`nil`) aSession.putbinaryfile( localfile, remotefile, blocksize ) {| data | block }
|  | Transfers localfile to the server in binary mode, storing the result in remotefile. If callback or an associated block is supplied, calls it, passing in the transmitted data in blocksize chunks.
puttextfile | aSession.puttextfile( localfile, remotefile, callback=`nil`) aSession.puttextfile( localfile, remotefile, blocksize ) {| data | block }
|  | Transfers localfile to the server in ASCII (text) mode, storing the result in remotefile. If callback or an associated block is supplied, calls it, passing in the transmitted data one line at a time.
resume | aSession.resume -> `true` or `false`
|  | Returns the status of the resume flag (see `FTP#resume=`). Default is `false`.
resume= | aSession.resume=aBoolean
|  | Sets the status of the resume flag. When resume is `true`, partially received files will resume where they left off, instead of starting from the beginning again. This is done by sending a `REST` command (`REST`art incomplete transfer) to the server.
retrbinary | aSession.retrbinary( cmd, blocksize ) {| data | block }
|  | Puts the connection into binary (image) mode, issues the given command, and fetches the data returned, passing it to the associated block in chunks of blocksize characters. Note that cmd is a server command (such as ``RETR myfile'').
retrlines | aSession.retrlines(cmd) {| line | block }
|  | Puts the connection into ASCII (text) mode, issues the given command, and passes the resulting data, one line at a time, to the associated block. If no block is given, prints the lines. Note that cmd is a server command (such as ``RETR myfile'').
return_code | aSession.return_code -> aFixnum
|  | Returns the return code from the last operation.
storbinary | aSession.storbinary( cmd, fileName, blocksize, callback=`nil`) aSession.storbinary( cmd, fileName, blocksize ) {| data | block }
|  | Puts the connection into binary (image) mode, issues the given server-side command (such as ``STOR myfile''), and sends the contents of the file named fileName to the server. If the optional block is given, or if the callBack parameter is a `Proc`, also passes it the data, in chunks of blocksize characters.
storlines | aSession.storlines( cmd, fileName, callback=`nil`) aSession.storlines( cmd, fileName ) {| data | block }
|  | Puts the connection into ASCII (text) mode, issues the given server-side command (such as ``STOR myfile''), and sends the contents of the file named fileName to the server, one line at a time. If the optional block is given, or if the callBack parameter is a `Proc`, also passes it the lines.
welcome | aSession.welcome -> aString
|  | Returns the host's welcome message.

class Net::HTTP |
Parent: | Net::Protocol
Version: | 1.6

### Index:

new port start get head post start

    require 'net/http'

    h = Net::HTTP.new('www.pragmaticprogrammer.com', 80)
    resp, data = h.get('/index.html', nil )
    puts "Code = #{resp.code}"
    puts "Message = #{resp.message}"
    resp.each {|key, val| printf "%-14s = %-40.40s\n", key, val }
    p data[0..55]

produces:

    Code = 200
    Message = OK
    content-length = 8061
    date           = Mon, 26 Nov 2001 05:46:25 GMT
    connection     = close
    content-type   = text/html
    last-modified  = Tue, 13 Nov 2001 03:12:30 GMT
    etag           = "804d98-1f7d-3bf08f9e"
    server         = Rapidsite/Apa-1.3.14 (Unix) FrontPage/4.
    accept-ranges  = bytes
    "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional"

The `net/http` library provides a simple client to fetch headers and Web page contents using the HTTP protocol.

The `get`, `post`, and `head` requests raise exceptions on any error, including some HTTP status responses that would normally be considered recoverable. There are two ways of handling these.

1. Each method has a corresponding version `get2`, `post2`, or `head2` that does not raise an exception. These versions are documented in the source.
2. Recoverable errors raise a `Net::ProtoRetriableError` exception. This exception contains a `data` attribute containing the response returned by the server.

The code below illustrates the handling of an HTTP status 301, a redirect. It uses Tomoyuki Kosimizu's URI package, available in the RAA.

    h = Net::HTTP.new(ARGV[0] || 'www.ruby-lang.org', 80)
    url = ARGV[1] || '/'

    begin
      resp, data = h.get(url, nil) { |a| }
    rescue Net::ProtoRetriableError => detail
      head = detail.data

      if head.code == "301"
        uri = URI.create(head['location'])

        host = uri['host']
        url  = uri['path']
        port = uri['port']

        h.finish
        h = Net::HTTP.new(host, port)

        retry
      end
    end

class methods
new | Net::HTTP.new( host='localhost', port=80, proxy=`nil`, proxy_port=`nil` ) -> aSession
|  | Creates and returns a new `HTTP` object. No connection is made until `HTTP#start` is called.
port | Net::HTTP.port -> aFixnum
|  | Returns the default HTTP port (80).
start | Net::HTTP.start( host=`nil`, port=80 ) Net::HTTP.start( host=`nil`, port=80 ) {| aSession | block }
|  | Equivalent to `Net::HTTP.new(host, port).start`.

instance methods
get | aSession.get( path, headers=`nil`, dest="" ) -> anArray aSession.get( path, headers=`nil`) {| result | block } -> anArray
|  | Retrieves headers and content from the specified path on the host specified when aSession was created. If specified, the headers parameter is a `Hash` containing additional header names and values to be sent with the request. The method returns a two-element array. The first element is an `HTTPResponse` object (documented in the next section). The second element is the page's content. The page's content is also passed to the `<<` method of the dest parameter, or to the block if specified. This result is built network block by network block, not line by line. An exception is raised if an error is encountered. Multiple `get` calls may be made on aSession. Unless `Protocol#finish` is explicitly called, the connection will use the HTTP/1.1 keep-alive protocol, and will not close between requests.
head | aSession.head( path, headers=`nil` ) -> aHash
|  | Retrieves headers from the specified path on the host specified when aSession was created. If specified, the headers parameter is a hash containing additional header names and values to be sent with the request. The method returns a hash of received headers. An exception is raised if an error is encountered. Multiple `head` calls may be made on aSession.
post | aSession.post( path, data, headers=`nil`, dest="" ) -> anArray aSession.post( path, data, headers=`nil` ) {| result | block } -> anArray
|  | Sends data to path using an HTTP POST request. headers is a hash containing additional headers. Assigns the result to data or to the block, as for `Net_HTTP#get`. Returns a two-element array containing an HTTPResponse object and the reply body.
start | aSession.start aSession.start {| aSession | block }
|  | Establishes a connection to the host associated with aSession. (`start` is actually a method in `Net::Protocol`, but its use is required in HTTP objects.) In the block form, closes the session at the end of the block.

class Net::HTTPResponse |
Parent: |
Version: | 1.6

### Index:

[ ] [ ]= code each key? message

Represents an HTTP response to a GET or POST request.

instance methods
[ ] | aSession[ aKey ] -> aString
|  | Returns the header corresponding to the case-insensitive key. For example, a key of ``Content-type'' might return ``text/html''.
[ ]= | aSession[ aKey ] = aString
|  | Sets the header corresponding to the case-insensitive key.
code | aSession.code -> aString
|  | Returns the result code from the request (for example, ``404'').
each | aSession.each {| key, val | block }
|  | Iterates over all the header key-value pairs.
key? | aSession.key?( aKey ) -> `true` or `false`
|  | Returns `true` only if a header with the given key exists.
message | aSession.message -> aString
|  | Returns the result message from the request (for example, ``Not found'').

class Net::POP |
Parent: | Net::Protocol
Version: | 1.6

### Index:

new each finish mails start

    require 'net/pop'
    pop = Net::POP3.new('server.ruby-stuff.com')
    pop.start('user', 'secret') do |pop|
      msg = pop.mails[0]

      # Print the 'From:' header line
      puts msg.header.split("\r\n").grep(/^From: /)

      # Put message to $stdout (by calling <<)
      puts "\nFull message:\n"
      msg.all($stdout)
    end

produces:

    From: Dave Thomas <dave@pragmaticprogrammer.com>

    Full message:
    Return-Path: <dave@pragmaticprogrammer.com>
    Received: (from dave@pragmaticprogrammer.com)
    	by pragmaticprogrammer.com (8.8.7/8.8.7) id XAA10537;
    	Sun, 21 May 2000 23:45:58 -0500
    Date: Sun, 21 May 2000 23:45:58 -0500
    From: Dave Thomas <dave@pragmaticprogrammer.com>
    Message-Id: <200005220445.XAA10537@pragmaticprogrammer.com>
    To: user@ruby-stuff.com
    Subject: New Ruby Version
    Status: RO

    Just to let you know there's a new Ruby version out.

The `net/pop` library provides a simple client to fetch and delete mail on a Post Office Protocol (POP) server.

The class `Net::POP3` is used to access a POP server, returning a list of `Net::POPMail` objects, one per message stored on the server. These `POPMail` objects are then used to fetch and/or delete individual messages. The library also provides an alternative to the `POP3` class that performs `APOP` authentication.

class methods
new | HTTP.new( host='localhost', port=110 ) -> aSession
|  | Creates and returns a new `POP3` object. No connection is made until `POP3#start` is called.

instance methods
each | aSession.each {| popmail | block }
|  | Calls the associated block once for each e-mail stored on the server, passing in the corresponding `POPMail` object.
finish | aSession.finish -> `true` or `false`
|  | Closes the pop connection. Some servers require that a connection is closed before they honor actions such as deleting mail. Returns `false` if the connection was never used.
mails | aSession.mails -> anArray
|  | Returns an array of `POPMail` objects, where each object corresponds to an e-mail message stored on the server.
start | aSession.start( user, password ) aSession.start( user, password ) {| pop | block }
|  | Establishes a connection to the pop server, using the supplied username and password. Fetches a list of mail held on the server, which may be accessed using the `POP3#mails` and `POP3#each` methods. In block form, passes aSession to the block, and closes the connection using `finish` when the block terminates.

class Net::APOP |
Parent: | Net::POP3
Version: | 1.6

### Index:

start

instance methods
start | aSession.start( user, password )
|  | Establishes a connection to the APOP server.

class Net::POPMail |
Parent: | Object
Version: | 1.6

### Index:

all delete delete! header size top uidl

instance methods
all | aSession.all -> aString aSession.all( dest ) aSession.all {| aString | block }
|  | Fetches the corresponding e-mail from the server. With no argument or associated block, returns the e-mail as a string. With an argument but no block, appends the e-mail to dest by invoking dest `<<` for each line in the e-mail. With an associated block, invokes the block once for each line in the e-mail.
delete | aSession.delete
|  | Deletes the e-mail from the server.
delete! | aSession.delete!
|  | Synonym for `POPMail#delete`.
header | aSession.header -> aString
|  | Returns the header lines for the corresponding e-mail message.
size | aSession.size -> aFixnum
|  | Returns the size in bytes of the corresponding e-mail.
top | aSession.top( lines ) -> aString
|  | Returns the header lines, plus lines message lines for the corresponding e-mail message.
uidl | aSession.uidl -> aString
|  | Returns the server-specific unique identifier for the corresponding e-mail.

class Net::SMTP |
Parent: | Net::Protocol
Version: | 1.6

### Index:

new start ready sendmail start

    require 'net/smtp'

    # --- Send using class methods
    msg = [ "Subject: Test\n", "\n", "Now is the time\n" ]
    Net::SMTP.start do |smtp|
      smtp.sendmail( msg,  'dave@localhost', ['dave'] )
    end

    # --- Send using SMTP object and an adaptor
    smtp = Net::SMTP.new
    smtp.start('pragprog.com')
    smtp.ready('dave@localhost', 'dave') do |a|
      a.write "Subject: Test1\r\n"
      a.write "\r\n"
      a.write "And so is this"
    end

The `net/smtp` library provides a simple client to send electronic mail using the Simple Mail Transfer Protocol (SMTP).

class methods
new | Net::SMTP.new( server='localhost', port=25 ) -> aSession
|  | Returns a new `SMTP` object connected to the given server and port.
start | Net::SMTP.start( server='localhost', port=25, domain=ENV['HOSTNAME'], acct=`nil`, passwd=`nil`, authtype=:cram_md5 ) -> aSession Net::SMTP.start( server='localhost', port=25, domain=ENV['HOSTNAME'], acct=`nil`, passwd=`nil`, authtype=:cram_md5 ) {| smtp | block }
|  | Equivalent to `Net::SMTP.new(server, port).start(...)`. For an explanation of the remainder of the parameters, see the instance method `Net_SMTP#start`. Creates a new `SMTP` object. The domain parameter will be used in the initial `HELO` or `EHLO` transaction with the SMTP server. In the block form, the smtp object is passed into the block. When the block terminates, the session is closed.

instance methods
ready | aSession.ready( from, to ) {| anAdaptor | block }
|  | Equivalent to `sendmail(from, to) { ...}`. Sends header and body lines to the sendmail server. The from parameter is used as the sender's name in the `MAIL FROM:` command, and the to is either a string or an array of strings containing the recipients for the `RCPT TO:` command. The block is passed an adaptor object. Lines are sent to the server by calling the adaptor's `write` method. The terminating '.' and `QUIT` are sent automatically.
sendmail | aSession.sendmail( src, from, to )
|  | Sends header and body lines to the sendmail server. The from parameter is used as the sender's name in the `MAIL FROM:` command, and to is either a string or an array of strings containing the recipients for the `RCPT TO:` command. Lines to be sent are fetched by invoking src `.each`. The terminating '.' and `QUIT` are sent automatically.
start | aSession.start( domain=ENV['HOSTNAME'], acct=`nil`, passwd=`nil`, authtype=:cram_md5 ) -> `true` or `false` aSession.start( domain=ENV['HOSTNAME'], acct=`nil`, passwd=`nil`, authtype=:cram_md5 ) {| smtp | block } -> `true` or `false`
|  | Starts an SMTP session by connecting to the given domain (host). If acct and passwd are given, authentication will be attempted using the given authentication type (`:plain` or `:cram_md5`). If a block is supplied, it will be invoked with aSession as a parameter. The connection will be closed when the block terminates.

class Net::Telnet |
Parent: | [Socket]
Version: | 1.6

### Index:

new binmode binmode= cmd login print telnetmode telnetmode= waitfor write

Connect to a `localhost`, run the ``date'' command, and disconnect.

`require 'net/telnet'`
``
`tn = Net::Telnet.new({})`
`tn.login "guest", "secret"`
`tn.cmd "date"` | » | `"date\r\nSun Nov 25 23:46:32 CST 2001\n\r> "`

Monitor output as it occurs. We associate a block with each of the library calls; this block is called whenever data becomes available from the host.

    require 'net/telnet'

    tn = Net::Telnet.new({})     { |str| print str }
    tn.login("guest", "secret")  { |str| print str }
    tn.cmd("date")  { |str| print str }

produces:

    Trying localhost...
    Connected to localhost.
    Welcome to SuSE Linux 7.1 (i386) - Kernel 2.4.0-64GB-SMP (7).

    zip login: guest
    Password:
    Last login: Sun Nov 25 23:46:32 from localhost
    /etc/zshrc: setopt: no such option: histexpiredupsfirst [31]

    > date
    Sun Nov 25 23:46:32 CST 2001

    >

Get the time from an NTP server.

    require 'net/telnet'
    tn = Net::Telnet.new('Host'       => 'time.nonexistent.org',
                         'Port'       => 'time',
                         'Timeout'    => 60,
                         'Telnetmode' => false)
    atomicTime = tn.recv(4).unpack('N')[0]
    puts "Atomic time: " + Time.at(atomicTime - 2208988800).to_s
    puts "Local time:  " + Time.now.to_s

produces:

    Atomic time: Sun Nov 25 23:46:24 CST 2001
    Local time:  Sun Nov 25 23:46:32 CST 2001

The `net/telnet` library provides a complete implementation of a telnet client and includes features that make it a convenient mechanism for interacting with non-telnet services.

Although the class description that follows indicates that `Net::Telnet` is a subclass of class `Socket`, this is a lie. In reality, the class delegates to `Socket`. The net effect is the same: the methods of `Socket` and its parent, class `IO`, are available through `Net::Telnet` objects.

The methods `new`, `cmd`, `login`, and `waitfor` take an optional block. If present, the block is passed output from the server as it is received by the routine. This can be used to provide realtime output, rather than waiting for (for example) a login to complete before displaying the server's response.

class methods
new | Net::Telnet.new( options ) -> aSession Net::Telnet.new( options ) {| str | block } -> aSession
|  | Connects to a server. options is a `Hash` with zero or more of the following:
Option | Default | Meaning
`Binmode` | `false` | If true, no end-of-line processing will be performed.
`Host` | localhost | Name or address of server's host.
`Port` | 23 | Name or number of service to call.
`Prompt` | `/[$%#>]/` | Pattern that matches the host's prompt.
`Telnetmode` | `true` | If `false`, ignore the majority of telnet embedded escape sequences. Used when talking with a non-telnet server.
`Timeout` | 10 | Time in seconds to wait for a server response (both during connection and during regular data transmission).
`Waittime` | 0 | Time to wait for prompt to appear in received data stream.

instance methods
binmode | aSession.binmode -> `true` or `false`
|  | Returns the current value of the `Binmode` flag.
binmode= | aSession.binmode = `true` or `false`
|  | Sets the `Binmode` flag, returning the new value.
cmd | aSession.cmd( options ) -> aString aSession.cmd( options ) {| str | block } -> aString
|  | Sends a string to the server and waits (using a timeout) for a string that matches a pattern to be returned by the server. If the parameter is not a `Hash`, it is sent as a string to the server, and the pattern to match and the timeout are the `Prompt` and `Timeout` options given when aSession was created. If options is a `Hash`, then options['String'] is sent to the server. options['Match'] may be used to override the class `Prompt` parameter, and options['Timeout'] the timeout. The method returns the complete server response.
login | aSession.login( options, password=nil ) -> aString aSession.login( options, password=nil ) {| str | block } -> aString
|  | If options is a `Hash`, a username is taken from options['Name'] and a password from options['Password']; otherwise, options is assumed to be the username, and password the password. The method waits for the server to send the string matching the pattern `/login[:]*\z/` and sends the username. If a password is given, it then waits for the server to send `/Password[:]*\z/` and sends the password. The method returns the full server response.
print | aSession.print( aString )
|  | Sends aString to the server, honoring `Telnetmode`, `Binarymode`, and any additional modes negotiated with the server.
telnetmode | aSession.telnetmode -> `true` or `false`
|  | Returns the current value of the `Telnetmode` flag.
telnetmode= | aSession.telnetmode= `true` or `false`
|  | Sets the `Telnetmode` flag, returning the new value.
waitfor | aSession.waitfor( options ) -> aString aSession.waitfor( options ) {| str | block } -> aString
|  | Waits for the server to respond with a string that matches a string or pattern. If options is not a `Hash`, it is compared against the cumulative server output as that output is received using options. `===`. It is likely that you will want to use a regular expression in this case. If options is a `Hash`, then options['Match'], options['Prompt'], or options['String'] provides the match. In the latter case, the string will be converted to a regular expression before being used. options may also include the keys ``Timeout'' and ``Waittime'' to override the class options of the same names.
write | aSession.write( aString )
|  | Writes aString to the server with no translation.

## CGI Development

class CGI |
Parent: | Object
Version: | 1.6

### Index:

escape escapeElement escapeHTML new parse pretty rfc1123_date unescape unescapeElement unescapeHTML [ ] cookies has_key? header keys out params

    require "cgi"
    cgi = CGI.new("html3")  # add HTML generation methods
    cgi.out {
      CGI.pretty (
        cgi.html {
          cgi.head { cgi.title{"TITLE"} } +
          cgi.body {
            cgi.form {
              cgi.textarea("get_text") +
              cgi.br +
              cgi.submit
            } +
            cgi.h1 { "This is big!" } +
            cgi.center { "Jazz Greats of the 20" +
              cgi.small {"th"} + " century" + cgi.hr
            } + cgi.p + cgi.table ('BORDER' => '5') {
              cgi.tr { cgi.td {"Artist"} + cgi.td {"Album"} } +
              cgi.tr { cgi.td {"Davis, Miles"} +
              cgi.td {"Kind of Blue"} }
            }
          }
        }
      ) # CGI.pretty is a method call, not a block
    }

(The output of this script is shown in Figure 26.2 on page 499.)

The `CGI` class provides support for programs used as a Web server CGI (Common Gateway Interface) script. It contains several methods for accessing fields in a CGI form, manipulating ``cookies'' and the environment, and outputting formatted HTML.

Since environment variables contain a lot of useful information for a CGI script, `CGI` makes accessing them very easy---environment variables are accessible as attributes of `CGI` objects. For instance, `cgi.auth_type` returns the value of `ENV["AUTH_TYPE"]`. To create the method name, the environment variable name is translated to all lowercase, and the ```HTTP_`'' prefix is stripped off. Thus, `HTTP_USER_AGENT` would be available as the method `user_agent`.

Cookies are represented using a separate object of class `CGI::Cookie`, containing the following accessors:

Accessor | Description
`name` | Name of this cookie
`value` | Array of values
`path` | Path (optional)
`domain` | Domain (optional)
`expires` | Time of expiry, defaults to `Time.now` (optional)
`secure` | `true` for a secure cookie

Figure not available...

You create a cookie object using `CGI_Cookie.new`, which takes as arguments the accessors listed above, or `CGI_Cookie.parse`, which takes an encoded string and returns a cookie object.

class methods
escape | CGI.escape( aString ) -> aNewString
|  | Returns a URL-encoded string made from the given argument, where unsafe characters (not alphanumeric, ``_'', ``-'', or ``.'') are encoded using ``%xx'' escapes.
escapeElement | CGI.escapeElement( aString [, elements ]* ) -> aNewString
|  | Returns a string made from the given argument with certain HTML-special characters escaped. The HTML elements given in elements will be escaped; other HTML elements will not be affected.
    print CGI::escapeElement('<BR><A HREF="url"></A><P>', "A", "IMG")
produces:
    <BR>&lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt;<P>
escapeHTML | CGI.escapeHTML( aString ) -> aNewString
|  | Returns a string made from the given argument with HTML-special characters (such as ```&`'',```"`'',```<`'',```>`'') quoted using ```&amp;`'', ```&quot;`'', ```&lt;`'', ```&gt;`'', and so on.
new | CGI.new( [ aString ]* ) -> aSession
|  | Returns a new `CGI` object. If HTML output is required, the desired standards level must be given in aString (otherwise, no output routines will be created). The level may be one of:
String | Standards Level | String | Standards Level
``html3'' | HTML 3.2 | ``html4'' | HTML 4.0 Strict
``html4Tr'' | HTML 4.0 Transitional | ``html4Fr'' | HTML 4.0 Frameset
parse | CGI.parse( aString ) -> aHash
|  | Parses a query string and returns a hash of its key-value pairs.
pretty | CGI.pretty( anHTMLString, aLeaderString=" " ) -> aSession
|  | Formats the given anHTMLString in a nice, readable format, optionally prefixing each line with aLeaderString.
rfc1123_date | CGI.rfc1123_date( aTime ) -> aString
|  | Returns a string representing the given time according to RFC 1123 (for instance, `Mon, 1 Jan 2001 00:00:00 GMT`).
unescape | CGI.unescape( aString ) -> aNewString
|  | Returns a string containing ``unsafe'' characters made from the given URL-encoded argument, where unsafe characters were encoded using ``%'' escapes.
unescapeElement | CGI.unescapeElement( aString [, elements ]* ) -> aNewString
|  | Returns a string with the selected escaped HTML elements expanded to the actual characters.
unescapeHTML | CGI.unescapeHTML( aString ) -> aNewString
|  | Returns a string made from the given argument with HTML-special quoted characters expanded to the actual characters.

instance methods
[ ] | aSession[ [ aString ]+ ] -> anArray
|  | Returns the values of the given field names from the CGI form in an `Array`. See the note on multipart forms on page 503.
cookies | aSession.cookies -> aHash
|  | Returns a new `Hash` object containing key-value pairs of cookie keys and values.
has_key? | aSession.has_key( aString ) -> `true` or `false`
|  | Returns `true` if the form contains a field named aString.
header | aSession.header( aContentType="text/html" ) -> aString aSession.header( aHash ) -> aString
|  | Returns a string containing the given headers (in the `MOD_RUBY` environment, the resulting header is sent immediately instead). If a hash is given as an argument, then the key-value pairs will be used to generate headers.
keys | aSession.keys -> anArray
|  | Returns an array of all existing field names for the form.
out | aSession.out( aContentType="text/html" ) { block } -> `nil` aSession.out( aHash ) { block } -> `nil`
|  | Generates HTML output using the results of the block as the content. Headers are generated as with `CGI#header`. See the example at the start of this section.
params | aSession.params -> aHash
|  | Returns a new `Hash` object containing key-value pairs of field names and values from the form.

### HTML Output Methods

In addition, `CGI` supports the following HTML output methods. Each of these methods is named after the corresponding HTML feature (or close to it). Those tags that require content (such as `blockquote`) take an optional block; the block should return a `String` that will be used as the content for the feature. These methods may take arguments as indicated, or as a hash with the given names as keys.

\

`a`( url )
`a`( `HREF` => )

`base`( url )
`base`( `HREF` => )

`blockquote`( cite="" ) { aString }
`blockquote`( `CITE` => ) { aString }

`caption`( align=nil ) { aString }
`caption`( `ALIGN` => ) { aString }

`checkbox`( name=`nil`, value=`nil`, checked=`nil` )
`checkbox`( `NAME`, `VALUE`, `CHECKED` => )

`checkbox_group`( name=`nil`, [ items ]+ )
`checkbox_group`( `NAME`, `VALUES` => )

> Items may be individual `String` names, or any of: an array of [ name, checked ], an array of [ value, name ], or an array of [ value, name, checked ]. The value for the hash key VALUES should be an array of these items.

`file_field`( name="", size=20, maxlength=`nil` )
`file_field`( `NAME`, `SIZE`, `MAXLENGTH` => )

`form`( method="post", action=`nil`, enctype="application/x-www-form-urlencoded" ) { aStr }
`form`( `METHOD`, `ACTION`, `ENCTYPE` => ) { aStr }

`hidden`( name="", value=`nil` )
`hidden`( `NAME`, `VALUE` => )

`html`( ) { aString }
`html`( `PRETTY`, `DOCTYPE` => ) { aString }

`img_button`( src="", name=`nil`, alt=`nil` )
`img_button`( `SRC`, `NAME`, `ALT` => )

`img`( src="", alt="", width=`nil`, height=`nil` )
`img`( `SRC`, `ALT`, `WIDTH`, `HEIGHT` => )

`multipart_form`( action=`nil`, enctype="multipart/form-data" ) { aString }
`multipart_form`( `METHOD`, `ACTION`, `ENCTYPE` => ) { aString }

`password_field`( name="", value=`nil`, size=40, maxlength=`nil` )
`password_field`( `NAME`, `VALUE`, `SIZE`, `MAXLENGTH` => )

`popup_menu`( name="", items )
`popup_menu`( `NAME`, `SIZE`, `MULTIPLE`, `VALUES` (array of items) => )

> Items may be individual `String` names, or any of: an array of [ name, selected ], an array of [ value, name ], or an array of [ value, name, selected ]. The value for the hash key VALUES should be an array of these items.

`radio_button`( name="", value=`nil`, checked=`nil` )
`radio_button`( `NAME`, `VALUE`, `CHECKED` => )

`radio_group`( name="", items )
`radio_group`( `NAME`, `VALUES` (array of items) => )

> Items may be individual `String` names, or any of: an array of [ name, selected ], an array of [ value, name ], or an array of [ value, name, selected ]. The value for the hash key VALUES should be an array of these items.

`reset`( value=`nil`, name=`nil` )
`reset`( `VALUE`, `NAME` => )

`scrolling_list`( alias for popup_menu )
`scrolling_list`( => )

`submit`( value=`nil`, name=`nil` )
`submit`( `VALUE`, `NAME` => )

`text_field`( name="", value=`nil`, size=40, maxlength=`nil` )
`text_field`( `NAME`, `VALUE`, `SIZE`, MAXLENGTH => )

`textarea`( name="", cols=70, rows=10 )
`textarea`( `NAME`, `COLS`, `ROWS` => )

\

In addition, all HTML tags are supported as methods, including `title`, `head`, `body`, `br`, `pre`, and so on. The block given to the method must return a `String`, which will be used as the content for that tag type. Not all tags require content: `<P>`, for example, does not. The available tags vary according to the supported HTML level---Table 26.1 on page 503 lists the complete set. For these methods, you can pass in a hash with attributes for the given tag. For instance, you might pass in `'BORDER'=>'5'` to the `table` method to set the border width of the table.

HTML tags available as methods
{HTML 3}
a address applet area b base basefont big blockquote body br caption center cite code dd dfn dir div dl dt em font form h1 h2 h3 h4 h5 h6 head hr html i img input isindex kbd li link listing map menu meta ol option p param plaintext pre samp script select small strike strong style sub sup table td textarea th title tr tt u ul var xmp
{HTML 4}
a abbr acronym address area b base bdo big blockquote body br button caption cite code col colgroup dd del dfn div dl dt em fieldset form h1 h2 h3 h4 h5 h6 head hr html i img input ins kbd label legend li link map meta noscript object ol optgroup option p param pre q samp script select small span strong style sub sup table tbody td textarea tfoot th thead title tr tt ul var
{HTML 4 Transitional}
a abbr acronym address applet area b base basefont bdo big blockquote body br button caption center cite code col colgroup dd del dfn dir div dl dt em fieldset font form h1 h2 h3 h4 h5 h6 head hr html i iframe img input ins isindex kbd label legend li link map menu meta noframes noscript object ol optgroup option p param pre q s samp script select small span strike strong style sub sup table tbody td textarea tfoot th thead title tr tt u ul var
frame frameset

### Multipart Form Values

When dealing with a multipart form, the array returned by `CGI#[]` is composed of objects of class `Tempfile`, with the following dynamically added methods:

Method | Description
`read` | Body
`local_path` | Path to local file containing the content
`original_filename` | Original filename of the content
`content_type` | Content type

class CGI::Session |
Parent: | Object
Version: | 1.6

### Index:

new [ ] [ ]= delete update

A `CGI::Session` maintains a persistent state for web users in a CGI environment. Sessions may be memory-resident or may be stored on disk. See the discussion on page 146 for details.

class methods
new | CGI::Session.new( aCgi, [ aHash ]* ) -> aSession
|  | Returns a new session object for the `CGI` query. Options that may be given in aHash include:
Option | Description
`session_key` | Name of CGI key for session identification.
`session_id` | Value of session id.
`new_session` | If `true`, create a new session id for this session. If `false`, use an existing session identified by `session_id`. If omitted, use an existing session if available, otherwise create a new one.
`database_manager` | Class to use to save sessions; may be `CGI::Session::FileStore` or `CGI::Session::MemoryStore` (or user defined if you're brave). Default is `FileStore`.
`tmpdir` | For `FileStore,` directory for session files.
`prefix` | For `FileStore,` prefix of session filenames.

instance methods
[ ] | aSession[ aKey ] -> aValue
|  | Returns the value for the given key.
[ ]= | aSession[ aKey ] = aValue -> aValue
|  | Sets the value for the given key.
delete | aSession.delete
|  | Calls the `delete` method of the underlying database manager. For `FileStore`, deletes the physical file containing the session. For `MemoryStore`, removes the session from memory.
update | aSession.update
|  | Calls the `update` method of the underlying database manager. For `FileStore`, writes the session data out to disk. Has no effect with `MemoryStore`.

Previous < | Contents ^ | Next >

Extracted from the book "Programming Ruby - The Pragmatic Programmer's Guide"
Copyright © 2000 Addison Wesley Longman, Inc. Released under the terms of the Open Publication License V1.0.
This reference is available for download.