1 Running Web Servlets

▼ |  | Web Applications in Racket

1 | Running Web Servlets
2 | Stateful Servlets
3 | Stateless Servlets
4 | HTTP: Hypertext Transfer Protocol
5 | URL-Based Dispatch
6 | Formlets: Functional Form Abstraction
7 | Templates: Separation of View
8 | Page: Short-hand for Common Patterns
9 | Testing Servlets
10 | Troubleshooting and Tips
| Index

► | 1 | Running Web Servlets

1.1 | Instant Servlets
1.2 | Simple Single Servlet Servers
1.3 | Command-line Tools

On this page:

1.1`` Instant Servlets
no-web-browser
static-files-path
1.2`` Simple Single Servlet Servers
1.2.1`` Examples
1.2.1.1`` Stateless Servlets
1.2.2`` Full API
serve/ servlet
1.3`` Command-line Tools

top contents ← prev up next →

### 1`` Running Web Servlets🔗ℹ

There are a number of ways to run Web servlets.

#### 1.1`` Instant Servlets🔗ℹ

#lang web-server/insta | package: web-server-doc

The fastest way to get a servlet running in the Web server is to use the "Insta" language in DrRacket. Enter the following into DrRacket:

> #lang web-server/insta
> (define (start req)
> (response/xexpr
> `(html (head (title "Hello world!"))
> (body (p "Hey out there!")))))

And press Run. A Web browser will open up showing your new servlet. This servlet will only be accessible from your local machine.

Behind the scenes, DrRacket has used serve/servlet to start a new server that uses your start function as the servlet. You are given the entire web-server/servlet API.

The following API is provided to customize the server instance:

> procedure (no-web-browser) → void

Calling this will instruct DrRacket to not start a Web browser when you press Run.

> procedure (static-files-path path) → void
> path : path-string?

This instructs the Web server to serve static files, such as stylesheets and images, from path.

If you want more control over specific parameters, keep reading about web-server/servlet-env.

#### 1.2`` Simple Single Servlet Servers🔗ℹ

(require web-server/servlet-env) | package: web-server-lib

The Web Server provides a way to quickly configure and start a servlet with more customizability than web-server/insta provides. This is provided by the web-server/servlet-env module.

##### 1.2.1`` Examples🔗ℹ

Here is a simple example of its use:

> #lang racket
> (require web-server/servlet
> web-server/servlet-env)
> (define (start req)
> (response/xexpr
> `(html (head (title "Hello world!"))
> (body (p "Hey out there!")))))
> (serve/servlet start)

Unlike the web-server/insta language, start is not a special identifier, so we could just as well have written the example as:

> #lang racket
> (require web-server/servlet
> web-server/servlet-env)
> (define (my-app req)
> (response/xexpr
> `(html (head (title "Hello world!"))
> (body (p "Hey out there!")))))
> (serve/servlet my-app)

Let’s look at some of the customizations serve/servlet allows.

Suppose you’d like to change the port to something else, change the last line to:

> (serve/servlet my-app
> #:port 8080)

Suppose you want to accept connections from external machines:

> (serve/servlet my-app
> #:listen-ip #f)

By default the URL for your servlet is "http://localhost:8000/servlets/standalone.rkt", suppose you wanted it to be "http://localhost:8000/hello.rkt":

> (serve/servlet my-app
> #:servlet-path "/hello.rkt")

Suppose you wanted it to capture top-level requests:

> (serve/servlet my-app
> #:servlet-regexp #rx"")

Or, perhaps just some nice top-level name:

> (serve/servlet my-app
> #:servlet-path "/main")

Suppose you wanted to use a style-sheet ("style.css") found on your Desktop ("/Users/jay/Desktop/"):

> (serve/servlet my-app
> #:extra-files-paths
> (list
> (build-path "/Users/jay/Desktop")))

These files are served in addition to those from the #:server-root-path "htdocs" directory. You may pass any number of extra paths.

If you want to use serve/servlet in a start up script for a Web application, and don’t want a browser opened or the DrRacket banner printed, then you can write:

> (serve/servlet my-app
> #:command-line? #t)

##### 1.2.1.1`` Stateless Servlets🔗ℹ

Suppose you would like to start a server for a stateless Web servlet "servlet.rkt" that provides start:

> #lang racket
> (require "servlet.rkt"
> web-server/servlet-env)
> (serve/servlet start #:stateless? #t)

You can also put the call to serve/servlet in the web-server module directly:

> #lang web-server
> (require web-server/servlet-env)
> (define (start req)
> (start
> (send/suspend
> (lambda (k-url)
> (response/xexpr
> `(html (body (a ([href ,k-url]) "Hello world!"))))))))
> (serve/servlet start #:stateless? #t)

Like always, you don’t even need to save the file.

##### 1.2.2`` Full API🔗ℹ

> > procedure
> > (serve/servlet |
> > |  | start |
> > | [ | #:command-line? command-line? |
> > |  | #:connection-close? connection-close? |
> > |  | #:launch-browser? launch-browser? |
> > |  | #:quit? quit? |
> > |  | #:banner? banner? |
> > |  | #:listen-ip listen-ip |
> > |  | #:port port |
> > |  | #:max-waiting max-waiting |
> > |  | #:safety-limits safety-limits |
> > |  | #:servlet-path servlet-path |
> > |  | #:servlet-regexp servlet-regexp |
> > |  | #:stateless? stateless? |
> > |  | #:stuffer stuffer |
> > |  | #:manager manager |
> > |  | #:servlet-namespace servlet-namespace |
> > |  | #:server-root-path server-root-path |
> > |  | #:extra-files-paths extra-files-paths |
> > |  | #:servlets-root servlets-root |
> > |  | #:servlet-current-directory servlet-current-directory |
> > |  | #:file-not-found-responder file-not-found-responder |
> > |  | #:servlet-loading-responder responders-servlet-loading |
> > |  | #:servlet-responder responders-servlet |
> > |  | #:mime-types-path mime-types-path |
> > |  | #:ssl? ssl? |
> > |  | #:ssl-cert ssl-cert |
> > |  | #:ssl-key ssl-key |
> > |  | #:log-file log-file |
> > |  | #:log-format log-format]) |
> → any
> start : (request? . -> . can-be-response?)
> command-line? : boolean? = #f
> connection-close? : boolean? = #f
> launch-browser? : boolean? = (not command-line?)
> quit? : boolean? = (not command-line?)
> banner? : boolean? = (not command-line?)
> listen-ip : (or/c #f string?) = "127.0.0.1"
> port : listen-port-number? = 8000
> max-waiting : exact-nonnegative-integer? = 511
> | safety-limits |  | : |  | safety-limits?
> |  |  | = |  | (make-safety-limits #:max-waiting max-waiting)
> servlet-path : string? = "/servlets/standalone.rkt"
> | servlet-regexp |  | : |  | regexp?
> |  |  | = |  |
> (regexp
> (format "^~a$" (regexp-quote servlet-path)))
> stateless? : boolean? = #f
> stuffer : (stuffer/c serializable? bytes?) = default-stuffer
> | manager |  | : |  | manager?
> |  |  | = |  | (make-threshold-LRU-manager #f (* 128 1024 1024))
> servlet-namespace : (listof module-path?) = empty
> | server-root-path |  | : |  | path-string?
> |  |  | = |  | (collection-path "web-server" "default-web-root")
> | extra-files-paths |  | : |  | (listof path-string?)
> |  |  | = |  | (list (build-path server-root-path "htdocs"))
> | servlets-root |  | : |  | path-string?
> |  |  | = |  | (build-path server-root-path "htdocs")
> servlet-current-directory : path-string? = servlets-root
> | file-not-found-responder |  | : |  | (request? . -> . can-be-response?)
> |  |  | = |  |
> (gen-file-not-found-responder
> (build-path
> server-root-path
> "conf"
> "not-found.html"))
> | responders-servlet-loading |  | : |  | (url? any/c . -> . can-be-response?)
> |  |  | = |  | servlet-loading-responder
> | responders-servlet |  | : |  | (url? any/c . -> . can-be-response?)
> |  |  | = |  | servlet-error-responder
> mime-types-path : path-string? = ....
> ssl? : boolean? = #f
> | ssl-cert |  | : |  | (or/c #f path-string?)
> |  |  | = |  | (and ssl? (build-path server-root-path "server-cert.pem"))
> | ssl-key |  | : |  | (or/c #f path-string?)
> |  |  | = |  | (and ssl? (build-path server-root-path "private-key.pem"))
> log-file : (or/c #f path-string? output-port?) = #f
> | log-format |  | : |  | (or/c log-format/c format-reqresp/c)
> |  |  | = |  | 'apache-default

This sets up and starts a fairly default server instance.

start is loaded as a servlet and responds to requests that match servlet-regexp. The current directory of servlet execution is servlet-current-directory.

If launch-browser? is true, then a web browser is opened to "http://localhost:<port><servlet-path>". servlet-path has no other purpose, if servlet-regexp is provided.

If quit? is true, then the URL "/quit" ends the server.

If stateless? is true, then the servlet is run as a stateless

> #lang web-server

module and stuffer is used as the stuffer.

serve/servlet is simpler interface over serve/launch/wait, dispatch/servlet, and a few of the standard Dispatchers. Some options, like port and safety-limits are transparently passed to serve/launch/wait. Some advanced customization requires using these underlying pieces of the web-server directly. However, many simpler customizations do not, which the rest of this section describes.

The server listens on listen-ip and port port. If listen-ip is #f, then the server accepts connections to all of the listening machine’s addresses. Otherwise, the server accepts connections only at the interface(s) associated with the given string. For example, providing "127.0.0.1" (the default) as listen-ip creates a server that accepts only connections to "127.0.0.1" (the loopback interface) from the local machine.

If ssl-cert and ssl-key are not false, then the server runs in HTTPS mode with ssl-cert and ssl-key as the certificates and private keys.

The servlet is loaded with manager as its continuation manager. (The default manager limits the amount of memory to 64 MB and deals with memory pressure as discussed in the make-threshold-LRU-manager documentation.)

The server files are rooted at server-root-path (which is the "default-web-root" directory in the web-server collection by default.) File paths, in addition to the "htdocs" directory under server-root-path may be provided with extra-files-paths. These paths are checked first, in the order they appear in the list.

Other servlets are served from servlets-root. The modules specified by servlet-namespace are shared between servlets found in servlets-root and the current namespace (and therefore the start procedure.)

If a file cannot be found, file-not-found-responder is used to generate an error response. If a servlet fails to load, responders-servlet-loading is used. If a servlet errors during its operation, responders-servlet is used.

If banner? is true, then an informative banner is printed. You may want to use this when running from the command line, in which case the command-line? option controls similar options.

MIME types are looked up at mime-types-path. By default the "mime.types" file in the server-root-path is used, but if that file does not exist, then the file that ships with the Web Server is used instead. Of course, if a path is given, then it overrides this behavior.

If log-file is given, then it used to log requests using log-format as the format. Allowable formats are those allowed by log-format->format. If log-format is a function, it is used directly to render the log entry. If log-file is a filepath, the given file is opened and written in a different thread. If log-file is an output-port?, logs are written directly to the port.

If connection-close? is #t, then every connection is closed after one request. Otherwise, the client decides based on what HTTP version it uses.

Changed in version 1.3 of package web-server-lib: Added support for providing log-file as an output port.
Changed in version 1.6: Added the safety-limits argument as with serve/launch/wait: see compatability note.

#### 1.3`` Command-line Tools🔗ℹ

One command-line utility is provided with the Web Server:

plt-web-server [-f <file-name> -p <port> -a <ip-address> --ssl]

The optional file-name argument specifies the path to a configuration-table S-expression (see configuration-table->sexpr for the syntax documentation.) If this is not provided, the default configuration shipped with the server is used. The optional port and ip-address arguments override the corresponding portions of the configuration-table. If the ssl option is provided, then the server uses HTTPS with "server-cert.pem" and "private-key.pem" in the current directory, with 443 as the default port. (See the openssl module for details on the SSL implementation.)

The configuration-table is given to configuration-table->web-config@ and used to construct a web-config^ unit, and is linked with the web-server@ unit. The resulting unit is invoked, and the server runs until the process is killed.

top contents ← prev up next →