
# Writing an extension for Ocsigen server

This page describes how to extend Ocsigen's server. This can be used to create new ways to generate pages (like Apache modules), to filter and change the requests (for example, rewriting of URLS), to extend the syntax of the configuration file.


### Filtering the requests or writing a module to generate pages

You can take as example the files `staticmod.ml` or `accesscontrol.ml` from Ocsigen Server's distribution.

The type of request is `Ocsigen_extensions.request_info` (have a look at it in the interface of module [`Ocsigen_extensions`](./Ocsigen_extensions.md)).

Each extensions loaded in the configuration file tries to handle the request and returns something of type `Extensions.answer`. If the page is not found by the extension (`Ext_not_found`), the following one will try to handle the request. If the page is found, the answer is `Ext_found r`. An extension can also modify the request before giving it to the next one (answer `Ext_continue_with of Extensions.request_info`), etc.


### Filtering the outputs

It is also possible to create extensions that will filter the output of the server (for example to compress it). It is very similar to the previous one. Have a look at the file `deflatemod.ml` for an example.


### Extending the configuration file


#### Extending the configuration file for an extension

The parsing of Ocsigen's configuration file is using a very basic xml parser (package `xml-light`). The function to be registered by the `Extensions.register_extension` function takes two parameters: the path of the web site and the xml subtree.

```
let parse_config path = function
    Xml.Element ("tag", attr, content) -> ...
      (* Do what you want here *)
  | Xml.Element _ ->
      raise (Extensions.Bad_config_tag_for_extension t)
  | _ -> raise (Extensions.Error_in_config_file "(my extension)")
```
The module `Parseconfig` defines functions to parse strings or sizes (in bytes, GB etc).


#### Giving parameters to an extension

Extensions may take parameters in the configuration file. During the loading of the extension, the function `Extensions.get_config ()` returns the xml tree between `<extension>` and `</extension>` (or `<library>` and `</library>`). Write a parser for that tree.


### Catching the request before it is fully read

For some extensions of the Web server, it is necessary to catch the request before it has been fully read (especially before the body of the request has been read). For example it is the case if you want to write a (reverse) proxy.


### Adding new commands for the server

If you want to add your own commands for the server command pipe, do something like:

```
let () =
  Ocsigen_extensions.register_command_function ~prefix:"yourextensionname"
    (fun s c -> match c with
       | ["mycommand"] -> ...
       | _ -> raise Ocsigen_extensions.Unknown_command)
```