Apache HTTPD
mod_cern_meta.c
Go to the documentation of this file.
1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/*
18 * mod_cern_meta.c
19 * version 0.1.0
20 * status beta
21 *
22 * Andrew Wilson <[email protected]> 25.Jan.96
23 *
24 * *** IMPORTANT ***
25 * This version of mod_cern_meta.c controls Meta File behaviour on a
26 * per-directory basis. Previous versions of the module defined behaviour
27 * on a per-server basis. The upshot is that you'll need to revisit your
28 * configuration files in order to make use of the new module.
29 * ***
30 *
31 * Emulate the CERN HTTPD Meta file semantics. Meta files are HTTP
32 * headers that can be output in addition to the normal range of
33 * headers for each file accessed. They appear rather like the Apache
34 * .asis files, and are able to provide a crude way of influencing
35 * the Expires: header, as well as providing other curiosities.
36 * There are many ways to manage meta information, this one was
37 * chosen because there is already a large number of CERN users
38 * who can exploit this module. It should be noted that there are probably
39 * more sensitive ways of managing the Expires: header specifically.
40 *
41 * The module obeys the following directives, which can appear
42 * in the server's .conf files and in .htaccess files.
43 *
44 * MetaFiles <on|off>
45 *
46 * turns on|off meta file processing for any directory.
47 * Default value is off
48 *
49 * # turn on MetaFiles in this directory
50 * MetaFiles on
51 *
52 * MetaDir <directory name>
53 *
54 * specifies the name of the directory in which Apache can find
55 * meta information files. The directory is usually a 'hidden'
56 * subdirectory of the directory that contains the file being
57 * accessed. eg:
58 *
59 * # .meta files are in the *same* directory as the
60 * # file being accessed
61 * MetaDir .
62 *
63 * the default is to look in a '.web' subdirectory. This is the
64 * same as for CERN 3.+ webservers and behaviour is the same as
65 * for the directive:
66 *
67 * MetaDir .web
68 *
69 * MetaSuffix <meta file suffix>
70 *
71 * specifies the file name suffix for the file containing the
72 * meta information. eg:
73 *
74 * # our meta files are suffixed with '.cern_meta'
75 * MetaSuffix .cern_meta
76 *
77 * the default is to look for files with the suffix '.meta'. This
78 * behaviour is the same as for the directive:
79 *
80 * MetaSuffix .meta
81 *
82 * When accessing the file
83 *
84 * DOCUMENT_ROOT/somedir/index.html
85 *
86 * this module will look for the file
87 *
88 * DOCUMENT_ROOT/somedir/.web/index.html.meta
89 *
90 * and will use its contents to generate additional MIME header
91 * information.
92 *
93 * For more information on the CERN Meta file semantics see:
94 *
95 * http://www.w3.org/hypertext/WWW/Daemon/User/Config/General.html#MetaDir
96 *
97 * Change-log:
98 * 29.Jan.96 pfopen/pfclose instead of fopen/fclose
99 * DECLINE when real file not found, we may be checking each
100 * of the index.html/index.shtml/index.htm variants and don't
101 * need to report missing ones as spurious errors.
102 * 31.Jan.96 log_error reports about a malformed .meta file, rather
103 * than a script error.
104 * 20.Jun.96 MetaFiles <on|off> default off, added, so that module
105 * can be configured per-directory. Prior to this the module
106 * was running for each request anywhere on the server, naughty..
107 * 29.Jun.96 All directives made per-directory.
108 */
109
110#include "apr.h"
111#include "apr_strings.h"
112
113#define APR_WANT_STRFUNC
114#include "apr_want.h"
115
116#if APR_HAVE_SYS_TYPES_H
117#include <sys/types.h>
118#endif
119
120#include "ap_config.h"
121#include "httpd.h"
122#include "http_config.h"
123#include "util_script.h"
124#include "http_log.h"
125#include "http_request.h"
126#include "http_protocol.h"
127#include "apr_lib.h"
128
129#define DIR_CMD_PERMS OR_INDEXES
130
131#define DEFAULT_METADIR ".web"
132#define DEFAULT_METASUFFIX ".meta"
133#define DEFAULT_METAFILES 0
134
135module AP_MODULE_DECLARE_DATA cern_meta_module;
136
137typedef struct {
138 const char *metadir;
139 const char *metasuffix;
142
144{
147
148 new->metadir = NULL;
149 new->metasuffix = NULL;
150 new->metafiles = DEFAULT_METAFILES;
151
152 return new;
153}
154
156{
161
162 new->metadir = add->metadir ? add->metadir : base->metadir;
163 new->metasuffix = add->metasuffix ? add->metasuffix : base->metasuffix;
164 new->metafiles = add->metafiles;
165
166 return new;
167}
168
169static const char *set_metadir(cmd_parms *parms, void *in_dconf, const char *arg)
170{
172
173 dconf->metadir = arg;
174 return NULL;
175}
176
177static const char *set_metasuffix(cmd_parms *parms, void *in_dconf, const char *arg)
178{
180
181 dconf->metasuffix = arg;
182 return NULL;
183}
184
185static const char *set_metafiles(cmd_parms *parms, void *in_dconf, int arg)
186{
188
189 dconf->metafiles = arg;
190 return NULL;
191}
192
193
195{
197 "Limited to 'on' or 'off'"),
199 "the name of the directory containing meta files"),
201 "the filename suffix for meta files"),
202 {NULL}
203};
204
205/* XXX: this is very similar to ap_scan_script_header_err_core...
206 * are the differences deliberate, or just a result of bit rot?
207 */
209{
210 char w[MAX_STRING_LEN];
211 char *l;
212 int p;
214
216 while (apr_file_gets(w, MAX_STRING_LEN - 1, f) == APR_SUCCESS) {
217
218 /* Delete terminal (CR?)LF */
219 p = strlen(w);
220 if (p > 0 && w[p - 1] == '\n') {
221 if (p > 1 && w[p - 2] == '\015')
222 w[p - 2] = '\0';
223 else
224 w[p - 1] = '\0';
225 }
226
227 if (w[0] == '\0') {
228 return OK;
229 }
230
231 /* if we see a bogus header don't ignore it. Shout and scream */
232
233 if (!(l = strchr(w, ':'))) {
235 "malformed header in meta file: %s", r->filename);
237 }
238
239 *l++ = '\0';
240 while (apr_isspace(*l))
241 ++l;
242
243 if (!ap_cstr_casecmp(w, "Content-type")) {
244 char *tmp;
245 /* Nuke trailing whitespace */
246
247 char *endp = l + strlen(l) - 1;
248 while (endp > l && apr_isspace(*endp))
249 *endp-- = '\0';
250
251 tmp = apr_pstrdup(r->pool, l);
254 }
255 else if (!ap_cstr_casecmp(w, "Status")) {
256 sscanf(l, "%d", &r->status);
258 }
259 else {
261 }
262 }
264 return OK;
265}
266
268{
269 char *metafilename;
270 char *leading_slash;
271 char *last_slash;
272 char *real_file;
273 char *scrap_book;
274 apr_file_t *f = NULL;
277 int rv;
279
280 dconf = ap_get_module_config(r->per_dir_config, &cern_meta_module);
281
282 if (!dconf->metafiles) {
283 return DECLINED;
284 }
285
286 /* if ./.web/$1.meta exists then output 'asis' */
287
288 if (r->finfo.filetype == APR_NOFILE) {
289 return DECLINED;
290 }
291
292 /* is this a directory? */
293 if (r->finfo.filetype == APR_DIR || r->uri[strlen(r->uri) - 1] == '/') {
294 return DECLINED;
295 }
296
297 /* what directory is this file in? */
299
302 if ((last_slash != NULL) && (last_slash != leading_slash)) {
303 /* skip over last slash */
305 real_file++;
306 *last_slash = '\0';
307 }
308 else {
309 /* no last slash, buh?! */
311 "internal error in mod_cern_meta: %s", r->filename);
312 /* should really barf, but hey, let's be friends... */
313 return DECLINED;
314 }
315
317 dconf->metadir ? dconf->metadir : DEFAULT_METADIR,
318 "/", real_file,
319 dconf->metasuffix ? dconf->metasuffix : DEFAULT_METASUFFIX,
320 NULL);
321
322 /* It sucks to require this subrequest to complete, because this
323 * means people must leave their meta files accessible to the world.
324 * A better solution might be a "safe open" feature of pfopen to avoid
325 * pipes, symlinks, and crap like that.
326 *
327 * In fact, this doesn't suck. Because <Location > blocks are never run
328 * against sub_req_lookup_file, the meta can be somewhat protected by
329 * either masking it with a <Location > directive or alias, or stowing
330 * the file outside of the web document tree, while providing the
331 * appropriate directory blocks to allow access to it as a file.
332 */
334 if (rr->status != HTTP_OK) {
336 return DECLINED;
337 }
339
341 if (retcode != APR_SUCCESS) {
343 return DECLINED;
344 }
346 "meta file permissions deny server access: %s", metafilename);
347 return HTTP_FORBIDDEN;
348 }
349
350 /* read the headers in */
351 rv = scan_meta_file(r, f);
353
354 return rv;
355}
356
361
363{
365 create_cern_meta_dir_config, /* dir config creater */
366 merge_cern_meta_dir_configs, /* dir merger --- default is to override */
367 NULL, /* server config */
368 NULL, /* merge server configs */
369 cern_meta_cmds, /* command apr_table_t */
370 register_hooks /* register hooks */
371};
Symbol export macros and hook functions.
APR general purpose library routines.
APR Strings library.
APR Standard Headers Support.
#define AP_INIT_TAKE1(directive, func, mconfig, where, help)
#define ap_get_module_config(v, m)
#define AP_DECLARE_MODULE(foo)
#define AP_INIT_FLAG(directive, func, mconfig, where, help)
ap_conf_vector_t * base
request_rec * r
#define MAX_STRING_LEN
Definition httpd.h:300
#define DECLINED
Definition httpd.h:457
#define OK
Definition httpd.h:456
#define APLOGNO(n)
Definition http_log.h:117
#define ap_log_rerror
Definition http_log.h:454
#define APLOG_ERR
Definition http_log.h:67
#define APLOG_MARK
Definition http_log.h:283
void ap_set_content_type(request_rec *r, const char *ct)
request_rec * ap_sub_req_lookup_file(const char *new_file, const request_rec *r, ap_filter_t *next_filter)
Definition request.c:2433
void ap_hook_fixups(ap_HOOK_fixups_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
Definition request.c:87
void ap_destroy_sub_req(request_rec *r)
Definition request.c:2547
void * dummy
Definition http_vhost.h:62
void const char * arg
Definition http_vhost.h:63
#define APR_STATUS_IS_ENOENT(s)
Definition apr_errno.h:1246
apr_file_t * f
#define APR_HOOK_MIDDLE
Definition apr_hooks.h:303
#define HTTP_OK
Definition httpd.h:490
#define HTTP_INTERNAL_SERVER_ERROR
Definition httpd.h:535
#define HTTP_FORBIDDEN
Definition httpd.h:511
#define STANDARD20_MODULE_STUFF
int ap_cstr_casecmp(const char *s1, const char *s2)
Definition util.c:3542
void ap_content_type_tolower(char *s)
Definition util.c:2505
apr_size_t size
#define apr_isspace(c)
Definition apr_lib.h:225
#define APR_SUCCESS
Definition apr_errno.h:225
int apr_status_t
Definition apr_errno.h:44
@ APR_DIR
@ APR_NOFILE
#define APR_READ
Definition apr_file_io.h:93
#define APR_OS_DEFAULT
#define APR_OVERLAP_TABLES_SET
Definition apr_tables.h:437
Apache Configuration.
Apache Logging library.
HTTP protocol handling.
Apache Request library.
HTTP Daemon routines.
apr_pool_t * p
Definition md_event.c:32
static void * create_cern_meta_dir_config(apr_pool_t *p, char *dummy)
static int scan_meta_file(request_rec *r, apr_file_t *f)
static const char * set_metadir(cmd_parms *parms, void *in_dconf, const char *arg)
static const command_rec cern_meta_cmds[]
static const char * set_metafiles(cmd_parms *parms, void *in_dconf, int arg)
#define DEFAULT_METASUFFIX
static void register_hooks(apr_pool_t *p)
static int add_cern_meta_data(request_rec *r)
static const char * set_metasuffix(cmd_parms *parms, void *in_dconf, const char *arg)
#define DEFAULT_METADIR
#define DEFAULT_METAFILES
#define DIR_CMD_PERMS
static void * merge_cern_meta_dir_configs(apr_pool_t *p, void *basev, void *addv)
return NULL
Definition mod_so.c:359
apr_filetype_e filetype
const char * metasuffix
A structure that represents the current request.
Definition httpd.h:845
int status
Definition httpd.h:891
char * uri
Definition httpd.h:1016
apr_pool_t * pool
Definition httpd.h:847
char * filename
Definition httpd.h:1018
apr_finfo_t finfo
Definition httpd.h:1094
struct ap_conf_vector_t * per_dir_config
Definition httpd.h:1047
const char * status_line
Definition httpd.h:889
apr_table_t * headers_out
Definition httpd.h:978
Apache script tools.