xref: /lighttpd1.4/src/mod_skeleton.c (revision 70b1af06)
1 #include "first.h"
2 
3 #include <stdlib.h>
4 #include <string.h>
5 
6 #include "plugin.h"
7 
8 #include "base.h"
9 #include "log.h"
10 #include "buffer.h"
11 #include "array.h"
12 
13 /**
14  * this is a skeleton for a lighttpd plugin
15  *
16  * just replaces every occurrence of 'skeleton' by your plugin name
17  *
18  * e.g. in vim:
19  *
20  *   :%s/skeleton/myhandler/
21  *
22  */
23 
24 
25 /* plugin config for all request/connections */
26 
27 typedef struct {
28     const array *match;
29 } plugin_config;
30 
31 typedef struct {
32     PLUGIN_DATA;
33     plugin_config defaults;
34     plugin_config conf;
35 } plugin_data;
36 
37 
38 #if 0 /* (needed if module keeps state for request) */
39 
40 typedef struct {
41 	size_t foo;
42 } handler_ctx;
43 
44 static handler_ctx * handler_ctx_init() {
45 	handler_ctx * hctx = calloc(1, sizeof(*hctx));
46 	force_assert(hctx);
47 	return hctx;
48 }
49 
50 static void handler_ctx_free(handler_ctx *hctx) {
51 	free(hctx);
52 }
53 
54 #endif
55 
56 
57 /* init the plugin data */
58 INIT_FUNC(mod_skeleton_init) {
59     return calloc(1, sizeof(plugin_data));
60 }
61 
62 /* handle plugin config and check values */
63 
64 static void mod_skeleton_merge_config_cpv(plugin_config * const pconf, const config_plugin_value_t * const cpv) {
65     switch (cpv->k_id) { /* index into static config_plugin_keys_t cpk[] */
66       case 0: /* skeleton.array */
67         pconf->match = cpv->v.a;
68         break;
69       default:/* should not happen */
70         return;
71     }
72 }
73 
74 static void mod_skeleton_merge_config(plugin_config * const pconf, const config_plugin_value_t *cpv) {
75     do {
76         mod_skeleton_merge_config_cpv(pconf, cpv);
77     } while ((++cpv)->k_id != -1);
78 }
79 
80 static void mod_skeleton_patch_config(request_st * const r, plugin_data * const p) {
81     p->conf = p->defaults; /* copy small struct instead of memcpy() */
82     /*memcpy(&p->conf, &p->defaults, sizeof(plugin_config));*/
83     for (int i = 1, used = p->nconfig; i < used; ++i) {
84         if (config_check_cond(r, (uint32_t)p->cvlist[i].k_id))
85             mod_skeleton_merge_config(&p->conf, p->cvlist+p->cvlist[i].v.u2[0]);
86     }
87 }
88 
89 SETDEFAULTS_FUNC(mod_skeleton_set_defaults) {
90     static const config_plugin_keys_t cpk[] = {
91       { CONST_STR_LEN("skeleton.array"),
92         T_CONFIG_ARRAY_VLIST,
93         T_CONFIG_SCOPE_CONNECTION }
94      ,{ NULL, 0,
95         T_CONFIG_UNSET,
96         T_CONFIG_SCOPE_UNSET }
97     };
98 
99     plugin_data * const p = p_d;
100     if (!config_plugin_values_init(srv, p, cpk, "mod_skeleton"))
101         return HANDLER_ERROR;
102 
103     /* initialize p->defaults from global config context */
104     if (p->nconfig > 0 && p->cvlist->v.u2[1]) {
105         const config_plugin_value_t *cpv = p->cvlist + p->cvlist->v.u2[0];
106         if (-1 != cpv->k_id)
107             mod_skeleton_merge_config(&p->defaults, cpv);
108     }
109 
110     return HANDLER_GO_ON;
111 }
112 
113 URIHANDLER_FUNC(mod_skeleton_uri_handler) {
114     plugin_data * const p = p_d;
115 
116     /* determine whether or not module participates in request */
117 
118     if (NULL != r->handler_module) return HANDLER_GO_ON;
119     if (buffer_string_is_empty(&r->uri.path)) return HANDLER_GO_ON;
120 
121     /* get module config for request */
122     mod_skeleton_patch_config(r, p);
123 
124     if (NULL == p->conf.match
125         || NULL == array_match_value_suffix(p->conf.match, &r->uri.path)) {
126         return HANDLER_GO_ON;
127     }
128 
129     /* module participates in request; business logic here */
130 
131     r->http_status = 403; /* example: reject request with 403 Forbidden */
132     return HANDLER_FINISHED;
133 }
134 
135 /* this function is called at dlopen() time and inits the callbacks */
136 int mod_skeleton_plugin_init(plugin *p);
137 int mod_skeleton_plugin_init(plugin *p) {
138 	p->version     = LIGHTTPD_VERSION_ID;
139 	p->name        = "skeleton";
140 	p->init        = mod_skeleton_init;
141 	p->set_defaults= mod_skeleton_set_defaults;
142 
143 	p->handle_uri_clean = mod_skeleton_uri_handler;
144 
145 	return 0;
146 }
147