00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef MOD_REWRITE_H
00018 #define MOD_REWRITE_H 1
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 #include "apr.h"
00054
00055 #define APR_WANT_STRFUNC
00056 #define APR_WANT_MEMFUNC
00057 #include "apr_want.h"
00058
00059
00060 #if APR_HAVE_STDARG_H
00061 #include <stdarg.h>
00062 #endif
00063 #if APR_HAVE_STDLIB_H
00064 #include <stdlib.h>
00065 #endif
00066 #if APR_HAVE_CTYPE_H
00067 #include <ctype.h>
00068 #endif
00069 #if APR_HAVE_SYS_TYPES_H
00070 #include <sys/types.h>
00071 #endif
00072
00073 #if APR_HAS_THREADS
00074 #include "apr_thread_mutex.h"
00075 #endif
00076 #include "apr_optional.h"
00077 #include "apr_dbm.h"
00078 #include "ap_config.h"
00079
00080
00081 #define CORE_PRIVATE
00082 #include "httpd.h"
00083 #include "http_config.h"
00084 #include "http_request.h"
00085 #include "http_core.h"
00086 #include "http_log.h"
00087 #include "http_vhost.h"
00088
00089
00090
00091
00092
00093 #define VARY_KEY "rewrite-Vary"
00094 #define VARY_KEY_THIS "rewrite-Vary-this"
00095
00096
00097
00098
00099
00100
00101
00102 #define ENVVAR_SCRIPT_URL "SCRIPT_URL"
00103 #define ENVVAR_SCRIPT_URI "SCRIPT_URI"
00104
00105 #define REWRITE_FORCED_MIMETYPE_NOTEVAR "rewrite-forced-mimetype"
00106
00107 #define CONDFLAG_NONE 1<<0
00108 #define CONDFLAG_NOCASE 1<<1
00109 #define CONDFLAG_NOTMATCH 1<<2
00110 #define CONDFLAG_ORNEXT 1<<3
00111
00112 #define RULEFLAG_NONE 1<<0
00113 #define RULEFLAG_FORCEREDIRECT 1<<1
00114 #define RULEFLAG_LASTRULE 1<<2
00115 #define RULEFLAG_NEWROUND 1<<3
00116 #define RULEFLAG_CHAIN 1<<4
00117 #define RULEFLAG_IGNOREONSUBREQ 1<<5
00118 #define RULEFLAG_NOTMATCH 1<<6
00119 #define RULEFLAG_PROXY 1<<7
00120 #define RULEFLAG_PASSTHROUGH 1<<8
00121 #define RULEFLAG_FORBIDDEN 1<<9
00122 #define RULEFLAG_GONE 1<<10
00123 #define RULEFLAG_QSAPPEND 1<<11
00124 #define RULEFLAG_NOCASE 1<<12
00125 #define RULEFLAG_NOESCAPE 1<<13
00126
00127 #define ACTION_NORMAL 1<<0
00128 #define ACTION_NOESCAPE 1<<1
00129
00130 #define MAPTYPE_TXT 1<<0
00131 #define MAPTYPE_DBM 1<<1
00132 #define MAPTYPE_PRG 1<<2
00133 #define MAPTYPE_INT 1<<3
00134 #define MAPTYPE_RND 1<<4
00135
00136 #define ENGINE_DISABLED 1<<0
00137 #define ENGINE_ENABLED 1<<1
00138
00139 #define OPTION_NONE 1<<0
00140 #define OPTION_INHERIT 1<<1
00141
00142 #define CACHEMODE_TS 1<<0
00143 #define CACHEMODE_TTL 1<<1
00144
00145 #define CACHE_TLB_ROWS 1024
00146 #define CACHE_TLB_COLS 4
00147
00148 #ifndef FALSE
00149 #define FALSE 0
00150 #define TRUE !FALSE
00151 #endif
00152
00153 #ifndef NO
00154 #define NO FALSE
00155 #define YES TRUE
00156 #endif
00157
00158 #ifndef RAND_MAX
00159 #define RAND_MAX 32767
00160 #endif
00161
00162 #ifndef LONG_STRING_LEN
00163 #define LONG_STRING_LEN 2048
00164 #endif
00165
00166 #define MAX_ENV_FLAGS 15
00167 #define MAX_COOKIE_FLAGS 15
00168
00169 #define MAX_COOKIE_LEN 4096
00170
00171
00172 #define REWRITE_REDIRECT_LIMIT 10
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184 typedef struct {
00185 const char *name;
00186 const char *datafile;
00187 const char *dbmtype;
00188 const char *checkfile;
00189 int type;
00190 apr_file_t *fpin;
00191 apr_file_t *fpout;
00192 apr_file_t *fperr;
00193 char *(*func)(request_rec *,
00194 char *);
00195 char **argv;
00196 char *cachename;
00197 } rewritemap_entry;
00198
00199 typedef struct {
00200 char *input;
00201 char *pattern;
00202 regex_t *regexp;
00203 int flags;
00204 } rewritecond_entry;
00205
00206 typedef struct {
00207 apr_array_header_t *rewriteconds;
00208 char *pattern;
00209 regex_t *regexp;
00210 char *output;
00211 int flags;
00212 char *forced_mimetype;
00213 int forced_responsecode;
00214 char *env[MAX_ENV_FLAGS+1];
00215 char *cookie[MAX_COOKIE_FLAGS+1];
00216 int skip;
00217 } rewriterule_entry;
00218
00219
00220
00221
00222
00223 typedef struct {
00224 int state;
00225 int options;
00226 const char *rewritelogfile;
00227 apr_file_t *rewritelogfp;
00228 int rewriteloglevel;
00229 apr_array_header_t *rewritemaps;
00230 apr_array_header_t *rewriteconds;
00231 apr_array_header_t *rewriterules;
00232 server_rec *server;
00233 int redirect_limit;
00234 } rewrite_server_conf;
00235
00236
00237
00238
00239
00240 typedef struct {
00241 int state;
00242 int options;
00243 apr_array_header_t *rewriteconds;
00244 apr_array_header_t *rewriterules;
00245 char *directory;
00246 const char *baseurl;
00247 int redirect_limit;
00248 } rewrite_perdir_conf;
00249
00250
00251
00252
00253 typedef struct {
00254 int redirects;
00255 int redirect_limit;
00256 } rewrite_request_conf;
00257
00258
00259
00260
00261
00262 typedef struct cacheentry {
00263 apr_time_t time;
00264 char *key;
00265 char *value;
00266 } cacheentry;
00267
00268 typedef struct tlbentry {
00269 int t[CACHE_TLB_COLS];
00270 } cachetlbentry;
00271
00272 typedef struct cachelist {
00273 char *resource;
00274 apr_array_header_t *entries;
00275 apr_array_header_t *tlb;
00276 } cachelist;
00277
00278 typedef struct cache {
00279 apr_pool_t *pool;
00280 apr_array_header_t *lists;
00281 #if APR_HAS_THREADS
00282 apr_thread_mutex_t *lock;
00283 #endif
00284 } cache;
00285
00286
00287
00288
00289
00290 typedef struct backrefinfo {
00291 char *source;
00292 int nsub;
00293 regmatch_t regmatch[AP_MAX_REG_MATCH];
00294 } backrefinfo;
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304 static void *config_server_create(apr_pool_t *p, server_rec *s);
00305 static void *config_server_merge (apr_pool_t *p, void *basev, void *overridesv);
00306 static void *config_perdir_create(apr_pool_t *p, char *path);
00307 static void *config_perdir_merge (apr_pool_t *p, void *basev, void *overridesv);
00308
00309
00310 static const char *cmd_rewriteengine(cmd_parms *cmd,
00311 void *dconf, int flag);
00312 static const char *cmd_rewriteoptions(cmd_parms *cmd,
00313 void *dconf,
00314 const char *option);
00315 static const char *cmd_rewritelog (cmd_parms *cmd, void *dconf, const char *a1);
00316 static const char *cmd_rewriteloglevel(cmd_parms *cmd, void *dconf, const char *a1);
00317 static const char *cmd_rewritemap (cmd_parms *cmd, void *dconf,
00318 const char *a1, const char *a2);
00319 static const char *cmd_rewritelock(cmd_parms *cmd, void *dconf, const char *a1);
00320 static const char *cmd_rewritebase(cmd_parms *cmd, void *dconf,
00321 const char *a1);
00322 static const char *cmd_rewritecond(cmd_parms *cmd, void *dconf,
00323 const char *str);
00324 static const char *cmd_rewritecond_parseflagfield(apr_pool_t *p,
00325 rewritecond_entry *new,
00326 char *str);
00327 static const char *cmd_rewritecond_setflag(apr_pool_t *p, rewritecond_entry *cfg,
00328 char *key, char *val);
00329 static const char *cmd_rewriterule(cmd_parms *cmd, void *dconf,
00330 const char *str);
00331 static const char *cmd_rewriterule_parseflagfield(apr_pool_t *p,
00332 rewriterule_entry *new,
00333 char *str);
00334 static const char *cmd_rewriterule_setflag(apr_pool_t *p, rewriterule_entry *cfg,
00335 char *key, char *val);
00336
00337
00338 static int pre_config(apr_pool_t *pconf,
00339 apr_pool_t *plog,
00340 apr_pool_t *ptemp);
00341 static int post_config(apr_pool_t *pconf,
00342 apr_pool_t *plog,
00343 apr_pool_t *ptemp,
00344 server_rec *s);
00345 static void init_child(apr_pool_t *p, server_rec *s);
00346
00347
00348 static int hook_uri2file (request_rec *r);
00349 static int hook_mimetype (request_rec *r);
00350 static int hook_fixup (request_rec *r);
00351 static int handler_redirect(request_rec *r);
00352
00353
00354 static int apply_rewrite_list(request_rec *r, apr_array_header_t *rewriterules,
00355 char *perdir);
00356 static int apply_rewrite_rule(request_rec *r, rewriterule_entry *p,
00357 char *perdir);
00358 static int apply_rewrite_cond(request_rec *r, rewritecond_entry *p,
00359 char *perdir, backrefinfo *briRR,
00360 backrefinfo *briRC);
00361
00362 static void do_expand(request_rec *r, char *input, char *buffer, int nbuf,
00363 backrefinfo *briRR, backrefinfo *briRC);
00364 static void do_expand_env(request_rec *r, char *env[],
00365 backrefinfo *briRR, backrefinfo *briRC);
00366 static void do_expand_cookie(request_rec *r, char *cookie[],
00367 backrefinfo *briRR, backrefinfo *briRC);
00368
00369
00370 static void splitout_queryargs(request_rec *r, int qsappend);
00371 static void fully_qualify_uri(request_rec *r);
00372 static void reduce_uri(request_rec *r);
00373 static unsigned is_absolute_uri(char *uri);
00374 static char *escape_absolute_uri(apr_pool_t *p, char *uri, unsigned scheme);
00375 static char *expand_tildepaths(request_rec *r, char *uri);
00376
00377
00378 static char *lookup_map(request_rec *r, char *name, char *key);
00379 static char *lookup_map_txtfile(request_rec *r, const char *file, char *key);
00380 static char *lookup_map_dbmfile(request_rec *r, const char *file,
00381 const char *dbmtype, char *key);
00382 static char *lookup_map_program(request_rec *r, apr_file_t *fpin,
00383 apr_file_t *fpout, char *key);
00384
00385 typedef char *(rewrite_mapfunc_t)(request_rec *r, char *key);
00386 static void ap_register_rewrite_mapfunc(char *name, rewrite_mapfunc_t *func);
00387 APR_DECLARE_OPTIONAL_FN(void, ap_register_rewrite_mapfunc,
00388 (char *name, rewrite_mapfunc_t *func));
00389
00390 static char *rewrite_mapfunc_toupper(request_rec *r, char *key);
00391 static char *rewrite_mapfunc_tolower(request_rec *r, char *key);
00392 static char *rewrite_mapfunc_escape(request_rec *r, char *key);
00393 static char *rewrite_mapfunc_unescape(request_rec *r, char *key);
00394
00395 static char *select_random_value_part(request_rec *r, char *value);
00396 static void rewrite_rand_init(void);
00397 static int rewrite_rand(int l, int h);
00398
00399
00400 static int open_rewritelog(server_rec *s, apr_pool_t *p);
00401 static void rewritelog(request_rec *r, int level, const char *text, ...)
00402 __attribute__((format(printf,3,4)));
00403 static char *current_logtime(request_rec *r);
00404
00405
00406 static apr_status_t rewritelock_create(server_rec *s, apr_pool_t *p);
00407 static apr_status_t rewritelock_remove(void *data);
00408
00409
00410 static apr_status_t run_rewritemap_programs(server_rec *s, apr_pool_t *p);
00411 static apr_status_t rewritemap_program_child(apr_pool_t *p,
00412 const char *progname, char **argv,
00413 apr_file_t **fpout,
00414 apr_file_t **fpin);
00415
00416
00417 static char *lookup_variable(request_rec *r, char *var);
00418 static char *lookup_header(request_rec *r, const char *name);
00419
00420
00421 static cache *init_cache(apr_pool_t *p);
00422 static char *get_cache_string(cache *c, const char *res, int mode, apr_time_t mtime,
00423 char *key);
00424 static void set_cache_string(cache *c, const char *res, int mode, apr_time_t mtime,
00425 char *key, char *value);
00426 static cacheentry *retrieve_cache_string(cache *c, const char *res, char *key);
00427 static void store_cache_string(cache *c, const char *res, cacheentry *ce);
00428
00429
00430 static char *subst_prefix_path(request_rec *r, char *input, char *match,
00431 const char *subst);
00432 static int parseargline(char *str, char **a1, char **a2, char **a3);
00433 static int prefix_stat(const char *path, apr_pool_t *pool);
00434 static void add_env_variable(request_rec *r, char *s);
00435 static void add_cookie(request_rec *r, char *s);
00436 static int subreq_ok(request_rec *r);
00437 static int is_redirect_limit_exceeded(request_rec *r);
00438
00439
00440 static int compare_lexicography(char *cpNum1, char *cpNum2);
00441
00442
00443 static char *find_closing_bracket(char *s, int left, int right);
00444 static char *find_char_in_brackets(char *s, int c, int left, int right);
00445
00446 #endif