home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  


Writing Apache Modules with Perl and C
By:   Lincoln Stein and Doug MacEachern
Published:   O'Reilly & Associates, Inc.  - March 1999

Copyright © 1999 by O'Reilly & Associates, Inc.


 


   Show Contents   Previous Page   Next Page

Chapter 11 - C API Reference Guide, Part II / Implementing Configuration Directives in C
The cmd_parms Structure

A cmd_parms structure is the first argument passed to all directive handlers. It contains a miscellaneous collection of information about the server configuration process. You may never actually need to use this argument, but it is available for certain advanced configuration tasks, such as implementing new container directives.

Example 11-2 gives the cmd_parms typedef, copied from http_config.h. The extensive (and sometimes wry) comments have been condensed to save some space.

Example 11-2. The cmd_parms Structure (from http_config.h)

typedef struct {
  void *info;                /* argument to command from cmd table */
  int override;              /* same as req_override */
  int limited;               /* which methods are <Limit>ed */
  configfile_t *config_file; /* filehandle for reading from config stream */ 
pool *pool; /* long-term resource pool */ pool *temp_pool; /* short-term resource pool */ server_rec *server; /* server record */ char *path; /* directive path information */ const command_rec *cmd; /* copy of command_rec entry */ const char *end_token; /* end token for container directives */ } cmd_parms;

Here is a brief description of each of the fields in this structure:

void *info

This field contains a copy of the cmd_data field in the current directive's command record. It is typically used for passing static information to the directive handler.

int override

The override field contains a copy of the args_how field in the current directive's command record.

int limited

If the directive is contained within a <Limit> section, this field contains a bit mask representing the method numbers that the section applies to. This bit mask is constructed from the method numbers in the same way as described in "Authorization and Authentication Routines" in Chapter 10.

configfile_t *config_file

This is a filehandle-like data type from which you can read raw text from the current configuration file. See "Customizing the Configuration Process" later in this chapter for details on using this field.

pool *pool

This is a resource pool that persists for the lifetime of the server. It is only destroyed when the server is restarted or shutdown. If you wish to allocate truly long-term configuration information, this is the pool to use.

pool *temp_pool

In contrast, this pool pointer is available only within the configuration phase during server startup. It is destroyed before the first request is served. It is handy for allocating space for scratch data that your module won't need after configuration is completed.

server_rec *server

This field contains a pointer to the server_rec for the current (virtual) host. You will need to use it when processing server-specific configuration directives in order to retrieve the server-specific configuration record.

char *path

When the handler is called to process a directory-specific directive, the path will contain whatever is the argument of the enclosing <Directory>, <Location>, or <Files> section. For <Directory> and <Location>, this will be the path of the current directory. For <Files>, it will be the text of the regular expression or glob match. If the handler is being called to process a directive located in an access control file, path will contain the path to the directory containing the .htaccess file.

If the directive is called in a server context (either in the main part of a configuration file or a <VirtualHost> section), path will be an empty string.

The path field is used by two frequent idioms. One idiom is used when you want a directive to be available only in a per-directory context, such as a .htaccess file. This effect is achieved by the following fragment of a directive-processing routine:

static const char *foo_cmd(cmd_parms *parms, void *mconfig, ...)
{
   foo_dir_config *cfg = (foo_dir_config *)mconfig;
   if (parms->path == NULL || cfg == NULL) {
      return "foo: only valid in per-directory context";
   }
   ...

The other idiom is used when you want a directive to be valid for processing directives located both inside and outside of <Directory> sections and to operate on the per-server configuration record when outside a directory context but on the per-directory record when inside a directory context:

static const char *foo_cmd(cmd_parms *parms, void  *mconfig, ...)
{
  foo_dir_conf *dconf = (foo_dir_conf *)mconfig;
  foo_srv_conf *sconf = (foo_srv_conf *)
       ap_get_module_config(parms->server->module_config, &foo_module);
   if (parms->path == NULL) {
       ...configure sconf...
  }
  else {
      ...configure dconf...
  }
}

const command_rec *cmd

This field points back to the command_rec entry that describes the directive that the current handler is responsible for.

const char *end_token

When Apache is processing the contents of a container section such as <Directory>, end_token contains the character string that will terminate the section, e.g., </Directory>. end_token is used internally by Apache's ap_srm_command_loop() function (described later in this chapter) but is rarely, if ever, needed by modules.

Accessing Module Configuration Data

   Show Contents   Go to Top   Previous Page   Next Page

The last piece in the puzzle is a way for modules to get access to their configuration data at request time, from within a transaction phase handler. This need is satisfied by the ap_get_module_config() call, and its rarely used sibling, ap_set_module_config().

void *ap_get_module_config (void *conf_vector, module *m)

Modules can use ap_get_module_config() to fetch both per-directory and per-server configuration data. To fetch per-directory data, pass the function the contents of the request record's per_dir_config field as the first argument, and the address of the module's own module structure as the second:

hello_dir_config *cfg = (hello_dir_config *)
       ap_get_module_config(r->per_dir_config, &hello_module);

The function result is a void*. For clarity you should cast it to correct type in order to access the configuration data structure's fields, although technically many C compilers allow you to assign void pointers to typed variables without complaining. You'll see examples of both styles in the standard Apache modules.

Do not make the mistake of using the request record's request_config field here. The request_config is a spare (and usually empty) field that a module can use to pass configuration information to subrequests. We'll touch on this shortly.

To fetch per-server data, use the configuration vector stored in the server record's module_config field as the first argument:

traffic_server_config *cfg = (traffic_server_config *)
   ap_get_module_config(r->server->module_config, &traffic_module);

In case you're wondering, the per_dir_config and module_config fields are actually pointers to a private Apache type known as the "configuration vector." However, this data type doesn't contain any user-serviceable parts and so is presented to the visible part of the API as an opaque void pointer.

void ap_set_module_config (void *conf_vector, module *m, void *val)

Modules don't often call this function directly, as it is called for them by the internal configuration mechanism. When a new per-directory or per-server module configuration is created, Apache saves a pointer to it in a vector of configuration records, indexed by the address of your module. A copy of this vector eventually appears in the server record's module_config field or in the request record's per_dir_config field. Given a configuration vector, a module pointer, and the configuration data block, ap_set_module_ config() appends the configuration information to the vector for later retrieval by ap_get_ module_config().

Some modules, such as mod_negotiation, don't bother with a per-server config creator because their entire configuration consists of an "on" or "off" Boolean. Instead, the directive handlers for these modules simply call ap_set_module_config() to set their configuration block to NULL when their state is off or non-NULL when their state is on. This is not a recommended practice!

Another use for ap_set_module_config() is to pass per-request configuration data to subrequests via the request record's request_config field. This field usually points to an empty configuration vector, but handlers are free to append their own configuration data to the vector. The information is then available for use by subrequests and by handlers for later phases of the transaction. Any information stored in request_config is cleared out at the end of the current transaction.

Example:

ap_set_module_config(r->request_config, &my_module, cfg_ptr);

To see some practical examples of the request_config field, examine the source code for mod_include and mod_mime_magic, where the request_config vector is used to stash information passed to subrequests.

To pass simple string messages between different phases and between requests and subrequests, you might consider using the notes table instead.

   Show Contents   Go to Top   Previous Page   Next Page
Copyright © 1999 by O'Reilly & Associates, Inc.