more net library docs

svn: r9284
This commit is contained in:
Matthew Flatt 2008-04-13 15:44:10 +00:00
parent 320068fc89
commit 2b5d800190
7 changed files with 504 additions and 7 deletions

View File

@ -0,0 +1,76 @@
#lang scribble/doc
@(require "common.ss"
(for-label net/dns
net/dns-unit
net/dns-sig))
@title{DNS: Domain Name Service Queries}
@defmodule[net/dns]{The @schememodname[net/dns] module provides
utilities for looking up hostnames.
Thanks to Eduardo Cavazos and Jason Crowe for repairs and
improvements.}
@; ----------------------------------------
@section[#:tag "dns-proc"]{Functions}
@defproc[(dns-get-address [nameserver string?]
[address string?])
string?]{
Consults the specified nameserver (normally a numerical address like
@scheme["128.42.1.30"]) to obtain a numerical address for the given
Internet address.
The query record sent to the DNS server includes the "recursive" bit,
but @scheme[dns-get-address] also implements a recursive search itself
in case the server does not provide this optional feature.}
@defproc[(dns-get-name [nameserver string?]
[address string?])
string?]{
Consults the specified nameserver (normally a numerical address like
@scheme["128.42.1.30"]) to obtain a name for the given numerical
address.}
@defproc[(dns-get-mail-exchanger [nameserver string?]
[address string?])
string?]{
Consults the specified nameserver to obtain the address for a mail
exchanger the given mail host address. For example, the mail exchanger
for @scheme["ollie.cs.rice.edu"] might be @scheme["cs.rice.edu"].}
@defproc[(dns-find-nameserver) (or/c string? false/c)]{
Attempts to find the address of a nameserver on the present system.
Under Unix, this procedure parses @filepath{/etc/resolv.conf} to
extract the first nameserver address. Under Windows, it runs
@exec{nslookup.exe}.}
@; ----------------------------------------
@section{DNS Unit}
@defmodule[net/dns-unit]
@defthing[dns@ unit?]{
Imports nothing, exports @scheme[dns^].}
@; ----------------------------------------
@section{DNS Signature}
@defmodule[net/dns-sig]
@defsignature[dns^ ()]{}
Includes everything exported by the @schememodname[net/dns] module.

View File

@ -0,0 +1,239 @@
#lang scribble/doc
@(require "common.ss"
scribble/eval
scribble/struct
(for-label net/head
net/head-unit
net/head-sig))
@(define head-eval (make-base-eval))
@interaction-eval[#:eval head-eval (require net/head)]
@title{headers: Parsing and Constructing}
@defmodule[net/head]{The @schememodname[net/head] module provides
utilities for parsing and constructing RFC 822 headers
@cite["RFC822"], which are used in protocols such as HTTP, SMTP, and
NNTP.}
A @deftech{header} is represented as a string or byte string
containing CRLF-delimited lines. Each field within the header spans
one or more lines. In addition, the header ends with two CRLFs
(because the first one terminates the last field, and the second
terminates the header).
@; ----------------------------------------
@section{Functions}
@defthing[empty-header string?]{
The string @scheme["\r\n\r\n"], which corresponds to the empty header.
This value is useful for building up headers with
@scheme[insert-field] and @scheme[append-headers].}
@defproc[(validate-header [candidate (or string? bytes?)]) void?]{
Checks that @scheme[candidate] matches RFC 822. If it does not, an
exception is raised.}
@defproc[(extract-field [field (or/c string? bytes?)] [header (or/c string? bytes?)])
(or/c string? bytes? false/c)]{
Returns the header content for the specified field, or @scheme[#f] if
the field is not in the header. The @scheme[field] string should not
end with @scheme[":"], and it is used case-insensitively. The returned
string will not contain the field name, color separator, or CRLF
terminator for the field; however, if the field spans multiple lines,
the CRLFs separating the lines will be intact.
The @scheme[field] and @scheme[header] arguments must be both strings
or both byte strings, and the result (if not @scheme[#f]) is of the
same type.
@examples[
#:eval head-eval
(extract-field "TO" (insert-field "to" "me@localhost"
empty-header))
]}
@defproc[(extract-all-fields [header (or/c string? bytes?)])
(listof (cons/c (or/c string? bytes?)
(or/c string? bytes?)))]{
Returns an association-list version of the header; the case of the
field names is preserved, as well as the order and duplicate uses of a
field name.
The result provides strings if @scheme[header] is a string, byte
strings if @scheme[header] is a byte string.}
@defproc[(remove-field [field (or/c string? bytes?)]
[header (or/c string? bytes?)])
(or/c string? bytes?)]{
Creates a new header by removing the specified field from
@scheme[header] (or the first instance of the field, if it occurs
multiple times). If the field is not in @scheme[header], then the
return value is @scheme[header].
The @scheme[field] and @scheme[header] arguments must be both strings
or both byte strings, and the result is of the same type.}
@defproc[(insert-field [field (or/c string? bytes?)]
[value (or/c string? bytes?)]
[header (or/c string? bytes?)])
(or/c string? bytes?)]{
Creates a new header by prefixing the given @scheme[header] with the
given @scheme[field]-@scheme[value] pair. The @scheme[value] string
should not contain a terminating CRLF, but a multi-line value (perhaps
created with @scheme[data-lines->data]) may contain separator CRLFs.
The @scheme[field], @scheme[value], and @scheme[header] arguments must
be all strings or all byte strings, and the result is of the same
type.}
@defproc[(replaces-field [field (or/c string? bytes?)]
[value (or/c string? bytes? false/c)]
[header (or/c string? bytes?)])
(or/c string? bytes?)]{
Composes @scheme[remove-field] and (if @scheme[value] is not
@scheme[#f]) @scheme[insert-field].}
@defproc[(append-headers [header1 (or/c string? bytes?)]
[header2 (or/c string? bytes?)])
(or/c string? bytes?)]{
Appends two headers.
The @scheme[header1] and @scheme[header2] arguments must be both
strings or both byte strings, and the result is of the same type.}
@defproc[(standard-message-header [from string?]
[to (listof -string?)]
[cc (listof strings?)]
[bcc (listof string?)]
[subject string?])
string?]{
Creates a standard mail header given the sender, various lists of
recipients, a subject. A @scheme["Date"] field is added to the header
automatically, using the current time.
The BCC recipients do not actually appear in the header, but they're
accepted anyway to complete the abstraction.}
@defproc[(data-lines->data (listof string?)) string?]{
Merges multiple lines for a single field value into one string,
adding CRLF-TAB separators.}
@defproc[(extract-addresses [line string?]
[kind (one-of/c 'name 'address
'full 'all)])
(or/c (listof string?)
(listof (list/c string? string? string?)))]{
Parses @scheme[string] as a list of comma-delimited mail addresses,
raising an exception if the list is ill-formed. This procedure can be
used for single-address strings, in which case the returned list
contains only one address.
The @scheme[kind] argument specifies which portion of an address
should be returned:
@itemize[
@item{@scheme['name] --- the free-form name in the address, or the
address itself if no name is available.
@examples[
#:eval head-eval
(extract-addresses "John Doe <doe@localhost>" 'name)
(extract-addresses "doe@localhost (Johnny Doe)" 'name)
(extract-addresses "doe@localhost" 'name)
(extract-addresses " \"Doe, John\" <doe@localhost>, jane"
'name)
]}
@item{@scheme['address] --- just the mailing address, without any free-form
names.
@examples[
#:eval head-eval
(extract-addresses "John Doe <doe@localhost>" 'address)
(extract-addresses "doe@localhost (Johnny Doe)" 'address)
(extract-addresses "doe@localhost" 'address)
(extract-addresses " \"Doe, John\" <doe@localhost>, jane"
'address)
]}
@item{@scheme['full] --- the full address, essentially as it appears in the
input, but normalized.
@examples[
#:eval head-eval
(extract-addresses "John Doe < doe@localhost >" 'full)
(extract-addresses " doe@localhost (Johnny Doe)" 'full)
(extract-addresses "doe@localhost" 'full)
(extract-addresses " \"Doe, John\" <doe@localhost>, jane"
'full)
]}
@item{@scheme['all] --- a list containing each of the three possibilities:
free-form name, address, and full address (in that
order).
@examples[
#:eval head-eval
(extract-addresses "John Doe <doe@localhost>" 'all)
(extract-addresses "doe@localhost (Johnny Doe)" 'all)
(extract-addresses "doe@localhost" 'all)
(extract-addresses " \"Doe, John\" <doe@localhost>, jane"
'all)
]}
]}
@defproc[(assemble-address-field (addrs (listof string?))) string?]{
Creates a header field value from a list of addresses. The addresses
are comma-separated, and possibly broken into multiple lines.
@examples[
#:eval head-eval
(assemble-address-field '("doe@localhost"
"Jane <jane@elsewhere>"))
]}
@; ----------------------------------------
@section{Header Unit}
@defmodule[net/head-unit]
@defthing[head@ unit?]{
Imports nothing, exports @scheme[head^].}
@; ----------------------------------------
@section{Header Signature}
@defmodule[net/head-sig]
@defsignature[head^ ()]{}
Includes everything exported by the @schememodname[net/head] module.

View File

@ -43,9 +43,9 @@
@title{IMAP: Reading Mail}
@defmodule[net/imap]{The @schememodname[net/imap] module provides for
the client side of Internet Message Access Protocol version 4rev1
@cite["RFC2060"].}
@defmodule[net/imap]{The @schememodname[net/imap] module provides
utilities for the client side of Internet Message Access Protocol
version 4rev1 @cite["RFC2060"].}
@; ----------------------------------------
@ -497,3 +497,22 @@ mailbox path names.}
Returns a list of IMAP flags for the given mailbox. See also
@scheme[imap-flag->symbol].}
@; ----------------------------------------
@section{IMAP Unit}
@defmodule[net/imap-unit]
@defthing[imap@ unit?]{
Imports nothing, exports @scheme[imap^].}
@; ----------------------------------------
@section{IMAP Signature}
@defmodule[net/imap-sig]
@defsignature[imap^ ()]{}
Includes everything exported by the @schememodname[net/imap] module.

View File

@ -6,13 +6,16 @@
@table-of-contents[]
@include-section["url.scrbl"]
@include-section["uri-codec.scrbl"]
@include-section["sendurl.scrbl"]
@include-section["smtp.scrbl"]
@include-section["cgi.scrbl"]
@include-section["sendmail.scrbl"]
@include-section["head.scrbl"]
@include-section["nntp.scrbl"]
@include-section["pop3.scrbl"]
@include-section["imap.scrbl"]
@include-section["dns.scrbl"]
@include-section["gifwrite.scrbl"]
@(bibliography
@ -21,6 +24,13 @@
#:title "Common Gateway Interface (CGI/1.1)"
#:url "http://hoohoo.ncsa.uiuc.edu/cgi/")
(bib-entry #:key "RFC822"
#:title "Standard for the Format of ARPA Internet Text Messages"
#:author "David Crocker"
#:location "RFC"
#:url "http://www.ietf.org/rfc/rfc0822.txt"
#:date "1982")
(bib-entry #:key "RFC977"
#:title "Network News Transfer Protocol"
#:author "Brian Kantor and Phil Lapsley"
@ -28,6 +38,13 @@
#:url "http://www.ietf.org/rfc/rfc0977.txt"
#:date "1986")
(bib-entry #:key "RFC1738"
#:title "Uniform Resource Locators (URL)"
#:author "T. Berners-Lee, L. Masinter, and M. McCahill"
#:location "RFC"
#:url "http://www.ietf.org/rfc/rfc1738.txt"
#:date "1994")
(bib-entry #:key "RFC1939"
#:title "Post Office Protocol - Version 3"
#:author "J. Myers and M. Rose"

View File

@ -0,0 +1,147 @@
#lang scribble/doc
@(require "common.ss"
scribble/bnf
scribble/eval
(for-label net/url
net/uri-codec
net/uri-codec-unit
net/uri-codec-sig))
@(define uri-codec-eval (make-base-eval))
@interaction-eval[#:eval uri-codec-eval (require net/uri-codec)]
@title{URI Codec: Encoding and Decoding URIs}
@defmodule[net/uri-codec]{The @schememodname[net/uri-codec] module
provides utilities for encoding and decoding strings using the URI
encoding rules given in RFC 2396 @cite["RFC2396"], and to encode and
decode name/value pairs using the
@tt{application/x-www-form-urlencoded} mimetype given the in HTML 4.0
specification. There are minor differences between the two encodings.}
The URI encoding uses allows a few characters to be represented as-is:
@litchar{a} through @litchar{z}, @litchar{A} through @litchar{Z},
@litchar{0}-@litchar{9}, @litchar{-}, @litchar{_}, @litchar{.},
@litchar{!}, @litchar{~}, @litchar{*}, @litchar{'}, @litchar{(} and
@litchar{)}. The remaining characters are encoded as
@litchar{%}@nonterm{xx}, where @nonterm{xx} is the two-character hex
representation of the integer value of the character (where the
mapping character--integer is determined by US-ASCII if the integer is
less than 128).
The encoding, in line with RFC 2396's recommendation, represents a
character as-is, if possible. The decoding allows any characters
to be represented by their hex values, and allows characters to be
incorrectly represented as-is.
The rules for the @tt{application/x-www-form-urlencoded} mimetype
given in the HTML 4.0 spec are:
@itemize[
@item{Control names and values are escaped. Space characters are
replaced by @litchar{+}, and then reserved characters are escaped as
described in RFC 1738, section 2.2: Non-alphanumeric characters are
replaced by @litchar{%}@nonterm{xx} representing the ASCII code of
the character. Line breaks are represented as CRLF pairs:
@litchar{%0D%0A}. Note that RFC 2396 supersedes RFC 1738
@cite["RFC1738"].}
@item{The control names/values are listed in the order they appear
in the document. The name is separated from the value by @litchar{=}
and name/value pairs are separated from each other by either
@litchar{;} or @litchar{&}. When encoding, @litchar{;} is used as
the separator by default. When decoding, both @litchar{;} and
@litchar{&} are parsed as separators by default.}
]
These rules differs slightly from the straight encoding in RFC 2396 in
that @litchar{+} is allowed, and it represents a space. The
@schememodname[net/uri-codec] library follows this convention,
encoding a space as @litchar{+} and decoding @litchar{+} as a space.
In addtion, since there appear to be some brain-dead decoders on the
web, the library also encodes @litchar{!}, @litchar{~}, @litchar{'},
@litchar{(}, and @litchar{)} using their hex representation, which is
the same choice as made by the Java's @tt{URLEncoder}.
@; ----------------------------------------
@section[#:tag "uri-codec-proc"]{Functions}
@defproc[(uri-encode [str string?]) string?]{
Encode a string using the URI encoding rules.}
@defproc[(uri-decode [str string?]) string?]{
Decode a string using the URI decoding rules.}
@defproc[(form-urlencoded-encode [str string?]) string?]{
Encode a string using the @tt{application/x-www-form-urlencoded}
encoding rules. The result string contains no non-ASCII characters.}
@defproc[(form-urlencoded-deecode [str string?]) string?]{
Decode a string encoded using the
@tt{application/x-www-form-urlencoded} encoding rules.}
@defproc[(alist->form-urlencoded [alist (listof (cons/c symbol? string?))])
string?]{
Encode an association list using the
@tt{application/x-www-form-urlencoded} encoding rules.
The @scheme[current-alist-separator-mode] parameter determines the
separator used in the result.}
@defproc[(form-urlencoded->alist [str string])
(listof (cons/c symbol? string?))]{
Decode a string encoded using the
@tt{application/x-www-form-urlencoded} encoding rules into an
association list. All keys are case-folded for conversion to symbols.
The @scheme[current-alist-separator-mode] parameter determines the way
that separators are parsed in the input.}
@defparam[current-alist-separator-mode mode
(one-of/c 'amp 'semi 'amp-or-semi 'semi-or-amp)]{
A parameter that determines the separator used/recognized between
associations in @scheme[form-urlencoded->alist],
@scheme[alist->form-urlencoded], @scheme[url->string], and
@scheme[string->url].
The default value is @scheme['amp-or-semi], which means that both
@litchar{&} and @litchar{;} are treated as separators when parsing,
and @litchar{&} is used as a separator when encoding. The other modes
use/recognize only of the separators.
@examples[
#:eval uri-codec-eval
(define ex '((x . "foo") (y . "bar") (z . "baz")))
(code:line (current-alist-separator-mode 'amp) (code:comment #, @t{try @scheme['amp]...}))
(form-urlencoded->alist "x=foo&y=bar&z=baz")
(form-urlencoded->alist "x=foo;y=bar;z=baz")
(alist->form-urlencoded ex)
(code:line (current-alist-separator-mode 'semi) (code:comment #, @t{try @scheme['semi]...}))
(form-urlencoded->alist "x=foo;y=bar;z=baz")
(form-urlencoded->alist "x=foo&y=bar&z=baz")
(alist->form-urlencoded ex)
(code:line (current-alist-separator-mode 'amp-or-semi) (code:comment #, @t{try @scheme['amp-or-semi]...}))
(form-urlencoded->alist "x=foo&y=bar&z=baz")
(form-urlencoded->alist "x=foo;y=bar;z=baz")
(alist->form-urlencoded ex)
(code:line (current-alist-separator-mode 'semi-or-amp) (code:comment #, @t{try @scheme['semi-or-amp]...}))
(form-urlencoded->alist "x=foo&y=bar&z=baz")
(form-urlencoded->alist "x=foo;y=bar;z=baz")
(alist->form-urlencoded ex)
]}

View File

@ -22,8 +22,7 @@ you have a regular input port with which to process the document, as with
any other file.
Currently the only supported protocols are @scheme["http"] and
sometimes @scheme["file"]. See also the @schememodname[net/news]
library.
sometimes @scheme["file"].
@section{URL Structure}
@ -284,7 +283,7 @@ something like @litchar{1.0} or @litchar{1.1}, @nonterm{code} is an
exact integer for the response code, and @nonterm{message} is
arbitrary text without a return or newline.
The @schememodname[net/head.ss] library provides procedures, such as
The @schememodname[net/head] library provides procedures, such as
@scheme[extract-field] for manipulating the header.
Since web servers sometimes return mis-formatted replies,

View File

@ -76,7 +76,7 @@ exception is raised, but not both. Scheme therefore supplies
which does permit the implementation of such an exclusive guarantee:
@schemeblock[
(parameterize ([break-enabled #f])
(parameterize-break #f
(with-handlers ([exn:break? (lambda (x) (void))])
(semaphore-wait/enable-break s)))
]