7 Web Programming

7.3 Server-Side Web Scripts

We have seen so far how to write programs that create static HTML documents. Such programs could be useful to transform existing data into a static set of HTML pages. In contrast, the contents of dynamic web pages is computed at the time they are requested by a client (usually, a web browser). Technically, the creation of dynamic web pages is supported by web servers by so-called CGI (Common Gateway Interface) programs. If a web server is asked for a document with the suffix “.cgi” instead of “.html” (the exact behavior is defined in the configuration of the web server; see also Section 7.4 below), then the server does not return the contents of the corresponding file but executes the file (the “CGI program”) and returns the standard output produced by this program. Thus, a CGI program must write an HTML document on its standard output. The CGI program can also take user input in an HTML form into account; this is described in Section 7.5.

Since the CGI program is some executable stored on the web server, it can be written in any programming language. Thus, we can also write a Curry program which generates prints an HTML document when it is executed. As already discussed above, writing raw HTML documents could be error prone so that it is better create HTML data structures. Therefore, the library HTML.Base supports the creation of dynamic web pages by compiling a Curry program with a main operation of type

main :: IO HtmlPage

into an executable which prints the corresponding HTML document (the actual application of this compiler is described in the next section). Since this is an I/O operation, the contents of the generated HTML documents could also depend on the environment of the web server, e.g., information stored in the file system or databases.

As a first example, we want to generate a CGI program that computes the above multiplications of digits on demand. For this purpose, we define the following operation multPage (the right-associate operator “$” is defined with a low precedence in the prelude and denotes function application; it is often used to avoid brackets, e.g., the expression “f $ g $ 3+4” is equivalent to “f (g (3+4))”) [Browse Program][Download Program]:

multPage :: IO HtmlPage
multPage =
  return $ headerPage "Multiplication of Digits" htmlMultiplications

Here we use the operation headerPage which is similar to page but adds the page title as a header line:

headerPage :: String -> [BaseHtml] -> HtmlPage
headerPage title hexps = page title (h1 [htxt title] : hexps)

To see an application of accessing the server environment, we define a form that shows the current date and time of the server (the IO action getLocalTime, defined in the standard library Data.Time contained in Curry package time, returns the local date and time in some internal representation which can be converted into a readable string by the function calendarTimeToString) [Browse Program][Download Program]:

timePage :: IO HtmlPage
timePage = do
 time <- getLocalTime
 return $ page "Current Server Time"
   [h1 [htxt $ "Current date and time: " ++ calendarTimeToString time]]

The installation of such web programs on a web server is described in the following section.