home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1999 April / PCO0499.ISO / filesbbs / os2 / apach134.arj / APACH134.ZIP / src / modules / standard / mod_rewrite.h < prev    next >
Encoding:
C/C++ Source or Header  |  1999-01-01  |  17.6 KB  |  486 lines

  1. /* ====================================================================
  2.  * Copyright (c) 1996-1999 The Apache Group.  All rights reserved.
  3.  *
  4.  * Redistribution and use in source and binary forms, with or without
  5.  * modification, are permitted provided that the following conditions
  6.  * are met:
  7.  *
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  *
  11.  * 2. Redistributions in binary form must reproduce the above copyright
  12.  *    notice, this list of conditions and the following disclaimer in
  13.  *    the documentation and/or other materials provided with the
  14.  *    distribution.
  15.  *
  16.  * 3. All advertising materials mentioning features or use of this
  17.  *    software must display the following acknowledgment:
  18.  *    "This product includes software developed by the Apache Group
  19.  *    for use in the Apache HTTP server project (http://www.apache.org/)."
  20.  *
  21.  * 4. The names "Apache Server" and "Apache Group" must not be used to
  22.  *    endorse or promote products derived from this software without
  23.  *    prior written permission. For written permission, please contact
  24.  *    apache@apache.org.
  25.  *
  26.  * 5. Products derived from this software may not be called "Apache"
  27.  *    nor may "Apache" appear in their names without prior written
  28.  *    permission of the Apache Group.
  29.  *
  30.  * 6. Redistributions of any form whatsoever must retain the following
  31.  *    acknowledgment:
  32.  *    "This product includes software developed by the Apache Group
  33.  *    for use in the Apache HTTP server project (http://www.apache.org/)."
  34.  *
  35.  * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
  36.  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  37.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  38.  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
  39.  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  41.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  42.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  43.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  44.  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  45.  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  46.  * OF THE POSSIBILITY OF SUCH DAMAGE.
  47.  * ====================================================================
  48.  *
  49.  * This software consists of voluntary contributions made by many
  50.  * individuals on behalf of the Apache Group and was originally based
  51.  * on public domain software written at the National Center for
  52.  * Supercomputing Applications, University of Illinois, Urbana-Champaign.
  53.  * For more information on the Apache Group and the Apache HTTP server
  54.  * project, please see <http://www.apache.org/>.
  55.  *
  56.  */
  57.  
  58.  
  59. #ifndef _MOD_REWRITE_H
  60. #define _MOD_REWRITE_H 1
  61.  
  62. /*
  63. **                       _                            _ _
  64. **   _ __ ___   ___   __| |    _ __ _____      ___ __(_) |_ ___
  65. **  | '_ ` _ \ / _ \ / _` |   | '__/ _ \ \ /\ / / '__| | __/ _ \
  66. **  | | | | | | (_) | (_| |   | | |  __/\ V  V /| |  | | ||  __/
  67. **  |_| |_| |_|\___/ \__,_|___|_|  \___| \_/\_/ |_|  |_|\__\___|
  68. **                       |_____|
  69. **
  70. **  URL Rewriting Module
  71. **
  72. **  This module uses a rule-based rewriting engine (based on a
  73. **  regular-expression parser) to rewrite requested URLs on the fly.
  74. **
  75. **  It supports an unlimited number of additional rule conditions (which can
  76. **  operate on a lot of variables, even on HTTP headers) for granular
  77. **  matching and even external database lookups (either via plain text
  78. **  tables, DBM hash files or even external processes) for advanced URL
  79. **  substitution.
  80. **
  81. **  It operates on the full URLs (including the PATH_INFO part) both in
  82. **  per-server context (httpd.conf) and per-dir context (.htaccess) and even
  83. **  can generate QUERY_STRING parts on result.   The rewriting result finally
  84. **  can lead to internal subprocessing, external request redirection or even
  85. **  to internal proxy throughput.
  86. **
  87. **  This module was originally written in April 1996 and
  88. **  gifted exclusively to the The Apache Group in July 1997 by
  89. **
  90. **      Ralf S. Engelschall
  91. **      rse@engelschall.com
  92. **      www.engelschall.com
  93. */
  94.  
  95.  
  96.     /* Include from the underlaying Unix system ... */
  97. #include <string.h>
  98. #include <stdarg.h>
  99. #include <stdlib.h>
  100. #include <time.h>
  101. #include <signal.h>
  102. #include <errno.h>
  103. #include <ctype.h>
  104. #include <sys/types.h>
  105. #include <sys/stat.h>
  106.  
  107.     /* Include from the Apache server ... */
  108. #include "httpd.h"
  109. #include "http_config.h"
  110. #include "http_conf_globals.h"
  111. #include "http_request.h"
  112. #include "http_core.h"
  113. #include "http_log.h"
  114. #include "http_vhost.h"
  115.  
  116.     /*
  117.      * The key in the r->notes table wherein we store our accumulated
  118.      * Vary values, and the one used for per-condition checks in a chain.
  119.      */
  120. #define VARY_KEY "rewrite-Vary"
  121. #define VARY_KEY_THIS "rewrite-Vary-this"
  122.  
  123.     /* The NDBM support:
  124.      * We support only NDBM files.
  125.      * But we have to stat the file for the mtime,
  126.      * so we also need to know the file extension
  127.      */
  128. #ifndef NO_DBM_REWRITEMAP
  129. #include <ndbm.h>
  130. #if (__FreeBSD__)
  131. #define NDBM_FILE_SUFFIX ".db"
  132. #else
  133. #define NDBM_FILE_SUFFIX ".pag"
  134. #endif
  135. #endif
  136.  
  137.  
  138.     /* The locking support:
  139.      * Try to determine whether we should use fcntl() or flock().
  140.      * Would be better ap_config.h could provide this... :-(
  141.      */
  142. #if defined(USE_FCNTL_SERIALIZED_ACCEPT)
  143. #define USE_FCNTL 1
  144. #include <fcntl.h>
  145. #endif
  146. #if defined(USE_FLOCK_SERIALIZED_ACCEPT)
  147. #define USE_FLOCK 1
  148. #include <sys/file.h>
  149. #endif
  150. #if !defined(USE_FCNTL) && !defined(USE_FLOCK)
  151. #define USE_FLOCK 1
  152. #if !defined(MPE) && !defined(WIN32)
  153. #include <sys/file.h>
  154. #endif
  155. #ifndef LOCK_UN
  156. #undef USE_FLOCK
  157. #define USE_FCNTL 1
  158. #include <fcntl.h>
  159. #endif
  160. #endif
  161. #ifdef AIX
  162. #undef USE_FLOCK
  163. #define USE_FCNTL 1
  164. #include <fcntl.h>
  165. #endif
  166. #ifdef WIN32
  167. #undef USE_FCNTL
  168. #define USE_LOCKING
  169. #include <sys/locking.h>
  170. #endif
  171.  
  172.  
  173. /*
  174. **
  175. **  Some defines
  176. **
  177. */
  178.  
  179. #define ENVVAR_SCRIPT_URL "SCRIPT_URL"
  180. #define ENVVAR_SCRIPT_URI "SCRIPT_URI"
  181.  
  182. #ifndef SUPPORT_DBM_REWRITEMAP
  183. #define SUPPORT_DBM_REWRITEMAP 0
  184. #endif
  185.  
  186. #define REWRITE_FORCED_MIMETYPE_NOTEVAR "rewrite-forced-mimetype"
  187.  
  188. #define CONDFLAG_NONE               1<<0
  189. #define CONDFLAG_NOCASE             1<<1
  190. #define CONDFLAG_NOTMATCH           1<<2
  191. #define CONDFLAG_ORNEXT             1<<3
  192.  
  193. #define RULEFLAG_NONE               1<<0
  194. #define RULEFLAG_FORCEREDIRECT      1<<1
  195. #define RULEFLAG_LASTRULE           1<<2
  196. #define RULEFLAG_NEWROUND           1<<3
  197. #define RULEFLAG_CHAIN              1<<4
  198. #define RULEFLAG_IGNOREONSUBREQ     1<<5
  199. #define RULEFLAG_NOTMATCH           1<<6
  200. #define RULEFLAG_PROXY              1<<7
  201. #define RULEFLAG_PASSTHROUGH        1<<8
  202. #define RULEFLAG_FORBIDDEN          1<<9
  203. #define RULEFLAG_GONE               1<<10
  204. #define RULEFLAG_QSAPPEND           1<<11
  205. #define RULEFLAG_NOCASE             1<<12
  206.  
  207. #define MAPTYPE_TXT                 1<<0
  208. #define MAPTYPE_DBM                 1<<1
  209. #define MAPTYPE_PRG                 1<<2
  210. #define MAPTYPE_INT                 1<<3
  211. #define MAPTYPE_RND                 1<<4
  212.  
  213. #define ENGINE_DISABLED             1<<0
  214. #define ENGINE_ENABLED              1<<1
  215.  
  216. #define OPTION_NONE                 1<<0
  217. #define OPTION_INHERIT              1<<1
  218.  
  219. #define CACHEMODE_TS                1<<0
  220. #define CACHEMODE_TTL               1<<1
  221.  
  222. #ifndef FALSE
  223. #define FALSE 0
  224. #define TRUE  !FALSE
  225. #endif
  226.  
  227. #ifndef NO
  228. #define NO    FALSE
  229. #define YES   TRUE
  230. #endif
  231.  
  232. #ifndef RAND_MAX
  233. #define RAND_MAX 32767
  234. #endif
  235.  
  236. #ifndef LONG_STRING_LEN
  237. #define LONG_STRING_LEN 2048
  238. #endif
  239.  
  240. #define MAX_ENV_FLAGS 15
  241.  
  242. #define MAX_NMATCH    10
  243.  
  244. #define MAPFILE_PATTERN "^([^ \t]+)[ \t]+([^ \t]+).*$"
  245. #define MAPFILE_OUTPUT  "$1,$2"
  246.  
  247.  
  248. /*
  249. **
  250. **  our private data structures we handle with
  251. **
  252. */
  253.  
  254.     /* the list structures for holding the mapfile information
  255.      * and the rewrite rules
  256.      */
  257. typedef struct {
  258.     char *name;                    /* the name of the map */
  259.     char *datafile;                /* filename for map data files */
  260.     char *checkfile;               /* filename to check for map existence */
  261.     int   type;                    /* the type of the map */
  262.     int   fpin;                    /* in  file pointer for program maps */
  263.     int   fpout;                   /* out file pointer for program maps */
  264.     int   fperr;                   /* err file pointer for program maps */
  265.     char *(*func)(request_rec *,   /* function pointer for internal maps */
  266.                   char *);
  267. } rewritemap_entry;
  268.  
  269. typedef struct {
  270.     char    *input;                /* Input string of RewriteCond */
  271.     char    *pattern;              /* the RegExp pattern string */
  272.     regex_t *regexp;
  273.     int      flags;                /* Flags which control the match */
  274. } rewritecond_entry;
  275.  
  276. typedef struct {
  277.     array_header *rewriteconds;    /* the corresponding RewriteCond entries */
  278.     char    *pattern;              /* the RegExp pattern string */
  279.     regex_t *regexp;               /* the RegExp pattern compilation */
  280.     char    *output;               /* the Substitution string */
  281.     int      flags;                /* Flags which control the substitution */
  282.     char    *forced_mimetype;      /* forced MIME type of substitution */
  283.     int      forced_responsecode;  /* forced HTTP redirect response status */
  284.     char    *env[MAX_ENV_FLAGS+1]; /* added environment variables */
  285.     int      skip;                 /* number of next rules to skip */
  286. } rewriterule_entry;
  287.  
  288.  
  289.     /* the per-server or per-virtual-server configuration
  290.      * statically generated once on startup for every server
  291.      */
  292. typedef struct {
  293.     int           state;           /* the RewriteEngine state */
  294.     int           options;         /* the RewriteOption state */
  295.     char         *rewritelogfile;  /* the RewriteLog filename */
  296.     int           rewritelogfp;    /* the RewriteLog open filepointer */
  297.     int           rewriteloglevel; /* the RewriteLog level of verbosity */
  298.     char         *rewritelockfile; /* the RewriteLock filename */
  299.     int           rewritelockfp;   /* the RewriteLock open filepointer */
  300.     array_header *rewritemaps;     /* the RewriteMap entries */
  301.     array_header *rewriteconds;    /* the RewriteCond entries (temporary) */
  302.     array_header *rewriterules;    /* the RewriteRule entries */
  303.     server_rec   *server;          /* the corresponding server indicator */
  304. } rewrite_server_conf;
  305.  
  306.  
  307.     /* the per-directory configuration
  308.      * generated on-the-fly by Apache server for current request
  309.      */
  310. typedef struct {
  311.     int           state;           /* the RewriteEngine state */
  312.     int           options;         /* the RewriteOption state */
  313.     array_header *rewriteconds;    /* the RewriteCond entries (temporary) */
  314.     array_header *rewriterules;    /* the RewriteRule entries */
  315.     char         *directory;       /* the directory where it applies */
  316.     char         *baseurl;         /* the base-URL  where it applies */
  317. } rewrite_perdir_conf;
  318.  
  319.  
  320.     /* the cache structures */
  321.  
  322. typedef struct cacheentry {
  323.     time_t time;
  324.     char  *key;
  325.     char  *value;
  326. } cacheentry;
  327.  
  328. typedef struct cachelist {
  329.     char         *resource;
  330.     array_header *entries;
  331. } cachelist;
  332.  
  333. typedef struct cache {
  334.     pool         *pool;
  335.     array_header *lists;
  336. } cache;
  337.  
  338.     /* the regex structure for the
  339.        substitution of backreferences */
  340.  
  341. typedef struct backrefinfo {
  342.     char *source;
  343.     int nsub;
  344.     regmatch_t regmatch[10];
  345. } backrefinfo;
  346.  
  347.  
  348. /*
  349. **
  350. **  forward declarations
  351. **
  352. */
  353.  
  354.     /* config structure handling */
  355. static void *config_server_create(pool *p, server_rec *s);
  356. static void *config_server_merge (pool *p, void *basev, void *overridesv);
  357. static void *config_perdir_create(pool *p, char *path);
  358. static void *config_perdir_merge (pool *p, void *basev, void *overridesv);
  359.  
  360.     /* config directive handling */
  361. static const char *cmd_rewriteengine(cmd_parms *cmd,
  362.                                      rewrite_perdir_conf *dconf, int flag);
  363. static const char *cmd_rewriteoptions(cmd_parms *cmd,
  364.                                       rewrite_perdir_conf *dconf,
  365.                                       char *option);
  366. static const char *cmd_rewriteoptions_setoption(pool *p, int *options,
  367.                                                 char *name);
  368. static const char *cmd_rewritelog     (cmd_parms *cmd, void *dconf, char *a1);
  369. static const char *cmd_rewriteloglevel(cmd_parms *cmd, void *dconf, char *a1);
  370. static const char *cmd_rewritemap     (cmd_parms *cmd, void *dconf, char *a1,
  371.                                        char *a2);
  372. static const char *cmd_rewritelock(cmd_parms *cmd, void *dconf, char *a1);
  373. static const char *cmd_rewritebase(cmd_parms *cmd, rewrite_perdir_conf *dconf,
  374.                                    char *a1);
  375. static const char *cmd_rewritecond(cmd_parms *cmd, rewrite_perdir_conf *dconf,
  376.                                    char *str);
  377. static const char *cmd_rewritecond_parseflagfield(pool *p,
  378.                                                   rewritecond_entry *new,
  379.                                                   char *str);
  380. static const char *cmd_rewritecond_setflag(pool *p, rewritecond_entry *cfg,
  381.                                            char *key, char *val);
  382. static const char *cmd_rewriterule(cmd_parms *cmd, rewrite_perdir_conf *dconf,
  383.                                    char *str);
  384. static const char *cmd_rewriterule_parseflagfield(pool *p,
  385.                                                   rewriterule_entry *new,
  386.                                                   char *str);
  387. static const char *cmd_rewriterule_setflag(pool *p, rewriterule_entry *cfg,
  388.                                            char *key, char *val);
  389.  
  390.     /* initialisation */
  391. static void init_module(server_rec *s, pool *p);
  392. static void init_child(server_rec *s, pool *p);
  393.  
  394.     /* runtime hooks */
  395. static int hook_uri2file   (request_rec *r);
  396. static int hook_mimetype   (request_rec *r);
  397. static int hook_fixup      (request_rec *r);
  398. static int handler_redirect(request_rec *r);
  399.  
  400.     /* rewriting engine */
  401. static int apply_rewrite_list(request_rec *r, array_header *rewriterules,
  402.                               char *perdir);
  403. static int apply_rewrite_rule(request_rec *r, rewriterule_entry *p,
  404.                               char *perdir);
  405. static int apply_rewrite_cond(request_rec *r, rewritecond_entry *p,
  406.                               char *perdir, backrefinfo *briRR,
  407.                               backrefinfo *briRC);
  408.  
  409.     /* URI transformation function */
  410. static void  splitout_queryargs(request_rec *r, int qsappend);
  411. static void  fully_qualify_uri(request_rec *r);
  412. static void  reduce_uri(request_rec *r);
  413. static void  expand_backref_inbuffer(pool *p, char *buf, int nbuf,
  414.                                      backrefinfo *bri, char c);
  415. static char *expand_tildepaths(request_rec *r, char *uri);
  416. static void  expand_map_lookups(request_rec *r, char *uri, int uri_len);
  417.  
  418.     /* rewrite map support functions */
  419. static char *lookup_map(request_rec *r, char *name, char *key);
  420. static char *lookup_map_txtfile(request_rec *r, char *file, char *key);
  421. #ifndef NO_DBM_REWRITEMAP
  422. static char *lookup_map_dbmfile(request_rec *r, char *file, char *key);
  423. #endif
  424. static char *lookup_map_program(request_rec *r, int fpin,
  425.                                 int fpout, char *key);
  426. static char *lookup_map_internal(request_rec *r,
  427.                                  char *(*func)(request_rec *r, char *key),
  428.                                  char *key);
  429. static char *rewrite_mapfunc_toupper(request_rec *r, char *key);
  430. static char *rewrite_mapfunc_tolower(request_rec *r, char *key);
  431. static char *rewrite_mapfunc_escape(request_rec *r, char *key);
  432. static char *rewrite_mapfunc_unescape(request_rec *r, char *key);
  433. static char *select_random_value_part(request_rec *r, char *value);
  434. static void  rewrite_rand_init(void);
  435. static int   rewrite_rand(int l, int h);
  436.  
  437.     /* rewriting logfile support */
  438. static void  open_rewritelog(server_rec *s, pool *p);
  439. static void  rewritelog(request_rec *r, int level, const char *text, ...)
  440.                         __attribute__((format(printf,3,4)));
  441. static char *current_logtime(request_rec *r);
  442.  
  443.     /* rewriting lockfile support */
  444. static void rewritelock_create(server_rec *s, pool *p);
  445. static void rewritelock_open(server_rec *s, pool *p);
  446. static void rewritelock_remove(void *data);
  447. static void rewritelock_alloc(request_rec *r);
  448. static void rewritelock_free(request_rec *r);
  449.  
  450.     /* program map support */
  451. static void  run_rewritemap_programs(server_rec *s, pool *p);
  452. static int   rewritemap_program_child(void *cmd, child_info *pinfo);
  453.  
  454.     /* env variable support */
  455. static void  expand_variables_inbuffer(request_rec *r, char *buf, int buf_len);
  456. static char *expand_variables(request_rec *r, char *str);
  457. static char *lookup_variable(request_rec *r, char *var);
  458. static char *lookup_header(request_rec *r, const char *name);
  459.  
  460.     /* caching functions */
  461. static cache *init_cache(pool *p);
  462. static char  *get_cache_string(cache *c, char *res, int mode, time_t mtime,
  463.                                char *key);
  464. static void   set_cache_string(cache *c, char *res, int mode, time_t mtime,
  465.                                char *key, char *value);
  466. static cacheentry *retrieve_cache_string(cache *c, char *res, char *key);
  467. static void   store_cache_string(cache *c, char *res, cacheentry *ce);
  468.  
  469.     /* misc functions */
  470. static char  *subst_prefix_path(request_rec *r, char *input, char *match,
  471.                                 char *subst);
  472. static int    parseargline(char *str, char **a1, char **a2, char **a3);
  473. static int    prefix_stat(const char *path, struct stat *sb);
  474. static void   add_env_variable(request_rec *r, char *s);
  475.  
  476.     /* File locking */
  477. static void fd_lock(request_rec *r, int fd);
  478. static void fd_unlock(request_rec *r, int fd);
  479.  
  480.     /* Lexicographic Comparison */
  481. static int compare_lexicography(char *cpNum1, char *cpNum2);
  482.  
  483. #endif /* _MOD_REWRITE_H */
  484.  
  485. /*EOF*/
  486.