# Request Callback functions

As we have seen in the previous chapters, the core part of the Library knows nothing about how to access, for example, a HTML document from a remote server. All this depends on what the application has registered. In many situations there are a number of things to do before a request is actually sent over the wire. For example we might already have the document in a cache or we might have some translation of the URL so that we don't go directly to the remote server. The latter case includes redirection of a request to go through a proxy server or a gateway. Likewise, when a request is terminated, we might want to keep a log of the request and the result, update history lists etc.

The Library does provide a large amount of such pre- and post processing modules. However, the exact amount used by an application depends on the purpose of the application. Simple script-like applications typically do not need any history mechanism etc. Therefore these modules are not a part of the core but instead they can be registered as all other preferences. The Net Manager provides functionality for registering a set of callback functions that can be called before and after a request has been executed. Of course, the result of a pre-processing might be that the request does not have to be executed at all in which case the request can be terminated before the protocol module is called to execute the request.

## Generic Handling of Callbacks

The registration of callback functions is handled by the HTNet Manager and it is (of course) based on lists as we have seen so many times before. A callback function can be added to a list by using the following function:

    extern BOOL HTNetCall_add (HTList * list, HTNetCallback * cbf, int status);

The callback function has to be of type `HTNetCallback` which is defined as

    typedef int HTNetCallback (HTRequest * request, int result);

This means that a callback function is called with the current request object and the result of the request. Now, if the callback is registered as a pre callback then we obviously do not yet have a result and the functions is called with the code HT_OK. However, if it is a post callback function then the result code may take any of the following values:

HT_ERROR
  An error occured
HT_INTERRUPTED
  The request was interrupted
HT_LOADED
  The document was loaded
HT_NO_DATA
  OK, but no data
HT_RETRY
  Retry request after at a later time
HT_PERM_REDIRECT
  The request has been permanently redirected and we send back the new URL
HT_TEMP_REDIRECT
  The request has been temporarily redirected and we send back the new URL
HT_NO_ACCESS
  The request could not be fulfilled because it didn't contain sufficient credentials

When a callback function is registered, it may be registered with a status code for which it is to be called. This means that there may be different callback functions to handle error situations, redirections etc. The status code may also take any of the values above, or HT_ALL if it is to be called always.

A callback function may return any code it likes, but IF the return code is different than HT_OK, then the callback loop is stopped. If we are in the before loop and a function returns anything else than HT_OK then we immediately jump to the after loop passing the last return code from the before loop.

Likewise, a callback function can be removed from a list using the following function:

    extern BOOL HTNetCall_delete (HTList * list, HTNetCallback *cbf);

or if you simply want to remove all functions from a list then you can use

    extern BOOL HTNetCall_deleteAll (HTList * list);

## Pre-Request Callbacks

When a request has been issued there are a number of things that an application might want to do with the request before it actually goes on the wire, for example to talk to a remote HTTP server. Examples are checking if the object already is kept in a cache managed by the application, if the request should be redirected to a proxy or a gateway, or there is some other kind of translation of the URL taking place. The Library provides a variety of modules that handles many common place translations such as redirection of URLs and caching. The full list of modules are:

### Rule File Management

An application can be setup by using a rule file, also known as a configuration file. This is for example the case with the W3C httpd and the W3C Line Mode Browser. The Rules module provides basic support for configuration file management and the application can use this is desired. The module is not referred to by the Library. Reading a rule file is implemented as a stream converter so that a rule file can come from anywhere, even across the network!

### Proxies and Gateways

Applications do not have to provide native support for all protocols, they can in many situations rely on the support of proxies and gateways to help doing the job. Proxy servers are often used to carry client requests through a firewall where they can provide services like corporate caching and other network optimizations. Both Proxy servers and gateways can serve as "protocol translators" which can convert a request in the main Web protocol, HTTP, to an equivalent request in another protocol, for example NNTP, FTP, or Gopher. In a later section we will see how to set up the Proxy servers and gateways using the Proxy module.

As a HTTP request looks different when it is directed to a proxy server than to a origin server, the HTTP module needs to know whether it is talking to a proxy for this particular request or not. You can specify in a request object whether a proxy is being used or not by using the following methods:

    extern void HTRequest_setProxing (HTRequest * request, BOOL proxying);
    extern BOOL HTRequest_proxying (HTRequest * request);

### Cache Manager

Caching is a required part of any efficient Internet access applications as it saves bandwidth and improves access performance significantly in almost all types of accesses. The Library supports two different types of cache: The memory cache and the file cache. The two types differ in several ways which reflects their two main purposes: The memory cache is for short term storage of graphic objects whereas the file cache is for intermediate term storage of data objects. Often it is desirable to have both a memory and a file version of a cached document, so the two types do not exclude each other. The HTCache module provides a basic cache that can be used by an application.

### Register a list of BEFORE Callbacks

Until now, we have only described how to build a list of callback functions. We will now describe how to setup a list as either a pre processing set of callback function (the BEFORE loop, or a post processing set (AFTER loop). A set of callback functions can be registered to be called before the request is started by using the following function:

    extern BOOL HTNet_setBefore	(HTList * list);

In many cases you know when you register a callback function that this is a function that you always want to be called when either a request starts up or terminates. In the former case you can simply register the callback directly using the following function:

    extern BOOL HTNetCall_addbefore	(HTNetCallback *cbf, int status);

## Post-Request Callbacks

When a request is terminated, the application often has to do some action as a result of the request (and of the result of the request). The Application part of the Library provides two following modules to handle logging and history management. You can register a POST request handler in the Net Manager as described in the User's Guide. The set of modules provided by the Library is:

### Logging

Often it is required to log the requests issued to the Library. This can either be the case if the application is a server or it can also be useful in a client application. The HTLog Module provides a simple logging mechanism which can be enabled if needed.

### History Management

Another type of logging is keeping track of which documents a user has visited when browsing along on the Web. The HTHistory module provides a basic set of functionality to keep track of multiple linear history lists.

### Register a list of AFTER Callbacks

The registration of a set of callback functions to be called when a request has terminated is handled in very much the same way:

    extern BOOL HTNet_setAfter	(HTList * list);
    extern BOOL HTNetCall_addBefore (HTNetCallback *cbf, int status);