(index ("make-entry" 0) ("entry->string" 410) ("send-entry" 817) ("send-line" 973) ("send-lastline" 1189) ("send-text-file" 1355) ("send-binary-file" 1672) ("accept" 1846) ("max-line-length" 1846))
(def (sig (procedure "(make-entry type name selector host port)" (id make-entry))) (p "Create a record consisting of the five main fields in RFC 1436.  The fields may be of any type, as they are converted to strings via " (tt "->string") " before sending.") (p "Example: " (tt "(make-entry 'I \"Picture of me\" \"/me.jpg\" (get-host-name) 70)")) (p "Also provided is the record predicate " (tt "entry?") "."))
(def (sig (procedure "(entry->string e)" (id entry->string))) (p "Converts an entry record to a string, using the following rules:") (ul (li "Entry fields are converted to strings via " (tt "->string")) (li "CR, LF, TAB and NUL are replaced with SPACE") (li "Only the first character of the " (tt "type") " field string is used") (li "Output string format is \"TypeName<TAB>Selector<TAB>Host<TAB>Port\"")))
(def (sig (procedure "(send-entry e)" (id send-entry))) (p "Send an entry record to the client.  Equivalent to " (tt "(send-line (entry->string e))") "."))
(def (sig (procedure "(send-line line)" (id send-line))) (p "Send a single line to the client, and terminate it with a CRLF.") (p "The constant " (tt "eol") " is also provided which is just the string \"\\r\\n\"."))
(def (sig (procedure "(send-lastline)" (id send-lastline))) (p "Send an end-of-transmission indicator to the client, which is simply a period on a line by itself."))
(def (sig (procedure "(send-text-file filename)" (id send-text-file))) (p "Read text file " (tt "FILENAME") " and send it to the client, with a " (tt "CRLF") " terminating each line.  A period at the beginning of a line will be escaped (doubled).  A lone period is sent at the end, via " (tt "(send-lastline)") "."))
(def (sig (procedure "(send-binary-file filename)" (id send-binary-file))) (p "Send a binary file verbatim to the client, using the sendfile module.  No lastline is sent."))
(def (sig (procedure "(accept handle-request)" (id accept)) (parameter "(max-line-length 2048)" (id max-line-length))) (p "Reads a line from the client (up to CRLF, plain CR, or plain LF), replaces any ASCII NULs with SPACE, and splits the line into fields, using TAB as the delimiter.  In general, client lines take 4 forms:") (ul (li (tt "Selector")) (li (tt "Selector<TAB>Search terms")) (li (tt "Selector<TAB>Gopher+ data")) (li (tt "Selector<TAB>Gopher+ data<TAB>Search terms"))) (p "The first field is always the requested selector.  Search terms are added for type 7 requests.  The Gopher+ protocol unfortunately introduces some context-sensitive ambiguity into the meaning of the fields, and this module is not in the business of figuring that out. Instead, the user is expected to hash out the meaning of any extra fields, and " (tt "handle-request") " is therefore called with two arguments:") (pre "(handle-request (car fields) (cdr fields))\n(handle-request selector extra)            ; put another way") (p "Note: the RFC says selectors may not exceed 255 characters, but this check is not enforced; however, to avoid memory overflow, " (tt "accept") " will only read up to max-line-length characters.  (Special note: line limiting doesn't currently work for TCP ports!)"))
