842ae4bd224140319ae7feec1872b93dfd491143fielding/* Licensed to the Apache Software Foundation (ASF) under one or more
842ae4bd224140319ae7feec1872b93dfd491143fielding * contributor license agreements. See the NOTICE file distributed with
842ae4bd224140319ae7feec1872b93dfd491143fielding * this work for additional information regarding copyright ownership.
842ae4bd224140319ae7feec1872b93dfd491143fielding * The ASF licenses this file to You under the Apache License, Version 2.0
842ae4bd224140319ae7feec1872b93dfd491143fielding * (the "License"); you may not use this file except in compliance with
842ae4bd224140319ae7feec1872b93dfd491143fielding * the License. You may obtain a copy of the License at
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding *
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * http://www.apache.org/licenses/LICENSE-2.0
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding *
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * Unless required by applicable law or agreed to in writing, software
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * distributed under the License is distributed on an "AS IS" BASIS,
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * See the License for the specific language governing permissions and
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * limitations under the License.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/*
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * mod_headers.c: Add/append/remove HTTP response headers
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * Written by Paul Sutton, paul@ukweb.com, 1 Oct 1996
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding *
ba4c566c200c2436dae841b7c811807c80cd712afielding * The Header directive can be used to add/replace/remove HTTP headers
ba4c566c200c2436dae841b7c811807c80cd712afielding * within the response message. The RequestHeader directive can be used
ba4c566c200c2436dae841b7c811807c80cd712afielding * to add/replace/remove HTTP headers before a request message is processed.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * Valid in both per-server and per-dir configurations.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding *
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * Syntax is:
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding *
ba4c566c200c2436dae841b7c811807c80cd712afielding * Header action header value
ba4c566c200c2436dae841b7c811807c80cd712afielding * RequestHeader action header value
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding *
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * Where action is one of:
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * set - set this header, replacing any old value
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * add - add this header, possible resulting in two or more
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * headers with the same name
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * append - append this text onto any existing header of this same
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd * merge - merge this text onto any existing header of this same,
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd * avoiding duplicate values
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * unset - remove this header
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd * edit - transform the header value according to a regexp
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding *
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * Where action is unset, the third argument (value) should not be given.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * The header name can include the colon, or not.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding *
ba4c566c200c2436dae841b7c811807c80cd712afielding * The Header and RequestHeader directives can only be used where allowed
ba4c566c200c2436dae841b7c811807c80cd712afielding * by the FileInfo override.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding *
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * When the request is processed, the header directives are processed in
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * this order: firstly, the main server, then the virtual server handling
e8f95a682820a599fe41b22977010636be5c2717jim * this request (if any), then any <Directory> sections (working downwards
e8f95a682820a599fe41b22977010636be5c2717jim * from the root dir), then an <Location> sections (working down from
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * shortest URL component), the any <File> sections. This order is
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * important if any 'set' or 'unset' actions are used. For example,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * the following two directives have different effect if applied in
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * the reverse order:
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding *
ba4c566c200c2436dae841b7c811807c80cd712afielding * Header append Author "John P. Doe"
ba4c566c200c2436dae841b7c811807c80cd712afielding * Header unset Author
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding *
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * Examples:
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding *
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * To set the "Author" header, use
ba4c566c200c2436dae841b7c811807c80cd712afielding * Header add Author "John P. Doe"
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding *
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * To remove a header:
ba4c566c200c2436dae841b7c811807c80cd712afielding * Header unset Author
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding *
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
024cd9589e52cf11ce765dfddb5b5f0c6e421a48gstein#include "apr.h"
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard#include "apr_lib.h"
0d496deee49b66bb43883640fa9c1a7e884a1b8ctrawick#include "apr_strings.h"
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard#include "apr_buckets.h"
024cd9589e52cf11ce765dfddb5b5f0c6e421a48gstein
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard#include "apr_hash.h"
024cd9589e52cf11ce765dfddb5b5f0c6e421a48gstein#define APR_WANT_STRFUNC
024cd9589e52cf11ce765dfddb5b5f0c6e421a48gstein#include "apr_want.h"
024cd9589e52cf11ce765dfddb5b5f0c6e421a48gstein
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#include "httpd.h"
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#include "http_config.h"
4cff088e460b3832142e59c63b357f8cf4d77fa8ake#include "http_request.h"
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard#include "http_log.h"
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard#include "util_filter.h"
7c4aca408b6678f99033503e588bbc2fdb836b09stoddard#include "http_protocol.h"
87e0bf269cc3386ee8e6ab561ff00770151f4f53niq#include "ap_expr.h"
5fac45c1ef49924141fe28497deb350cf031b377trawick
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton#include "mod_ssl.h" /* for the ssl_var_lookup optional function defn */
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard/* format_tag_hash is initialized during pre-config */
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddardstatic apr_hash_t *format_tag_hash;
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingtypedef enum {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding hdr_add = 'a', /* add header (could mean multiple hdrs) */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding hdr_set = 's', /* set (replace old value) */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding hdr_append = 'm', /* append (merge into any old value) */
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd hdr_merge = 'g', /* merge (merge, but avoid duplicates) */
3bc407b46a67691f3e5fd4f5f5ead4e1eff09998stoddard hdr_unset = 'u', /* unset header */
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq hdr_echo = 'e', /* echo headers from request to response */
64dbb5532fba398c5e81efeb21c7fd50c05819d7niq hdr_edit = 'r', /* change value by regexp, match once */
4b3f656d2ad030be85d219e02fdc11546ddecb5ccovener hdr_edit_r = 'R', /* change value by regexp, everymatch */
4b3f656d2ad030be85d219e02fdc11546ddecb5ccovener hdr_setifempty = 'i', /* set value if header not already present*/
4b3f656d2ad030be85d219e02fdc11546ddecb5ccovener hdr_note = 'n' /* set value of header in a note */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding} hdr_actions;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
08eb8303a91265264085e646f5937c76ae1e0c5bnd/*
08eb8303a91265264085e646f5937c76ae1e0c5bnd * magic cmd->info values
08eb8303a91265264085e646f5937c76ae1e0c5bnd */
08eb8303a91265264085e646f5937c76ae1e0c5bndstatic char hdr_in = '0'; /* RequestHeader */
d24345ec3173e01df72469ded862084c98ae4d61covenerstatic char hdr_out_onsuccess = '1'; /* Header onsuccess */
26f56d4a3c12077d605362e97490e34522fa4814covenerstatic char hdr_out_always = '2'; /* Header always */
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard
3b60bc6cafbb662cb3edc70c1df81c8deb31175ajorton/* Callback function type. */
3b60bc6cafbb662cb3edc70c1df81c8deb31175ajortontypedef const char *format_tag_fn(request_rec *r, char *a);
3b60bc6cafbb662cb3edc70c1df81c8deb31175ajorton
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard/*
e8f95a682820a599fe41b22977010636be5c2717jim * There is an array of struct format_tag per Header/RequestHeader
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard * config directive
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard */
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddardtypedef struct {
3b60bc6cafbb662cb3edc70c1df81c8deb31175ajorton format_tag_fn *func;
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard char *arg;
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard} format_tag;
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard
cf82d17373559b6163dbd6c844c1af82cab56883niq/* 'Magic' condition_var value to run action in post_read_request */
cf82d17373559b6163dbd6c844c1af82cab56883niqstatic const char* condition_early = "early";
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard/*
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard * There is one "header_entry" per Header/RequestHeader config directive
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard */
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingtypedef struct {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding hdr_actions action;
08eb8303a91265264085e646f5937c76ae1e0c5bnd const char *header;
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard apr_array_header_t *ta; /* Array of format_tag structs */
ef5650b61a8e35f3cc93ec07e73efc17ea329894jorton ap_regex_t *regex;
fd709745f1226d683c57ad9bbcdd05971d214d0cstoddard const char *condition_var;
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq const char *subs;
8fae12696bce44be9ce4c56888690cad8ac7b8f9sf ap_expr_info_t *expr;
81849cd8925f6ffaf57412aaaac8a6df0d33cbb6covener ap_expr_info_t *expr_out;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding} header_entry;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard/* echo_do is used for Header echo to iterate through the request headers*/
3bc407b46a67691f3e5fd4f5f5ead4e1eff09998stoddardtypedef struct {
3bc407b46a67691f3e5fd4f5f5ead4e1eff09998stoddard request_rec *r;
3bc407b46a67691f3e5fd4f5f5ead4e1eff09998stoddard header_entry *hdr;
3bc407b46a67691f3e5fd4f5f5ead4e1eff09998stoddard} echo_do;
3bc407b46a67691f3e5fd4f5f5ead4e1eff09998stoddard
6951fc02abfd7642e45333902c14855836717fadrpluem/* edit_do is used for Header edit to iterate through the request headers */
6951fc02abfd7642e45333902c14855836717fadrpluemtypedef struct {
88fa154e9a87c35cf4ee74d46f095f66fe897d0edruggeri request_rec *r;
6951fc02abfd7642e45333902c14855836717fadrpluem header_entry *hdr;
6951fc02abfd7642e45333902c14855836717fadrpluem apr_table_t *t;
6951fc02abfd7642e45333902c14855836717fadrpluem} edit_do;
6951fc02abfd7642e45333902c14855836717fadrpluem
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/*
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * headers_conf is our per-module configuration. This is used as both
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * a per-dir and per-server config
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding */
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingtypedef struct {
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard apr_array_header_t *fixup_in;
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard apr_array_header_t *fixup_out;
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar apr_array_header_t *fixup_err;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding} headers_conf;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
3d96ee83babeec32482c9082c9426340cee8c44dwrowemodule AP_MODULE_DECLARE_DATA headers_module;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton/* Pointer to ssl_var_lookup, if available. */
77f0db50b7e6636f6422de76ffb2a0af7acaed6djortonstatic APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *header_ssl_lookup = NULL;
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard/*
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard * Tag formatting functions
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard */
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddardstatic const char *constant_item(request_rec *r, char *stuff)
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard{
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard return stuff;
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard}
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddardstatic const char *header_request_duration(request_rec *r, char *a)
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard{
e8f95a682820a599fe41b22977010636be5c2717jim return apr_psprintf(r->pool, "D=%" APR_TIME_T_FMT,
e8f95a682820a599fe41b22977010636be5c2717jim (apr_time_now() - r->request_time));
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard}
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddardstatic const char *header_request_time(request_rec *r, char *a)
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard{
0329db7881b698897213e816552b0ab31f8d4d56trawick return apr_psprintf(r->pool, "t=%" APR_TIME_T_FMT, r->request_time);
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard}
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton/* unwrap_header returns HDR with any newlines converted into
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton * whitespace if necessary. */
77f0db50b7e6636f6422de76ffb2a0af7acaed6djortonstatic const char *unwrap_header(apr_pool_t *p, const char *hdr)
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton{
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton if (ap_strchr_c(hdr, APR_ASCII_LF) || ap_strchr_c(hdr, APR_ASCII_CR)) {
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton char *ptr;
e8f95a682820a599fe41b22977010636be5c2717jim
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton hdr = ptr = apr_pstrdup(p, hdr);
e8f95a682820a599fe41b22977010636be5c2717jim
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton do {
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton if (*ptr == APR_ASCII_LF || *ptr == APR_ASCII_CR)
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton *ptr = APR_ASCII_BLANK;
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton } while (*ptr++);
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton }
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton return hdr;
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton}
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton
ed4b039edaff2a734bd8da9c33e43e2fb8dd0db9ianhstatic const char *header_request_env_var(request_rec *r, char *a)
ed4b039edaff2a734bd8da9c33e43e2fb8dd0db9ianh{
54449e92dcdd62884ea83c3e0fb0ced57fb65801jwoolley const char *s = apr_table_get(r->subprocess_env,a);
a47a28784ca46876076471d2a0b45c11f800bffestoddard
ed4b039edaff2a734bd8da9c33e43e2fb8dd0db9ianh if (s)
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton return unwrap_header(r->pool, s);
ed4b039edaff2a734bd8da9c33e43e2fb8dd0db9ianh else
ed4b039edaff2a734bd8da9c33e43e2fb8dd0db9ianh return "(null)";
ed4b039edaff2a734bd8da9c33e43e2fb8dd0db9ianh}
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton
77f0db50b7e6636f6422de76ffb2a0af7acaed6djortonstatic const char *header_request_ssl_var(request_rec *r, char *name)
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton{
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton if (header_ssl_lookup) {
e8f95a682820a599fe41b22977010636be5c2717jim const char *val = header_ssl_lookup(r->pool, r->server,
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton r->connection, r, name);
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton if (val && val[0])
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton return unwrap_header(r->pool, val);
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton else
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton return "(null)";
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton }
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton else {
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton return "(null)";
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton }
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton}
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton
0b1e2711d8332fb10ca0a889f17dba261758e893jimstatic const char *header_request_loadavg(request_rec *r, char *a)
0b1e2711d8332fb10ca0a889f17dba261758e893jim{
0b1e2711d8332fb10ca0a889f17dba261758e893jim ap_loadavg_t t;
0b1e2711d8332fb10ca0a889f17dba261758e893jim ap_get_loadavg(&t);
414a70fb459ec63b1196d6467b4d8bc2a290883djim return apr_psprintf(r->pool, "l=%.2f/%.2f/%.2f", t.loadavg,
414a70fb459ec63b1196d6467b4d8bc2a290883djim t.loadavg5, t.loadavg15);
0b1e2711d8332fb10ca0a889f17dba261758e893jim}
0b1e2711d8332fb10ca0a889f17dba261758e893jim
0b1e2711d8332fb10ca0a889f17dba261758e893jimstatic const char *header_request_idle(request_rec *r, char *a)
0b1e2711d8332fb10ca0a889f17dba261758e893jim{
0b1e2711d8332fb10ca0a889f17dba261758e893jim ap_sload_t t;
0b1e2711d8332fb10ca0a889f17dba261758e893jim ap_get_sload(&t);
0b1e2711d8332fb10ca0a889f17dba261758e893jim return apr_psprintf(r->pool, "i=%d", t.idle);
0b1e2711d8332fb10ca0a889f17dba261758e893jim}
0b1e2711d8332fb10ca0a889f17dba261758e893jim
0b1e2711d8332fb10ca0a889f17dba261758e893jimstatic const char *header_request_busy(request_rec *r, char *a)
0b1e2711d8332fb10ca0a889f17dba261758e893jim{
0b1e2711d8332fb10ca0a889f17dba261758e893jim ap_sload_t t;
0b1e2711d8332fb10ca0a889f17dba261758e893jim ap_get_sload(&t);
0b1e2711d8332fb10ca0a889f17dba261758e893jim return apr_psprintf(r->pool, "b=%d", t.busy);
0b1e2711d8332fb10ca0a889f17dba261758e893jim}
0b1e2711d8332fb10ca0a889f17dba261758e893jim
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard/*
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard * Config routines
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard */
08eb8303a91265264085e646f5937c76ae1e0c5bnd
08eb8303a91265264085e646f5937c76ae1e0c5bndstatic void *create_headers_dir_config(apr_pool_t *p, char *d)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
a6b9ed64fdf548c61de9714e2cfb999ec59d149cgstein headers_conf *conf = apr_pcalloc(p, sizeof(*conf));
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard conf->fixup_in = apr_array_make(p, 2, sizeof(header_entry));
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard conf->fixup_out = apr_array_make(p, 2, sizeof(header_entry));
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar conf->fixup_err = apr_array_make(p, 2, sizeof(header_entry));
a6b9ed64fdf548c61de9714e2cfb999ec59d149cgstein
a6b9ed64fdf548c61de9714e2cfb999ec59d149cgstein return conf;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
1ccd992d37d62c8cb2056126f2234f64ec189bfddougmstatic void *merge_headers_config(apr_pool_t *p, void *basev, void *overridesv)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
a6b9ed64fdf548c61de9714e2cfb999ec59d149cgstein headers_conf *newconf = apr_pcalloc(p, sizeof(*newconf));
a6b9ed64fdf548c61de9714e2cfb999ec59d149cgstein headers_conf *base = basev;
a6b9ed64fdf548c61de9714e2cfb999ec59d149cgstein headers_conf *overrides = overridesv;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
08eb8303a91265264085e646f5937c76ae1e0c5bnd newconf->fixup_in = apr_array_append(p, base->fixup_in,
08eb8303a91265264085e646f5937c76ae1e0c5bnd overrides->fixup_in);
08eb8303a91265264085e646f5937c76ae1e0c5bnd newconf->fixup_out = apr_array_append(p, base->fixup_out,
08eb8303a91265264085e646f5937c76ae1e0c5bnd overrides->fixup_out);
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar newconf->fixup_err = apr_array_append(p, base->fixup_err,
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar overrides->fixup_err);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
a6b9ed64fdf548c61de9714e2cfb999ec59d149cgstein return newconf;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
e8f95a682820a599fe41b22977010636be5c2717jim
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddardstatic char *parse_misc_string(apr_pool_t *p, format_tag *tag, const char **sa)
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard{
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard const char *s;
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard char *d;
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard tag->func = constant_item;
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard s = *sa;
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard while (*s && *s != '%') {
a47a28784ca46876076471d2a0b45c11f800bffestoddard s++;
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard }
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard /*
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard * This might allocate a few chars extra if there's a backslash
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard * escape in the format string.
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard */
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard tag->arg = apr_palloc(p, s - *sa + 1);
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard d = tag->arg;
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard s = *sa;
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard while (*s && *s != '%') {
a47a28784ca46876076471d2a0b45c11f800bffestoddard if (*s != '\\') {
a47a28784ca46876076471d2a0b45c11f800bffestoddard *d++ = *s++;
a47a28784ca46876076471d2a0b45c11f800bffestoddard }
a47a28784ca46876076471d2a0b45c11f800bffestoddard else {
a47a28784ca46876076471d2a0b45c11f800bffestoddard s++;
a47a28784ca46876076471d2a0b45c11f800bffestoddard switch (*s) {
a47a28784ca46876076471d2a0b45c11f800bffestoddard case '\\':
a47a28784ca46876076471d2a0b45c11f800bffestoddard *d++ = '\\';
a47a28784ca46876076471d2a0b45c11f800bffestoddard s++;
a47a28784ca46876076471d2a0b45c11f800bffestoddard break;
a47a28784ca46876076471d2a0b45c11f800bffestoddard case 'r':
a47a28784ca46876076471d2a0b45c11f800bffestoddard *d++ = '\r';
a47a28784ca46876076471d2a0b45c11f800bffestoddard s++;
a47a28784ca46876076471d2a0b45c11f800bffestoddard break;
a47a28784ca46876076471d2a0b45c11f800bffestoddard case 'n':
a47a28784ca46876076471d2a0b45c11f800bffestoddard *d++ = '\n';
a47a28784ca46876076471d2a0b45c11f800bffestoddard s++;
a47a28784ca46876076471d2a0b45c11f800bffestoddard break;
e8f95a682820a599fe41b22977010636be5c2717jim case 't':
a47a28784ca46876076471d2a0b45c11f800bffestoddard *d++ = '\t';
a47a28784ca46876076471d2a0b45c11f800bffestoddard s++;
a47a28784ca46876076471d2a0b45c11f800bffestoddard break;
a47a28784ca46876076471d2a0b45c11f800bffestoddard default:
a47a28784ca46876076471d2a0b45c11f800bffestoddard /* copy verbatim */
a47a28784ca46876076471d2a0b45c11f800bffestoddard *d++ = '\\';
a47a28784ca46876076471d2a0b45c11f800bffestoddard /*
a47a28784ca46876076471d2a0b45c11f800bffestoddard * Allow the loop to deal with this *s in the normal
a47a28784ca46876076471d2a0b45c11f800bffestoddard * fashion so that it handles end of string etc.
a47a28784ca46876076471d2a0b45c11f800bffestoddard * properly.
a47a28784ca46876076471d2a0b45c11f800bffestoddard */
a47a28784ca46876076471d2a0b45c11f800bffestoddard break;
a47a28784ca46876076471d2a0b45c11f800bffestoddard }
a47a28784ca46876076471d2a0b45c11f800bffestoddard }
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard }
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard *d = '\0';
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard *sa = s;
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard return NULL;
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard}
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddardstatic char *parse_format_tag(apr_pool_t *p, format_tag *tag, const char **sa)
e8f95a682820a599fe41b22977010636be5c2717jim{
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard const char *s = *sa;
58ecd4abb0bc207016069618e7d2b9cb640046c4trawick const char * (*tag_handler)(request_rec *,char *);
a47a28784ca46876076471d2a0b45c11f800bffestoddard
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard /* Handle string literal/conditionals */
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard if (*s != '%') {
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard return parse_misc_string(p, tag, sa);
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard }
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard s++; /* skip the % */
56cefde0af6b8db6fda0f1d95d8cdca54f397cd0nd
07a4fd7c4750c999c907e624575045180c50c742niq /* Pass through %% or % at end of string as % */
07a4fd7c4750c999c907e624575045180c50c742niq if ((*s == '%') || (*s == '\0')) {
56cefde0af6b8db6fda0f1d95d8cdca54f397cd0nd tag->func = constant_item;
56cefde0af6b8db6fda0f1d95d8cdca54f397cd0nd tag->arg = "%";
33efd3cc4a50d2e29ac3c3d2ff30e18e9304450brpluem if (*s)
33efd3cc4a50d2e29ac3c3d2ff30e18e9304450brpluem s++;
33efd3cc4a50d2e29ac3c3d2ff30e18e9304450brpluem *sa = s;
56cefde0af6b8db6fda0f1d95d8cdca54f397cd0nd return NULL;
56cefde0af6b8db6fda0f1d95d8cdca54f397cd0nd }
56cefde0af6b8db6fda0f1d95d8cdca54f397cd0nd
28adee1a4cc79a411f2432cc7f8dc7c3170b745fsf tag->arg = "\0";
ed4b039edaff2a734bd8da9c33e43e2fb8dd0db9ianh /* grab the argument if there is one */
ed4b039edaff2a734bd8da9c33e43e2fb8dd0db9ianh if (*s == '{') {
ed4b039edaff2a734bd8da9c33e43e2fb8dd0db9ianh ++s;
ed4b039edaff2a734bd8da9c33e43e2fb8dd0db9ianh tag->arg = ap_getword(p,&s,'}');
ed4b039edaff2a734bd8da9c33e43e2fb8dd0db9ianh }
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard
58ecd4abb0bc207016069618e7d2b9cb640046c4trawick tag_handler = (const char * (*)(request_rec *,char *))apr_hash_get(format_tag_hash, s++, 1);
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard if (!tag_handler) {
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard char dummy[2];
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard dummy[0] = s[-1];
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard dummy[1] = '\0';
56cefde0af6b8db6fda0f1d95d8cdca54f397cd0nd return apr_pstrcat(p, "Unrecognized header format %", dummy, NULL);
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard }
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard tag->func = tag_handler;
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard *sa = s;
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard return NULL;
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard}
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard/*
e8f95a682820a599fe41b22977010636be5c2717jim * A format string consists of white space, text and optional format
e8f95a682820a599fe41b22977010636be5c2717jim * tags in any order. E.g.,
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard *
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard * Header add MyHeader "Free form text %D %t more text"
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard *
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard * Decompose the format string into its tags. Each tag (struct format_tag)
e8f95a682820a599fe41b22977010636be5c2717jim * contains a pointer to the function used to format the tag. Then save each
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard * tag in the tag array anchored in the header_entry.
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard */
81849cd8925f6ffaf57412aaaac8a6df0d33cbb6covenerstatic char *parse_format_string(cmd_parms *cmd, header_entry *hdr, const char *s)
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard{
81849cd8925f6ffaf57412aaaac8a6df0d33cbb6covener apr_pool_t *p = cmd->pool;
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard char *res;
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard
08eb8303a91265264085e646f5937c76ae1e0c5bnd /* No string to parse with unset and echo commands */
88fa154e9a87c35cf4ee74d46f095f66fe897d0edruggeri if (hdr->action == hdr_unset || hdr->action == hdr_echo) {
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard return NULL;
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard }
88fa154e9a87c35cf4ee74d46f095f66fe897d0edruggeri /* Tags are in the replacement value for edit */
88fa154e9a87c35cf4ee74d46f095f66fe897d0edruggeri else if (hdr->action == hdr_edit || hdr->action == hdr_edit_r ) {
88fa154e9a87c35cf4ee74d46f095f66fe897d0edruggeri s = hdr->subs;
88fa154e9a87c35cf4ee74d46f095f66fe897d0edruggeri }
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard
81849cd8925f6ffaf57412aaaac8a6df0d33cbb6covener if (!strncmp(s, "expr=", 5)) {
81849cd8925f6ffaf57412aaaac8a6df0d33cbb6covener const char *err;
81849cd8925f6ffaf57412aaaac8a6df0d33cbb6covener hdr->expr_out = ap_expr_parse_cmd(cmd, s+5,
81849cd8925f6ffaf57412aaaac8a6df0d33cbb6covener AP_EXPR_FLAG_STRING_RESULT,
81849cd8925f6ffaf57412aaaac8a6df0d33cbb6covener &err, NULL);
81849cd8925f6ffaf57412aaaac8a6df0d33cbb6covener if (err) {
81849cd8925f6ffaf57412aaaac8a6df0d33cbb6covener return apr_pstrcat(cmd->pool,
81849cd8925f6ffaf57412aaaac8a6df0d33cbb6covener "Can't parse value expression : ", err, NULL);
81849cd8925f6ffaf57412aaaac8a6df0d33cbb6covener }
81849cd8925f6ffaf57412aaaac8a6df0d33cbb6covener return NULL;
81849cd8925f6ffaf57412aaaac8a6df0d33cbb6covener }
81849cd8925f6ffaf57412aaaac8a6df0d33cbb6covener
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard hdr->ta = apr_array_make(p, 10, sizeof(format_tag));
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard while (*s) {
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard if ((res = parse_format_tag(p, (format_tag *) apr_array_push(hdr->ta), &s))) {
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard return res;
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard }
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard }
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard return NULL;
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
ba4c566c200c2436dae841b7c811807c80cd712afielding/* handle RequestHeader and Header directive */
08eb8303a91265264085e646f5937c76ae1e0c5bndstatic APR_INLINE const char *header_inout_cmd(cmd_parms *cmd,
08eb8303a91265264085e646f5937c76ae1e0c5bnd void *indirconf,
08eb8303a91265264085e646f5937c76ae1e0c5bnd const char *action,
08eb8303a91265264085e646f5937c76ae1e0c5bnd const char *hdr,
08eb8303a91265264085e646f5937c76ae1e0c5bnd const char *value,
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq const char *subs,
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq const char *envclause)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
0d496deee49b66bb43883640fa9c1a7e884a1b8ctrawick headers_conf *dirconf = indirconf;
2dc8dcdf14f304577a6210479a4008f7cb6bc827trawick const char *condition_var = NULL;
08eb8303a91265264085e646f5937c76ae1e0c5bnd const char *colon;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding header_entry *new;
8fae12696bce44be9ce4c56888690cad8ac7b8f9sf ap_expr_info_t *expr = NULL;
08eb8303a91265264085e646f5937c76ae1e0c5bnd
08eb8303a91265264085e646f5937c76ae1e0c5bnd apr_array_header_t *fixup = (cmd->info == &hdr_in)
d24345ec3173e01df72469ded862084c98ae4d61covener ? dirconf->fixup_in : (cmd->info == &hdr_out_always)
08eb8303a91265264085e646f5937c76ae1e0c5bnd ? dirconf->fixup_err
08eb8303a91265264085e646f5937c76ae1e0c5bnd : dirconf->fixup_out;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
bcb10e4b6aef86f57c8c8049048b0d7fb179b3b3jorton new = (header_entry *) apr_array_push(fixup);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (!strcasecmp(action, "set"))
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding new->action = hdr_set;
45dffe6c346dd73571ccaead10295fc7d53b59a6covener else if (!strcasecmp(action, "setifempty"))
45dffe6c346dd73571ccaead10295fc7d53b59a6covener new->action = hdr_setifempty;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding else if (!strcasecmp(action, "add"))
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding new->action = hdr_add;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding else if (!strcasecmp(action, "append"))
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding new->action = hdr_append;
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd else if (!strcasecmp(action, "merge"))
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd new->action = hdr_merge;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding else if (!strcasecmp(action, "unset"))
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding new->action = hdr_unset;
3bc407b46a67691f3e5fd4f5f5ead4e1eff09998stoddard else if (!strcasecmp(action, "echo"))
3bc407b46a67691f3e5fd4f5f5ead4e1eff09998stoddard new->action = hdr_echo;
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq else if (!strcasecmp(action, "edit"))
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq new->action = hdr_edit;
64dbb5532fba398c5e81efeb21c7fd50c05819d7niq else if (!strcasecmp(action, "edit*"))
64dbb5532fba398c5e81efeb21c7fd50c05819d7niq new->action = hdr_edit_r;
4b3f656d2ad030be85d219e02fdc11546ddecb5ccovener else if (!strcasecmp(action, "note"))
4b3f656d2ad030be85d219e02fdc11546ddecb5ccovener new->action = hdr_note;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding else
45dffe6c346dd73571ccaead10295fc7d53b59a6covener return "first argument must be 'add', 'set', 'setifempty', 'append', 'merge', "
4b3f656d2ad030be85d219e02fdc11546ddecb5ccovener "'unset', 'echo', 'note', 'edit', or 'edit*'.";
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
64dbb5532fba398c5e81efeb21c7fd50c05819d7niq if (new->action == hdr_edit || new->action == hdr_edit_r) {
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq if (subs == NULL) {
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq return "Header edit requires a match and a substitution";
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq }
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq new->regex = ap_pregcomp(cmd->pool, value, AP_REG_EXTENDED);
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq if (new->regex == NULL) {
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq return "Header edit regex could not be compiled";
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq }
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq new->subs = subs;
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq }
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq else {
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq /* there's no subs, so envclause is really that argument */
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq if (envclause != NULL) {
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq return "Too many arguments to directive";
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq }
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq envclause = subs;
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (new->action == hdr_unset) {
41369ed0bc7f2db6272278c27025f6aabf97fe63nd if (value) {
41369ed0bc7f2db6272278c27025f6aabf97fe63nd if (envclause) {
41369ed0bc7f2db6272278c27025f6aabf97fe63nd return "header unset takes two arguments";
41369ed0bc7f2db6272278c27025f6aabf97fe63nd }
41369ed0bc7f2db6272278c27025f6aabf97fe63nd envclause = value;
41369ed0bc7f2db6272278c27025f6aabf97fe63nd value = NULL;
41369ed0bc7f2db6272278c27025f6aabf97fe63nd }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
3bc407b46a67691f3e5fd4f5f5ead4e1eff09998stoddard else if (new->action == hdr_echo) {
ef5650b61a8e35f3cc93ec07e73efc17ea329894jorton ap_regex_t *regex;
08eb8303a91265264085e646f5937c76ae1e0c5bnd
41369ed0bc7f2db6272278c27025f6aabf97fe63nd if (value) {
41369ed0bc7f2db6272278c27025f6aabf97fe63nd if (envclause) {
41369ed0bc7f2db6272278c27025f6aabf97fe63nd return "Header echo takes two arguments";
41369ed0bc7f2db6272278c27025f6aabf97fe63nd }
41369ed0bc7f2db6272278c27025f6aabf97fe63nd envclause = value;
41369ed0bc7f2db6272278c27025f6aabf97fe63nd value = NULL;
41369ed0bc7f2db6272278c27025f6aabf97fe63nd }
d24345ec3173e01df72469ded862084c98ae4d61covener if (cmd->info != &hdr_out_onsuccess && cmd->info != &hdr_out_always)
174a8f105b1c11aa50a05993ea8ba2d117d3df6end return "Header echo only valid on Header "
496f8f3966319d43455675630a849bae019d2a32nd "directives";
3bc407b46a67691f3e5fd4f5f5ead4e1eff09998stoddard else {
ef5650b61a8e35f3cc93ec07e73efc17ea329894jorton regex = ap_pregcomp(cmd->pool, hdr, AP_REG_EXTENDED | AP_REG_NOSUB);
3bc407b46a67691f3e5fd4f5f5ead4e1eff09998stoddard if (regex == NULL) {
3bc407b46a67691f3e5fd4f5f5ead4e1eff09998stoddard return "Header echo regex could not be compiled";
3bc407b46a67691f3e5fd4f5f5ead4e1eff09998stoddard }
3bc407b46a67691f3e5fd4f5f5ead4e1eff09998stoddard }
3bc407b46a67691f3e5fd4f5f5ead4e1eff09998stoddard new->regex = regex;
3bc407b46a67691f3e5fd4f5f5ead4e1eff09998stoddard }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding else if (!value)
08eb8303a91265264085e646f5937c76ae1e0c5bnd return "Header requires three arguments";
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
fd709745f1226d683c57ad9bbcdd05971d214d0cstoddard /* Handle the envclause on Header */
fd709745f1226d683c57ad9bbcdd05971d214d0cstoddard if (envclause != NULL) {
cf82d17373559b6163dbd6c844c1af82cab56883niq if (strcasecmp(envclause, "early") == 0) {
cf82d17373559b6163dbd6c844c1af82cab56883niq condition_var = condition_early;
a47a28784ca46876076471d2a0b45c11f800bffestoddard }
87e0bf269cc3386ee8e6ab561ff00770151f4f53niq else if (strncasecmp(envclause, "env=", 4) == 0) {
cf82d17373559b6163dbd6c844c1af82cab56883niq if ((envclause[4] == '\0')
cf82d17373559b6163dbd6c844c1af82cab56883niq || ((envclause[4] == '!') && (envclause[5] == '\0'))) {
cf82d17373559b6163dbd6c844c1af82cab56883niq return "error: missing environment variable name. "
cf82d17373559b6163dbd6c844c1af82cab56883niq "envclause should be in the form env=envar ";
cf82d17373559b6163dbd6c844c1af82cab56883niq }
cf82d17373559b6163dbd6c844c1af82cab56883niq condition_var = envclause + 4;
a47a28784ca46876076471d2a0b45c11f800bffestoddard }
c07f5b18040b0d39b077666ad6fbbd28fe0eb5f1sf else if (strncasecmp(envclause, "expr=", 5) == 0) {
8fae12696bce44be9ce4c56888690cad8ac7b8f9sf const char *err = NULL;
c07f5b18040b0d39b077666ad6fbbd28fe0eb5f1sf expr = ap_expr_parse_cmd(cmd, envclause + 5, 0, &err, NULL);
87e0bf269cc3386ee8e6ab561ff00770151f4f53niq if (err) {
8fae12696bce44be9ce4c56888690cad8ac7b8f9sf return apr_pstrcat(cmd->pool,
8fae12696bce44be9ce4c56888690cad8ac7b8f9sf "Can't parse envclause/expression: ", err,
8fae12696bce44be9ce4c56888690cad8ac7b8f9sf NULL);
87e0bf269cc3386ee8e6ab561ff00770151f4f53niq }
87e0bf269cc3386ee8e6ab561ff00770151f4f53niq }
c07f5b18040b0d39b077666ad6fbbd28fe0eb5f1sf else {
c07f5b18040b0d39b077666ad6fbbd28fe0eb5f1sf return apr_pstrcat(cmd->pool, "Unknown parameter: ", envclause,
c07f5b18040b0d39b077666ad6fbbd28fe0eb5f1sf NULL);
c07f5b18040b0d39b077666ad6fbbd28fe0eb5f1sf }
fd709745f1226d683c57ad9bbcdd05971d214d0cstoddard }
e8f95a682820a599fe41b22977010636be5c2717jim
08eb8303a91265264085e646f5937c76ae1e0c5bnd if ((colon = ap_strchr_c(hdr, ':'))) {
08eb8303a91265264085e646f5937c76ae1e0c5bnd hdr = apr_pstrmemdup(cmd->pool, hdr, colon-hdr);
08eb8303a91265264085e646f5937c76ae1e0c5bnd }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding new->header = hdr;
fd709745f1226d683c57ad9bbcdd05971d214d0cstoddard new->condition_var = condition_var;
87e0bf269cc3386ee8e6ab561ff00770151f4f53niq new->expr = expr;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
81849cd8925f6ffaf57412aaaac8a6df0d33cbb6covener return parse_format_string(cmd, new, value);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
89ea31761658f422cf21cd3b0224dc5fe95cccd3nd/* Handle all (xxx)Header directives */
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddardstatic const char *header_cmd(cmd_parms *cmd, void *indirconf,
fd709745f1226d683c57ad9bbcdd05971d214d0cstoddard const char *args)
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard{
fd709745f1226d683c57ad9bbcdd05971d214d0cstoddard const char *action;
fd709745f1226d683c57ad9bbcdd05971d214d0cstoddard const char *hdr;
fd709745f1226d683c57ad9bbcdd05971d214d0cstoddard const char *val;
fd709745f1226d683c57ad9bbcdd05971d214d0cstoddard const char *envclause;
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq const char *subs;
fd709745f1226d683c57ad9bbcdd05971d214d0cstoddard
4e0565f42481dff87062cbfc55a2ecaa36b92e83sf action = ap_getword_conf(cmd->temp_pool, &args);
26f56d4a3c12077d605362e97490e34522fa4814covener if (cmd->info == &hdr_out_onsuccess) {
26f56d4a3c12077d605362e97490e34522fa4814covener if (!strcasecmp(action, "always")) {
26f56d4a3c12077d605362e97490e34522fa4814covener cmd->info = &hdr_out_always;
4e0565f42481dff87062cbfc55a2ecaa36b92e83sf action = ap_getword_conf(cmd->temp_pool, &args);
174a8f105b1c11aa50a05993ea8ba2d117d3df6end }
26f56d4a3c12077d605362e97490e34522fa4814covener else if (!strcasecmp(action, "onsuccess")) {
4e0565f42481dff87062cbfc55a2ecaa36b92e83sf action = ap_getword_conf(cmd->temp_pool, &args);
174a8f105b1c11aa50a05993ea8ba2d117d3df6end }
174a8f105b1c11aa50a05993ea8ba2d117d3df6end }
08eb8303a91265264085e646f5937c76ae1e0c5bnd hdr = ap_getword_conf(cmd->pool, &args);
08eb8303a91265264085e646f5937c76ae1e0c5bnd val = *args ? ap_getword_conf(cmd->pool, &args) : NULL;
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq subs = *args ? ap_getword_conf(cmd->pool, &args) : NULL;
08eb8303a91265264085e646f5937c76ae1e0c5bnd envclause = *args ? ap_getword_conf(cmd->pool, &args) : NULL;
fd709745f1226d683c57ad9bbcdd05971d214d0cstoddard
08eb8303a91265264085e646f5937c76ae1e0c5bnd if (*args) {
08eb8303a91265264085e646f5937c76ae1e0c5bnd return apr_pstrcat(cmd->pool, cmd->cmd->name,
174a8f105b1c11aa50a05993ea8ba2d117d3df6end " has too many arguments", NULL);
08eb8303a91265264085e646f5937c76ae1e0c5bnd }
08eb8303a91265264085e646f5937c76ae1e0c5bnd
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq return header_inout_cmd(cmd, indirconf, action, hdr, val, subs, envclause);
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard}
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard/*
e8f95a682820a599fe41b22977010636be5c2717jim * Process the tags in the format string. Tags may be format specifiers
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard * (%D, %t, etc.), whitespace or text strings. For each tag, run the handler
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard * (formatter) specific to the tag. Handlers return text strings.
e8f95a682820a599fe41b22977010636be5c2717jim * Concatenate the return from each handler into one string that is
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard * returned from this call.
81849cd8925f6ffaf57412aaaac8a6df0d33cbb6covener * If the original value was prefixed with "expr=", processing is
81849cd8925f6ffaf57412aaaac8a6df0d33cbb6covener * handled instead by ap_expr.
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard */
3becbd2611ffb2e8391a8eacce765b43dcb1c669wrowestatic char* process_tags(header_entry *hdr, request_rec *r)
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard{
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard int i;
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard const char *s;
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard char *str = NULL;
81849cd8925f6ffaf57412aaaac8a6df0d33cbb6covener format_tag *tag = NULL;
81849cd8925f6ffaf57412aaaac8a6df0d33cbb6covener
81849cd8925f6ffaf57412aaaac8a6df0d33cbb6covener if (hdr->expr_out) {
81849cd8925f6ffaf57412aaaac8a6df0d33cbb6covener const char *err;
81849cd8925f6ffaf57412aaaac8a6df0d33cbb6covener const char *val;
81849cd8925f6ffaf57412aaaac8a6df0d33cbb6covener val = ap_expr_str_exec(r, hdr->expr_out, &err);
81849cd8925f6ffaf57412aaaac8a6df0d33cbb6covener if (err) {
81849cd8925f6ffaf57412aaaac8a6df0d33cbb6covener ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02557)
81849cd8925f6ffaf57412aaaac8a6df0d33cbb6covener "Can't evaluate value expression: %s", err);
81849cd8925f6ffaf57412aaaac8a6df0d33cbb6covener return "";
81849cd8925f6ffaf57412aaaac8a6df0d33cbb6covener }
81849cd8925f6ffaf57412aaaac8a6df0d33cbb6covener return apr_pstrdup(r->pool, val);
81849cd8925f6ffaf57412aaaac8a6df0d33cbb6covener }
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard
81849cd8925f6ffaf57412aaaac8a6df0d33cbb6covener tag = (format_tag*) hdr->ta->elts;
e8f95a682820a599fe41b22977010636be5c2717jim
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard for (i = 0; i < hdr->ta->nelts; i++) {
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard s = tag[i].func(r, tag[i].arg);
e8f95a682820a599fe41b22977010636be5c2717jim if (str == NULL)
3becbd2611ffb2e8391a8eacce765b43dcb1c669wrowe str = apr_pstrdup(r->pool, s);
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard else
3becbd2611ffb2e8391a8eacce765b43dcb1c669wrowe str = apr_pstrcat(r->pool, str, s, NULL);
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard }
c52d06f85b1d2b9e922abd0b89d2b034ec878535nd return str ? str : "";
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard}
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niqstatic const char *process_regexp(header_entry *hdr, const char *value,
88fa154e9a87c35cf4ee74d46f095f66fe897d0edruggeri request_rec *r)
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq{
465bb7463b2334971514d5bc5df37de7ce88b151sf ap_regmatch_t pmatch[AP_MAX_REG_MATCH];
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq const char *subs;
64dbb5532fba398c5e81efeb21c7fd50c05819d7niq const char *remainder;
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq char *ret;
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq int diffsz;
465bb7463b2334971514d5bc5df37de7ce88b151sf if (ap_regexec(hdr->regex, value, AP_MAX_REG_MATCH, pmatch, 0)) {
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq /* no match, nothing to do */
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq return value;
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq }
88fa154e9a87c35cf4ee74d46f095f66fe897d0edruggeri /* Process tags in the input string rather than the resulting
88fa154e9a87c35cf4ee74d46f095f66fe897d0edruggeri * substitution to avoid surprises
88fa154e9a87c35cf4ee74d46f095f66fe897d0edruggeri */
88fa154e9a87c35cf4ee74d46f095f66fe897d0edruggeri subs = ap_pregsub(r->pool, process_tags(hdr, r), value, AP_MAX_REG_MATCH, pmatch);
51254470cbee1458031e364c8126e75ff07d225fsf if (subs == NULL)
51254470cbee1458031e364c8126e75ff07d225fsf return NULL;
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq diffsz = strlen(subs) - (pmatch[0].rm_eo - pmatch[0].rm_so);
64dbb5532fba398c5e81efeb21c7fd50c05819d7niq if (hdr->action == hdr_edit) {
64dbb5532fba398c5e81efeb21c7fd50c05819d7niq remainder = value + pmatch[0].rm_eo;
64dbb5532fba398c5e81efeb21c7fd50c05819d7niq }
64dbb5532fba398c5e81efeb21c7fd50c05819d7niq else { /* recurse to edit multiple matches if applicable */
88fa154e9a87c35cf4ee74d46f095f66fe897d0edruggeri remainder = process_regexp(hdr, value + pmatch[0].rm_eo, r);
51254470cbee1458031e364c8126e75ff07d225fsf if (remainder == NULL)
51254470cbee1458031e364c8126e75ff07d225fsf return NULL;
64dbb5532fba398c5e81efeb21c7fd50c05819d7niq diffsz += strlen(remainder) - strlen(value + pmatch[0].rm_eo);
64dbb5532fba398c5e81efeb21c7fd50c05819d7niq }
88fa154e9a87c35cf4ee74d46f095f66fe897d0edruggeri ret = apr_palloc(r->pool, strlen(value) + 1 + diffsz);
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq memcpy(ret, value, pmatch[0].rm_so);
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq strcpy(ret + pmatch[0].rm_so, subs);
15420e12eacf6a8d959a51128369783c01142d72niq strcat(ret, remainder);
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq return ret;
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq}
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard
3bc407b46a67691f3e5fd4f5f5ead4e1eff09998stoddardstatic int echo_header(echo_do *v, const char *key, const char *val)
3bc407b46a67691f3e5fd4f5f5ead4e1eff09998stoddard{
e8f95a682820a599fe41b22977010636be5c2717jim /* If the input header (key) matches the regex, echo it intact to
3bc407b46a67691f3e5fd4f5f5ead4e1eff09998stoddard * r->headers_out.
3bc407b46a67691f3e5fd4f5f5ead4e1eff09998stoddard */
3bc407b46a67691f3e5fd4f5f5ead4e1eff09998stoddard if (!ap_regexec(v->hdr->regex, key, 0, NULL, 0)) {
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard apr_table_add(v->r->headers_out, key, val);
3bc407b46a67691f3e5fd4f5f5ead4e1eff09998stoddard }
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard
f2127630a87ab5952a3d173b164e600c99cff25astoddard return 1;
3bc407b46a67691f3e5fd4f5f5ead4e1eff09998stoddard}
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard
6951fc02abfd7642e45333902c14855836717fadrpluemstatic int edit_header(void *v, const char *key, const char *val)
6951fc02abfd7642e45333902c14855836717fadrpluem{
6951fc02abfd7642e45333902c14855836717fadrpluem edit_do *ed = (edit_do *)v;
88fa154e9a87c35cf4ee74d46f095f66fe897d0edruggeri const char *repl = process_regexp(ed->hdr, val, ed->r);
51254470cbee1458031e364c8126e75ff07d225fsf if (repl == NULL)
51254470cbee1458031e364c8126e75ff07d225fsf return 0;
6951fc02abfd7642e45333902c14855836717fadrpluem
51254470cbee1458031e364c8126e75ff07d225fsf apr_table_addn(ed->t, key, repl);
6951fc02abfd7642e45333902c14855836717fadrpluem return 1;
6951fc02abfd7642e45333902c14855836717fadrpluem}
6951fc02abfd7642e45333902c14855836717fadrpluem
6951fc02abfd7642e45333902c14855836717fadrpluemstatic int add_them_all(void *v, const char *key, const char *val)
6951fc02abfd7642e45333902c14855836717fadrpluem{
6951fc02abfd7642e45333902c14855836717fadrpluem apr_table_t *headers = (apr_table_t *)v;
6951fc02abfd7642e45333902c14855836717fadrpluem
6951fc02abfd7642e45333902c14855836717fadrpluem apr_table_addn(headers, key, val);
6951fc02abfd7642e45333902c14855836717fadrpluem return 1;
6951fc02abfd7642e45333902c14855836717fadrpluem}
6951fc02abfd7642e45333902c14855836717fadrpluem
51254470cbee1458031e364c8126e75ff07d225fsfstatic int do_headers_fixup(request_rec *r, apr_table_t *headers,
cf82d17373559b6163dbd6c844c1af82cab56883niq apr_array_header_t *fixup, int early)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq echo_do v;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding int i;
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq const char *val;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard for (i = 0; i < fixup->nelts; ++i) {
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard header_entry *hdr = &((header_entry *) (fixup->elts))[i];
cf82d17373559b6163dbd6c844c1af82cab56883niq const char *envar = hdr->condition_var;
fd709745f1226d683c57ad9bbcdd05971d214d0cstoddard
43c3e6a4b559b76b750c245ee95e2782c15b4296jim /* ignore early headers in late calls */
cf82d17373559b6163dbd6c844c1af82cab56883niq if (!early && (envar == condition_early)) {
cf82d17373559b6163dbd6c844c1af82cab56883niq continue;
cf82d17373559b6163dbd6c844c1af82cab56883niq }
43c3e6a4b559b76b750c245ee95e2782c15b4296jim /* ignore late headers in early calls */
cf82d17373559b6163dbd6c844c1af82cab56883niq else if (early && (envar != condition_early)) {
cf82d17373559b6163dbd6c844c1af82cab56883niq continue;
cf82d17373559b6163dbd6c844c1af82cab56883niq }
87e0bf269cc3386ee8e6ab561ff00770151f4f53niq /* Do we have an expression to evaluate? */
87e0bf269cc3386ee8e6ab561ff00770151f4f53niq else if (hdr->expr != NULL) {
8fae12696bce44be9ce4c56888690cad8ac7b8f9sf const char *err = NULL;
8fae12696bce44be9ce4c56888690cad8ac7b8f9sf int eval = ap_expr_exec(r, hdr->expr, &err);
87e0bf269cc3386ee8e6ab561ff00770151f4f53niq if (err) {
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01501)
8fae12696bce44be9ce4c56888690cad8ac7b8f9sf "Failed to evaluate expression (%s) - ignoring",
8fae12696bce44be9ce4c56888690cad8ac7b8f9sf err);
87e0bf269cc3386ee8e6ab561ff00770151f4f53niq }
87e0bf269cc3386ee8e6ab561ff00770151f4f53niq else if (!eval) {
87e0bf269cc3386ee8e6ab561ff00770151f4f53niq continue;
87e0bf269cc3386ee8e6ab561ff00770151f4f53niq }
87e0bf269cc3386ee8e6ab561ff00770151f4f53niq }
fd709745f1226d683c57ad9bbcdd05971d214d0cstoddard /* Have any conditional envar-controlled Header processing to do? */
cf82d17373559b6163dbd6c844c1af82cab56883niq else if (envar && !early) {
fd709745f1226d683c57ad9bbcdd05971d214d0cstoddard if (*envar != '!') {
fd709745f1226d683c57ad9bbcdd05971d214d0cstoddard if (apr_table_get(r->subprocess_env, envar) == NULL)
fd709745f1226d683c57ad9bbcdd05971d214d0cstoddard continue;
fd709745f1226d683c57ad9bbcdd05971d214d0cstoddard }
fd709745f1226d683c57ad9bbcdd05971d214d0cstoddard else {
fd709745f1226d683c57ad9bbcdd05971d214d0cstoddard if (apr_table_get(r->subprocess_env, &envar[1]) != NULL)
fd709745f1226d683c57ad9bbcdd05971d214d0cstoddard continue;
fd709745f1226d683c57ad9bbcdd05971d214d0cstoddard }
fd709745f1226d683c57ad9bbcdd05971d214d0cstoddard }
fd709745f1226d683c57ad9bbcdd05971d214d0cstoddard
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding switch (hdr->action) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding case hdr_add:
3becbd2611ffb2e8391a8eacce765b43dcb1c669wrowe apr_table_addn(headers, hdr->header, process_tags(hdr, r));
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding break;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding case hdr_append:
3becbd2611ffb2e8391a8eacce765b43dcb1c669wrowe apr_table_mergen(headers, hdr->header, process_tags(hdr, r));
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding break;
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd case hdr_merge:
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd val = apr_table_get(headers, hdr->header);
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd if (val == NULL) {
3becbd2611ffb2e8391a8eacce765b43dcb1c669wrowe apr_table_addn(headers, hdr->header, process_tags(hdr, r));
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd } else {
3becbd2611ffb2e8391a8eacce765b43dcb1c669wrowe char *new_val = process_tags(hdr, r);
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd apr_size_t new_val_len = strlen(new_val);
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd int tok_found = 0;
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd /* modified version of logic in ap_get_token() */
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd while (*val) {
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd const char *tok_start;
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd
75b4c883b2ef72e0104b8b206f3408dbd1d36768jailletc while (apr_isspace(*val))
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd ++val;
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd tok_start = val;
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd while (*val && *val != ',') {
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd if (*val++ == '"')
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd while (*val)
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd if (*val++ == '"')
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd break;
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd }
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd
af6b55efc443f33e7f1d7f05ba7011781c28f02fwrowe if (new_val_len == (apr_size_t)(val - tok_start)
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd && !strncmp(tok_start, new_val, new_val_len)) {
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd tok_found = 1;
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd break;
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd }
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd if (*val)
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd ++val;
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd }
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd if (!tok_found) {
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd apr_table_mergen(headers, hdr->header, new_val);
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd }
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd }
22a7cd38c192adb811c7ab9bcba7b9261bf1c9edchrisd break;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding case hdr_set:
0aa9d47a4fd62b44cbf9a18b07f1949f9e8f0931issac if (!strcasecmp(hdr->header, "Content-Type")) {
3becbd2611ffb2e8391a8eacce765b43dcb1c669wrowe ap_set_content_type(r, process_tags(hdr, r));
0aa9d47a4fd62b44cbf9a18b07f1949f9e8f0931issac }
3becbd2611ffb2e8391a8eacce765b43dcb1c669wrowe apr_table_setn(headers, hdr->header, process_tags(hdr, r));
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding break;
45dffe6c346dd73571ccaead10295fc7d53b59a6covener case hdr_setifempty:
45dffe6c346dd73571ccaead10295fc7d53b59a6covener if (NULL == apr_table_get(headers, hdr->header)) {
45dffe6c346dd73571ccaead10295fc7d53b59a6covener if (!strcasecmp(hdr->header, "Content-Type")) {
45dffe6c346dd73571ccaead10295fc7d53b59a6covener ap_set_content_type(r, process_tags(hdr, r));
45dffe6c346dd73571ccaead10295fc7d53b59a6covener }
45dffe6c346dd73571ccaead10295fc7d53b59a6covener apr_table_setn(headers, hdr->header, process_tags(hdr, r));
45dffe6c346dd73571ccaead10295fc7d53b59a6covener }
45dffe6c346dd73571ccaead10295fc7d53b59a6covener break;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding case hdr_unset:
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard apr_table_unset(headers, hdr->header);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding break;
3bc407b46a67691f3e5fd4f5f5ead4e1eff09998stoddard case hdr_echo:
3bc407b46a67691f3e5fd4f5f5ead4e1eff09998stoddard v.r = r;
3bc407b46a67691f3e5fd4f5f5ead4e1eff09998stoddard v.hdr = hdr;
e8f95a682820a599fe41b22977010636be5c2717jim apr_table_do((int (*) (void *, const char *, const char *))
3bc407b46a67691f3e5fd4f5f5ead4e1eff09998stoddard echo_header, (void *) &v, r->headers_in, NULL);
3bc407b46a67691f3e5fd4f5f5ead4e1eff09998stoddard break;
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq case hdr_edit:
64dbb5532fba398c5e81efeb21c7fd50c05819d7niq case hdr_edit_r:
3a183ee5b8f8129f6d3ec493be51abacda7c6ea7niq if (!strcasecmp(hdr->header, "Content-Type") && r->content_type) {
88fa154e9a87c35cf4ee74d46f095f66fe897d0edruggeri const char *repl = process_regexp(hdr, r->content_type, r);
51254470cbee1458031e364c8126e75ff07d225fsf if (repl == NULL)
51254470cbee1458031e364c8126e75ff07d225fsf return 0;
51254470cbee1458031e364c8126e75ff07d225fsf ap_set_content_type(r, repl);
3a183ee5b8f8129f6d3ec493be51abacda7c6ea7niq }
6951fc02abfd7642e45333902c14855836717fadrpluem if (apr_table_get(headers, hdr->header)) {
6951fc02abfd7642e45333902c14855836717fadrpluem edit_do ed;
6951fc02abfd7642e45333902c14855836717fadrpluem
88fa154e9a87c35cf4ee74d46f095f66fe897d0edruggeri ed.r = r;
6951fc02abfd7642e45333902c14855836717fadrpluem ed.hdr = hdr;
6951fc02abfd7642e45333902c14855836717fadrpluem ed.t = apr_table_make(r->pool, 5);
51254470cbee1458031e364c8126e75ff07d225fsf if (!apr_table_do(edit_header, (void *) &ed, headers,
51254470cbee1458031e364c8126e75ff07d225fsf hdr->header, NULL))
51254470cbee1458031e364c8126e75ff07d225fsf return 0;
6951fc02abfd7642e45333902c14855836717fadrpluem apr_table_unset(headers, hdr->header);
6951fc02abfd7642e45333902c14855836717fadrpluem apr_table_do(add_them_all, (void *) headers, ed.t, NULL);
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq }
13c7ff50f27aefa2594d33089fcff6ceb9796fe7niq break;
4b3f656d2ad030be85d219e02fdc11546ddecb5ccovener case hdr_note:
4b3f656d2ad030be85d219e02fdc11546ddecb5ccovener apr_table_setn(r->notes, process_tags(hdr, r), apr_table_get(headers, hdr->header));
4b3f656d2ad030be85d219e02fdc11546ddecb5ccovener break;
4b3f656d2ad030be85d219e02fdc11546ddecb5ccovener
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
51254470cbee1458031e364c8126e75ff07d225fsf return 1;
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard}
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddardstatic void ap_headers_insert_output_filter(request_rec *r)
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard{
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard headers_conf *dirconf = ap_get_module_config(r->per_dir_config,
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard &headers_module);
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard
08eb8303a91265264085e646f5937c76ae1e0c5bnd if (dirconf->fixup_out->nelts || dirconf->fixup_err->nelts) {
a47a28784ca46876076471d2a0b45c11f800bffestoddard ap_add_output_filter("FIXUP_HEADERS_OUT", NULL, r, r->connection);
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard }
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard}
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar/*
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar * Make sure our error-path filter is in place.
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar */
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coarstatic void ap_headers_insert_error_filter(request_rec *r)
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar{
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar headers_conf *dirconf = ap_get_module_config(r->per_dir_config,
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar &headers_module);
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar
08eb8303a91265264085e646f5937c76ae1e0c5bnd if (dirconf->fixup_err->nelts) {
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar ap_add_output_filter("FIXUP_HEADERS_ERR", NULL, r, r->connection);
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar }
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar}
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddardstatic apr_status_t ap_headers_output_filter(ap_filter_t *f,
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard apr_bucket_brigade *in)
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard{
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard headers_conf *dirconf = ap_get_module_config(f->r->per_dir_config,
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard &headers_module);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
5f311c280b145c6a435cddb9ab98c9e87a17ce94covener ap_log_error(APLOG_MARK, APLOG_TRACE2, 0, f->r->server, APLOGNO(01502)
a47a28784ca46876076471d2a0b45c11f800bffestoddard "headers: ap_headers_output_filter()");
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard /* do the fixup */
cf82d17373559b6163dbd6c844c1af82cab56883niq do_headers_fixup(f->r, f->r->err_headers_out, dirconf->fixup_err, 0);
cf82d17373559b6163dbd6c844c1af82cab56883niq do_headers_fixup(f->r, f->r->headers_out, dirconf->fixup_out, 0);
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard /* remove ourselves from the filter chain */
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard ap_remove_output_filter(f);
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard /* send the data up the stack */
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard return ap_pass_brigade(f->next,in);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar/*
174a8f105b1c11aa50a05993ea8ba2d117d3df6end * Make sure we propagate any "Header always" settings on the error
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar * path through http_protocol.c.
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar */
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coarstatic apr_status_t ap_headers_error_filter(ap_filter_t *f,
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar apr_bucket_brigade *in)
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar{
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar headers_conf *dirconf;
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar dirconf = ap_get_module_config(f->r->per_dir_config,
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar &headers_module);
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, f->r->server, APLOGNO(01503)
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar "headers: ap_headers_error_filter()");
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar /*
174a8f105b1c11aa50a05993ea8ba2d117d3df6end * Add any header fields defined by "Header always" to r->err_headers_out.
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar * Server-wide first, then per-directory to allow overriding.
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar */
cf82d17373559b6163dbd6c844c1af82cab56883niq do_headers_fixup(f->r, f->r->err_headers_out, dirconf->fixup_err, 0);
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar /*
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar * We've done our bit; remove ourself from the filter chain so there's
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar * no possibility we'll be called again.
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar */
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar ap_remove_output_filter(f);
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar /*
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar * Pass the buck. (euro?)
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar */
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar return ap_pass_brigade(f->next, in);
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar}
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddardstatic apr_status_t ap_headers_fixup(request_rec *r)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
a6b9ed64fdf548c61de9714e2cfb999ec59d149cgstein headers_conf *dirconf = ap_get_module_config(r->per_dir_config,
a6b9ed64fdf548c61de9714e2cfb999ec59d149cgstein &headers_module);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard /* do the fixup */
08eb8303a91265264085e646f5937c76ae1e0c5bnd if (dirconf->fixup_in->nelts) {
cf82d17373559b6163dbd6c844c1af82cab56883niq do_headers_fixup(r, r->headers_in, dirconf->fixup_in, 0);
cf82d17373559b6163dbd6c844c1af82cab56883niq }
cf82d17373559b6163dbd6c844c1af82cab56883niq
cf82d17373559b6163dbd6c844c1af82cab56883niq return DECLINED;
cf82d17373559b6163dbd6c844c1af82cab56883niq}
cf82d17373559b6163dbd6c844c1af82cab56883niqstatic apr_status_t ap_headers_early(request_rec *r)
cf82d17373559b6163dbd6c844c1af82cab56883niq{
cf82d17373559b6163dbd6c844c1af82cab56883niq headers_conf *dirconf = ap_get_module_config(r->per_dir_config,
cf82d17373559b6163dbd6c844c1af82cab56883niq &headers_module);
cf82d17373559b6163dbd6c844c1af82cab56883niq
cf82d17373559b6163dbd6c844c1af82cab56883niq /* do the fixup */
cf82d17373559b6163dbd6c844c1af82cab56883niq if (dirconf->fixup_in->nelts) {
51254470cbee1458031e364c8126e75ff07d225fsf if (!do_headers_fixup(r, r->headers_in, dirconf->fixup_in, 1))
51254470cbee1458031e364c8126e75ff07d225fsf goto err;
cf82d17373559b6163dbd6c844c1af82cab56883niq }
cf82d17373559b6163dbd6c844c1af82cab56883niq if (dirconf->fixup_err->nelts) {
51254470cbee1458031e364c8126e75ff07d225fsf if (!do_headers_fixup(r, r->err_headers_out, dirconf->fixup_err, 1))
51254470cbee1458031e364c8126e75ff07d225fsf goto err;
cf82d17373559b6163dbd6c844c1af82cab56883niq }
cf82d17373559b6163dbd6c844c1af82cab56883niq if (dirconf->fixup_out->nelts) {
51254470cbee1458031e364c8126e75ff07d225fsf if (!do_headers_fixup(r, r->headers_out, dirconf->fixup_out, 1))
51254470cbee1458031e364c8126e75ff07d225fsf goto err;
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding return DECLINED;
51254470cbee1458031e364c8126e75ff07d225fsferr:
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(01504)
51254470cbee1458031e364c8126e75ff07d225fsf "Regular expression replacement failed (replacement too long?)");
51254470cbee1458031e364c8126e75ff07d225fsf return HTTP_INTERNAL_SERVER_ERROR;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
08eb8303a91265264085e646f5937c76ae1e0c5bnd
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddardstatic const command_rec headers_cmds[] =
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard{
26f56d4a3c12077d605362e97490e34522fa4814covener AP_INIT_RAW_ARGS("Header", header_cmd, &hdr_out_onsuccess, OR_FILEINFO,
174a8f105b1c11aa50a05993ea8ba2d117d3df6end "an optional condition, an action, header and value "
174a8f105b1c11aa50a05993ea8ba2d117d3df6end "followed by optional env clause"),
08eb8303a91265264085e646f5937c76ae1e0c5bnd AP_INIT_RAW_ARGS("RequestHeader", header_cmd, &hdr_in, OR_FILEINFO,
89ea31761658f422cf21cd3b0224dc5fe95cccd3nd "an action, header and value followed by optional env "
89ea31761658f422cf21cd3b0224dc5fe95cccd3nd "clause"),
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard {NULL}
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard};
73e8b26287de5c06fa470d36162e103dbac9c7e5wrowe
ce21d498b0473ab1a89c13d4da979d2b7019c1b5ndstatic void register_format_tag_handler(const char *tag,
3b60bc6cafbb662cb3edc70c1df81c8deb31175ajorton format_tag_fn *tag_handler)
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard{
ce21d498b0473ab1a89c13d4da979d2b7019c1b5nd apr_hash_set(format_tag_hash, tag, 1, tag_handler);
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard}
ce21d498b0473ab1a89c13d4da979d2b7019c1b5nd
417f504d4d11631c0d062be85347f82a26c88677aaronstatic int header_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp)
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard{
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard format_tag_hash = apr_hash_make(p);
3b60bc6cafbb662cb3edc70c1df81c8deb31175ajorton register_format_tag_handler("D", header_request_duration);
3b60bc6cafbb662cb3edc70c1df81c8deb31175ajorton register_format_tag_handler("t", header_request_time);
3b60bc6cafbb662cb3edc70c1df81c8deb31175ajorton register_format_tag_handler("e", header_request_env_var);
3b60bc6cafbb662cb3edc70c1df81c8deb31175ajorton register_format_tag_handler("s", header_request_ssl_var);
0b1e2711d8332fb10ca0a889f17dba261758e893jim register_format_tag_handler("l", header_request_loadavg);
0b1e2711d8332fb10ca0a889f17dba261758e893jim register_format_tag_handler("i", header_request_idle);
0b1e2711d8332fb10ca0a889f17dba261758e893jim register_format_tag_handler("b", header_request_busy);
ce21d498b0473ab1a89c13d4da979d2b7019c1b5nd
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton return OK;
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton}
417f504d4d11631c0d062be85347f82a26c88677aaron
77f0db50b7e6636f6422de76ffb2a0af7acaed6djortonstatic int header_post_config(apr_pool_t *pconf, apr_pool_t *plog,
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton apr_pool_t *ptemp, server_rec *s)
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton{
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton header_ssl_lookup = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup);
417f504d4d11631c0d062be85347f82a26c88677aaron return OK;
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard}
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard
73e8b26287de5c06fa470d36162e103dbac9c7e5wrowestatic void register_hooks(apr_pool_t *p)
577a76180006add04a166b12f1ad130aeedeaa5estoddard{
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar ap_register_output_filter("FIXUP_HEADERS_OUT", ap_headers_output_filter,
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar NULL, AP_FTYPE_CONTENT_SET);
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar ap_register_output_filter("FIXUP_HEADERS_ERR", ap_headers_error_filter,
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar NULL, AP_FTYPE_CONTENT_SET);
fd0075570654d8f3473f12c47f507c8b3c59a8e4stoddard ap_hook_pre_config(header_pre_config,NULL,NULL,APR_HOOK_MIDDLE);
77f0db50b7e6636f6422de76ffb2a0af7acaed6djorton ap_hook_post_config(header_post_config,NULL,NULL,APR_HOOK_MIDDLE);
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard ap_hook_insert_filter(ap_headers_insert_output_filter, NULL, NULL, APR_HOOK_LAST);
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar ap_hook_insert_error_filter(ap_headers_insert_error_filter,
71f3601de4983bc2a6aaffcf37dc1d35c8674a34coar NULL, NULL, APR_HOOK_LAST);
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard ap_hook_fixups(ap_headers_fixup, NULL, NULL, APR_HOOK_LAST);
cf82d17373559b6163dbd6c844c1af82cab56883niq ap_hook_post_read_request(ap_headers_early, NULL, NULL, APR_HOOK_FIRST);
ea92d0ffcb30b186010a2c8ca2c80d2ac09e34dastoddard}
73e8b26287de5c06fa470d36162e103dbac9c7e5wrowe
36ef8f77bffe75d1aa327882be1b5bdbe2ff567asfAP_DECLARE_MODULE(headers) =
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
577a76180006add04a166b12f1ad130aeedeaa5estoddard STANDARD20_MODULE_STUFF,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding create_headers_dir_config, /* dir config creater */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding merge_headers_config, /* dir merger --- default is to override */
08eb8303a91265264085e646f5937c76ae1e0c5bnd NULL, /* server config */
08eb8303a91265264085e646f5937c76ae1e0c5bnd NULL, /* merge server configs */
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm headers_cmds, /* command apr_table_t */
b3e877bb7c9c24fc84a9d7285ce848d99e81d57end register_hooks /* register hooks */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding};