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

« back to all changes in this revision

Viewing changes to src/mod_indexfile.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 <ctype.h>
 
2
#include <stdlib.h>
 
3
#include <string.h>
 
4
#include <errno.h>
 
5
 
 
6
 
 
7
#include "base.h"
 
8
#include "log.h"
 
9
#include "buffer.h"
 
10
 
 
11
#include "plugin.h"
 
12
 
 
13
#include "stat_cache.h"
 
14
 
 
15
/* plugin config for all request/connections */
 
16
 
 
17
typedef struct {
 
18
        array *indexfiles;
 
19
} plugin_config;
 
20
 
 
21
typedef struct {
 
22
        PLUGIN_DATA;
 
23
        
 
24
        buffer *tmp_buf;
 
25
        
 
26
        plugin_config **config_storage;
 
27
        
 
28
        plugin_config conf; 
 
29
} plugin_data;
 
30
 
 
31
/* init the plugin data */
 
32
INIT_FUNC(mod_indexfile_init) {
 
33
        plugin_data *p;
 
34
        
 
35
        p = calloc(1, sizeof(*p));
 
36
        
 
37
        p->tmp_buf = buffer_init();
 
38
        
 
39
        return p;
 
40
}
 
41
 
 
42
/* detroy the plugin data */
 
43
FREE_FUNC(mod_indexfile_free) {
 
44
        plugin_data *p = p_d;
 
45
        
 
46
        UNUSED(srv);
 
47
 
 
48
        if (!p) return HANDLER_GO_ON;
 
49
        
 
50
        if (p->config_storage) {
 
51
                size_t i;
 
52
                for (i = 0; i < srv->config_context->used; i++) {
 
53
                        plugin_config *s = p->config_storage[i];
 
54
 
 
55
                        if (!s) continue;
 
56
                        
 
57
                        array_free(s->indexfiles);
 
58
                        
 
59
                        free(s);
 
60
                }
 
61
                free(p->config_storage);
 
62
        }
 
63
        
 
64
        buffer_free(p->tmp_buf);
 
65
        
 
66
        free(p);
 
67
        
 
68
        return HANDLER_GO_ON;
 
69
}
 
70
 
 
71
/* handle plugin config and check values */
 
72
 
 
73
SETDEFAULTS_FUNC(mod_indexfile_set_defaults) {
 
74
        plugin_data *p = p_d;
 
75
        size_t i = 0;
 
76
        
 
77
        config_values_t cv[] = { 
 
78
                { "index-file.names",           NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
 
79
                { "server.indexfiles",          NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 1 */
 
80
                { NULL,                         NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
 
81
        };
 
82
        
 
83
        if (!p) return HANDLER_ERROR;
 
84
        
 
85
        p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
 
86
        
 
87
        for (i = 0; i < srv->config_context->used; i++) {
 
88
                plugin_config *s;
 
89
                
 
90
                s = calloc(1, sizeof(plugin_config));
 
91
                s->indexfiles    = array_init();
 
92
                
 
93
                cv[0].destination = s->indexfiles;
 
94
                cv[1].destination = s->indexfiles; /* old name for [0] */
 
95
                
 
96
                p->config_storage[i] = s;
 
97
        
 
98
                if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
 
99
                        return HANDLER_ERROR;
 
100
                }
 
101
        }
 
102
        
 
103
        return HANDLER_GO_ON;
 
104
}
 
105
 
 
106
#define PATCH(x) \
 
107
        p->conf.x = s->x;
 
108
static int mod_indexfile_patch_connection(server *srv, connection *con, plugin_data *p) {
 
109
        size_t i, j;
 
110
        plugin_config *s = p->config_storage[0];
 
111
        
 
112
        PATCH(indexfiles);
 
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("server.indexfiles"))) {
 
127
                                PATCH(indexfiles);
 
128
                        } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("index-file.names"))) {
 
129
                                PATCH(indexfiles);
 
130
                        }
 
131
                }
 
132
        }
 
133
        
 
134
        return 0;
 
135
}
 
136
#undef PATCH
 
137
 
 
138
URIHANDLER_FUNC(mod_indexfile_subrequest) {
 
139
        plugin_data *p = p_d;
 
140
        size_t k;
 
141
        stat_cache_entry *sce = NULL;
 
142
        
 
143
        if (con->uri.path->used == 0) return HANDLER_GO_ON;
 
144
        if (con->uri.path->ptr[con->uri.path->used - 2] != '/') return HANDLER_GO_ON;
 
145
        
 
146
        mod_indexfile_patch_connection(srv, con, p);
 
147
        
 
148
        if (con->conf.log_request_handling) {
 
149
                log_error_write(srv, __FILE__, __LINE__,  "s",  "-- handling the request as Indexfile");
 
150
                log_error_write(srv, __FILE__, __LINE__,  "sb", "URI          :", con->uri.path);
 
151
        }
 
152
        
 
153
        /* indexfile */
 
154
        for (k = 0; k < p->conf.indexfiles->used; k++) {
 
155
                data_string *ds = (data_string *)p->conf.indexfiles->data[k];
 
156
                
 
157
                if (ds->value && ds->value->ptr[0] == '/') {
 
158
                        /* if the index-file starts with a prefix as use this file as 
 
159
                         * index-generator */
 
160
                        buffer_copy_string_buffer(p->tmp_buf, con->physical.doc_root);
 
161
                } else {
 
162
                        buffer_copy_string_buffer(p->tmp_buf, con->physical.path);
 
163
                }
 
164
                buffer_append_string_buffer(p->tmp_buf, ds->value);
 
165
                
 
166
                if (HANDLER_ERROR == stat_cache_get_entry(srv, con, p->tmp_buf, &sce)) {
 
167
                        if (errno == EACCES) {
 
168
                                con->http_status = 403;
 
169
                                buffer_reset(con->physical.path);
 
170
                                
 
171
                                return HANDLER_FINISHED;
 
172
                        }
 
173
                        
 
174
                        if (errno != ENOENT &&
 
175
                            errno != ENOTDIR) {
 
176
                                /* we have no idea what happend. let's tell the user so. */
 
177
                                
 
178
                                con->http_status = 500;
 
179
                                
 
180
                                log_error_write(srv, __FILE__, __LINE__, "ssbsb",
 
181
                                                "file not found ... or so: ", strerror(errno),
 
182
                                                con->uri.path,
 
183
                                                "->", con->physical.path);
 
184
                                
 
185
                                buffer_reset(con->physical.path);
 
186
                                
 
187
                                return HANDLER_FINISHED;
 
188
                        }
 
189
                        continue;
 
190
                }
 
191
                        
 
192
                /* rewrite uri.path to the real path (/ -> /index.php) */
 
193
                buffer_append_string_buffer(con->uri.path, ds->value);
 
194
                buffer_copy_string_buffer(con->physical.path, p->tmp_buf);
 
195
                
 
196
                /* fce is already set up a few lines above */
 
197
                
 
198
                return HANDLER_GO_ON;
 
199
        }
 
200
        
 
201
        /* not found */
 
202
        return HANDLER_GO_ON;
 
203
}
 
204
 
 
205
/* this function is called at dlopen() time and inits the callbacks */
 
206
 
 
207
int mod_indexfile_plugin_init(plugin *p) {
 
208
        p->version     = LIGHTTPD_VERSION_ID;
 
209
        p->name        = buffer_init_string("indexfile");
 
210
        
 
211
        p->init        = mod_indexfile_init;
 
212
        p->handle_subrequest_start = mod_indexfile_subrequest;
 
213
        p->set_defaults  = mod_indexfile_set_defaults;
 
214
        p->cleanup     = mod_indexfile_free;
 
215
        
 
216
        p->data        = NULL;
 
217
        
 
218
        return 0;
 
219
}