~ubuntu-branches/ubuntu/natty/lighttpd/natty

« back to all changes in this revision

Viewing changes to src/mod_setenv.c

  • Committer: Bazaar Package Importer
  • Author(s): Torsten Marek
  • Date: 2005-11-26 11:48:51 UTC
  • Revision ID: james.westby@ubuntu.com-20051126114851-76t9q0rrwbzjnt2t
Tags: upstream-1.4.8
ImportĀ upstreamĀ versionĀ 1.4.8

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <stdlib.h>
 
2
#include <string.h>
 
3
 
 
4
#include "base.h"
 
5
#include "log.h"
 
6
#include "buffer.h"
 
7
 
 
8
#include "plugin.h"
 
9
 
 
10
#include "response.h"
 
11
 
 
12
/* plugin config for all request/connections */
 
13
 
 
14
typedef struct {
 
15
        array *request_header;
 
16
        array *response_header;
 
17
        
 
18
        array *environment;
 
19
} plugin_config;
 
20
 
 
21
typedef struct {
 
22
        PLUGIN_DATA;
 
23
        
 
24
        plugin_config **config_storage;
 
25
        
 
26
        plugin_config conf; 
 
27
} plugin_data;
 
28
 
 
29
/* init the plugin data */
 
30
INIT_FUNC(mod_setenv_init) {
 
31
        plugin_data *p;
 
32
        
 
33
        p = calloc(1, sizeof(*p));
 
34
        
 
35
        return p;
 
36
}
 
37
 
 
38
/* detroy the plugin data */
 
39
FREE_FUNC(mod_setenv_free) {
 
40
        plugin_data *p = p_d;
 
41
        
 
42
        UNUSED(srv);
 
43
 
 
44
        if (!p) return HANDLER_GO_ON;
 
45
        
 
46
        if (p->config_storage) {
 
47
                size_t i;
 
48
                for (i = 0; i < srv->config_context->used; i++) {
 
49
                        plugin_config *s = p->config_storage[i];
 
50
                        
 
51
                        array_free(s->request_header);
 
52
                        array_free(s->response_header);
 
53
                        array_free(s->environment);
 
54
                        
 
55
                        free(s);
 
56
                }
 
57
                free(p->config_storage);
 
58
        }
 
59
        
 
60
        free(p);
 
61
        
 
62
        return HANDLER_GO_ON;
 
63
}
 
64
 
 
65
/* handle plugin config and check values */
 
66
 
 
67
SETDEFAULTS_FUNC(mod_setenv_set_defaults) {
 
68
        plugin_data *p = p_d;
 
69
        size_t i = 0;
 
70
        
 
71
        config_values_t cv[] = { 
 
72
                { "setenv.add-request-header",  NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
 
73
                { "setenv.add-response-header", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 1 */
 
74
                { "setenv.add-environment",     NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 2 */
 
75
                { NULL,                         NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
 
76
        };
 
77
        
 
78
        if (!p) return HANDLER_ERROR;
 
79
        
 
80
        p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
 
81
        
 
82
        for (i = 0; i < srv->config_context->used; i++) {
 
83
                plugin_config *s;
 
84
                
 
85
                s = calloc(1, sizeof(plugin_config));
 
86
                s->request_header   = array_init();
 
87
                s->response_header  = array_init();
 
88
                s->environment      = array_init();
 
89
                
 
90
                cv[0].destination = s->request_header;
 
91
                cv[1].destination = s->response_header;
 
92
                cv[2].destination = s->environment;
 
93
                
 
94
                p->config_storage[i] = s;
 
95
        
 
96
                if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
 
97
                        return HANDLER_ERROR;
 
98
                }
 
99
        }
 
100
        
 
101
        return HANDLER_GO_ON;
 
102
}
 
103
 
 
104
#define PATCH(x) \
 
105
        p->conf.x = s->x;
 
106
static int mod_setenv_patch_connection(server *srv, connection *con, plugin_data *p) {
 
107
        size_t i, j;
 
108
        plugin_config *s = p->config_storage[0];
 
109
        
 
110
        PATCH(request_header);
 
111
        PATCH(response_header);
 
112
        PATCH(environment);
 
113
        
 
114
        /* skip the first, the global context */
 
115
        for (i = 1; i < srv->config_context->used; i++) {
 
116
                data_config *dc = (data_config *)srv->config_context->data[i];
 
117
                s = p->config_storage[i];
 
118
                
 
119
                /* condition didn't match */
 
120
                if (!config_check_cond(srv, con, dc)) continue;
 
121
                
 
122
                /* merge config */
 
123
                for (j = 0; j < dc->value->used; j++) {
 
124
                        data_unset *du = dc->value->data[j];
 
125
                        
 
126
                        if (buffer_is_equal_string(du->key, CONST_STR_LEN("setenv.add-request-header"))) {
 
127
                                PATCH(request_header);
 
128
                        } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("setenv.add-response-header"))) {
 
129
                                PATCH(response_header);
 
130
                        } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("setenv.add-environment"))) {
 
131
                                PATCH(environment);
 
132
                        }
 
133
                }
 
134
        }
 
135
        
 
136
        return 0;
 
137
}
 
138
#undef PATCH
 
139
 
 
140
URIHANDLER_FUNC(mod_setenv_uri_handler) {
 
141
        plugin_data *p = p_d;
 
142
        size_t k;
 
143
        
 
144
        mod_setenv_patch_connection(srv, con, p);
 
145
 
 
146
        for (k = 0; k < p->conf.request_header->used; k++) {
 
147
                data_string *ds = (data_string *)p->conf.request_header->data[k];
 
148
                data_string *ds_dst;
 
149
                
 
150
                if (NULL == (ds_dst = (data_string *)array_get_unused_element(con->request.headers, TYPE_STRING))) {
 
151
                        ds_dst = data_string_init();
 
152
                }
 
153
                
 
154
                buffer_copy_string_buffer(ds_dst->key, ds->key);
 
155
                buffer_copy_string_buffer(ds_dst->value, ds->value);
 
156
                
 
157
                array_insert_unique(con->request.headers, (data_unset *)ds_dst);
 
158
        }
 
159
        
 
160
        for (k = 0; k < p->conf.environment->used; k++) {
 
161
                data_string *ds = (data_string *)p->conf.environment->data[k];
 
162
                data_string *ds_dst;
 
163
                
 
164
                if (NULL == (ds_dst = (data_string *)array_get_unused_element(con->environment, TYPE_STRING))) {
 
165
                        ds_dst = data_string_init();
 
166
                }
 
167
                
 
168
                buffer_copy_string_buffer(ds_dst->key, ds->key);
 
169
                buffer_copy_string_buffer(ds_dst->value, ds->value);
 
170
                
 
171
                array_insert_unique(con->environment, (data_unset *)ds_dst);
 
172
        }
 
173
        
 
174
        for (k = 0; k < p->conf.response_header->used; k++) {
 
175
                data_string *ds = (data_string *)p->conf.response_header->data[k];
 
176
                
 
177
                response_header_insert(srv, con, CONST_BUF_LEN(ds->key), CONST_BUF_LEN(ds->value));
 
178
        }
 
179
        
 
180
        /* not found */
 
181
        return HANDLER_GO_ON;
 
182
}
 
183
 
 
184
/* this function is called at dlopen() time and inits the callbacks */
 
185
 
 
186
int mod_setenv_plugin_init(plugin *p) {
 
187
        p->version     = LIGHTTPD_VERSION_ID;
 
188
        p->name        = buffer_init_string("setenv");
 
189
        
 
190
        p->init        = mod_setenv_init;
 
191
        p->handle_uri_clean  = mod_setenv_uri_handler;
 
192
        p->set_defaults  = mod_setenv_set_defaults;
 
193
        p->cleanup     = mod_setenv_free;
 
194
        
 
195
        p->data        = NULL;
 
196
        
 
197
        return 0;
 
198
}