Chapter 11

Semi-Interal Functions

The following functions expose more of the Web server for use by the development environment. They are not intended for general use. They may change at anytime or disappear entirely.

11.1  Miscellaneous

server-loop

   custodian (-> iport oport) (-> void) -> void
   (define (server-loop custodian tcp-listener config initial-timeout) ···)

custodian
The parent custodian for servlets.
tcp-listener
Where requests arrive.
config
Encapsulates most of the state of the server.
initial-timeout
The number of seconds before timing out connections.

make-config

   (string -> host) (hash-table-of sym script) (unit servlet-sig -> response) (hash-table-of sym servlet-instance) -> config
   (define (make-config hosts scripts instances access) ···)

host-table
str -> host

Maps host names to hosts

script-table
(hash-table-of sym script)

Maps servlet names to servlet units

script
(unit servlet^ -> response)

Represents a servlet that is invoked on each request

instance-table
(hash-table-of sym servlet-instance)

Maps the path part of a URL to the running servlet.

access-table
(hash-table-of sym (str sym str -> (U \#f str)))

Maps host names to functions that accept a protection domain, a user name, and a password and either return \#f if access is not denied (i.e. is accessible) or a string prompting for a particular password (i.e. "Course Grades").

servlet-instance
(make-servlet-instance nat channel (hash-table-of sym (continuation request)))

The natural-number counts the continuations suspended by this servlet. The channel communicates HTTP requests from the connection thread to the suspended servlet. The hash-table maps parameter parts of URLs to suspended continuations.

add-new-instance

   symbol instance-table -> void
   (define (add-new-instance sym instance-table) ···)

This creates a new servlet-instance and installs it in the instance-table under the name specified by sym.

gen-send/suspend

   string symbol instance-table (response -> void) (servlet-instance -> void) -> ((string -> response) -> request)
   (define (gen-send/suspend url symbol instance-table output-page resume-next-request) ···)

This produces a function like send/suspend, customized for a particular instance of a servlet. The url must refer to the servlet, which instance-table must map symbol to. The output-page function is called to send responses to the Web browser (remotely via HTTP in the normal server, locally via some other means in the development environment). resume-next-request blocks for the the next Web request and jumps to the appropriate continuation.

gen-resume-next-request

   ( -> void) (channel -> void) -> (instance -> void)
   (define (gen-resume-next-request update-time! update-channel!) ···)

update-time!
Resets timeouts upon each Web request.
update-channel!
Receives the channel used to send responses to the connection thread.

11.2  Starting the Server from a Program

Requiring the library web-server.ss, via

(require (lib "web-server.ss" "web-server"))

provides the serve function, which starts the server with more configuration options.

serve

   configuration [natural-number (union string #f)] -> (-> void)
   (define (serve configuration . port ip-address) ···)

The serve function starts the Web server, just like the launcher does, but the configuration argument supplies the server's settings. The optional port argument overrides the port supplied by the configuration. The optional ip-address restricts accepted Web requests to come only from that address.

The result of invoking serve is a function of no arguments that shuts down the server.

serve

   (opt->* (configuration?) ((and/f number? integer? exact? positive?) (union string? false?) (make-mixin-contract frame%)) ((-> void?) (any? . -> . (union false? string?)) (any? . -> . (union false? string?)) (any? . -> . string?) (-> (union false? (is-a?/c frame%))) (-> (is-a?/c frame%))))
   (define (serve configuration . frame) ···)

In addition, this serve function accepts another optional argument. This argument is mixed into the frame% class created by the internal browser. The frame is then instantiated with one argument: the URL to visit.

11.3  The Interal Server

The library internal-server.ss provides a single function named internal-serve that behaves almost the same as serve. Instead of accepting HTTP requests from network connections, internal-serve constructs a virtual network via pipes and channels (see tcp-redirect.ss in the net collection) and uses a browser from the browser collection to show the URLs. No network connections from the underlying OS are used.

It returns six functions. The second, third, and fourth results are helper functions that manipulate URLs. They are here as an artifact of the internal server organization. Since the internal server has its own instantiation of the net collection's URL library, other code cannot manipulate the URLs. These are various needed helper functions.

  1. The first one shutsdown the Web server, as above.

  2. The second result is a function that takes in a URL value (any value, really -- whatever the browser collection uses as URLs should be okay here) and determines if it represents a URL that would be used internally or is a file: URL. This function returns \#f if the URL would be handled internally and returns a string representing the URL if it would be handled externally.

  3. The third result takes a URL value (any value, really -- whatever the browser collection uses as URLs should be okay here) and returns that path portion of the URL, or \#f if none.

  4. The fourth result turns a url into a string.

  5. The fifth result from this serve is a function that returns an already opened browser window, if one is available or \#f if none are available.

  6. The final result creates a new browser frame. The new frame is not visible.

11.4  Constructing Configurations

Constructing configurations requires another library.

(require (lib "configuration.ss" "web-server"))

load-configuration

   string -> configuration
   (define (load-configuration path) ···)

This function accepts a path to a configuration file and returns a configuration that serve accepts. The configuration tool can create configuration files, as explained in the section titled ``The Configuration Tool''. Configuration files can also be created by hand, as described in the section titled ``Configuration Syntax''.

11.5  Monitoring the Server

Requiring the library monitor-web-server.ss, via

(require (lib "monitor-web-server.ss" "web-server"))

provides the functions:

poke-web-server

   channel string nat nat -> result
   (define (poke-web-server channel server port timeout-seconds) ···)

The poke-web-server procedure takes a channel on which the results will come in, a server name to test, a port on that server to test, and a timeout (in seconds). The procedure returns immediately. The channel passed to the procedure will receive at least one result within (timeout-seconds + epsilon), for some reasonable epsilon.

A result is one of:

where server-name and msg are strings, server-port and timeout-seconds are numbers, and exn is an exception.

result-message

   result -> string
   (define (result-message result) ···)

The result-message procedure takes a result and produces a multi-line string suitable for inclusion in an error log or an email message.

11.5.1  Example

Here's a simple piece of code which checks the PLT download server:

(require (lib "monitor-web-server.ss" "web-server"))
(let ([result-channel (make-channel)]
      [server-name "download.plt-scheme.org"]
      [server-port 80])
    (poke-web-server result-channel server-name server-port 10)
    (let ([result (channel-get result-channel)])
      (match result
           [`(ok) (void)]
           [else (printf (result-message result))])))

To have this done automatically, see the section titled ``Monitoring the Server'' or Monit.