1 #include "first.h"
2
3 #include <stdlib.h>
4 #include <string.h>
5
6 #include "plugin.h"
7
8 #include "log.h"
9 #include "buffer.h"
10 #include "array.h"
11 #include "request.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(void) {
45 return ck_calloc(1, sizeof(handler_ctx));
46 }
47
48 static void handler_ctx_free(handler_ctx *hctx) {
49 free(hctx);
50 }
51
52 #endif
53
54
55 /* init the plugin data */
INIT_FUNC(mod_skeleton_init)56 INIT_FUNC(mod_skeleton_init) {
57 return ck_calloc(1, sizeof(plugin_data));
58 }
59
60 /* handle plugin config and check values */
61
mod_skeleton_merge_config_cpv(plugin_config * const pconf,const config_plugin_value_t * const cpv)62 static void mod_skeleton_merge_config_cpv(plugin_config * const pconf, const config_plugin_value_t * const cpv) {
63 switch (cpv->k_id) { /* index into static config_plugin_keys_t cpk[] */
64 case 0: /* skeleton.array */
65 pconf->match = cpv->v.a;
66 break;
67 default:/* should not happen */
68 return;
69 }
70 }
71
mod_skeleton_merge_config(plugin_config * const pconf,const config_plugin_value_t * cpv)72 static void mod_skeleton_merge_config(plugin_config * const pconf, const config_plugin_value_t *cpv) {
73 do {
74 mod_skeleton_merge_config_cpv(pconf, cpv);
75 } while ((++cpv)->k_id != -1);
76 }
77
mod_skeleton_patch_config(request_st * const r,plugin_data * const p)78 static void mod_skeleton_patch_config(request_st * const r, plugin_data * const p) {
79 p->conf = p->defaults; /* copy small struct instead of memcpy() */
80 /*memcpy(&p->conf, &p->defaults, sizeof(plugin_config));*/
81 for (int i = 1, used = p->nconfig; i < used; ++i) {
82 if (config_check_cond(r, (uint32_t)p->cvlist[i].k_id))
83 mod_skeleton_merge_config(&p->conf, p->cvlist+p->cvlist[i].v.u2[0]);
84 }
85 }
86
SETDEFAULTS_FUNC(mod_skeleton_set_defaults)87 SETDEFAULTS_FUNC(mod_skeleton_set_defaults) {
88 static const config_plugin_keys_t cpk[] = {
89 { CONST_STR_LEN("skeleton.array"),
90 T_CONFIG_ARRAY_VLIST,
91 T_CONFIG_SCOPE_CONNECTION }
92 ,{ NULL, 0,
93 T_CONFIG_UNSET,
94 T_CONFIG_SCOPE_UNSET }
95 };
96
97 plugin_data * const p = p_d;
98 if (!config_plugin_values_init(srv, p, cpk, "mod_skeleton"))
99 return HANDLER_ERROR;
100
101 /* initialize p->defaults from global config context */
102 if (p->nconfig > 0 && p->cvlist->v.u2[1]) {
103 const config_plugin_value_t *cpv = p->cvlist + p->cvlist->v.u2[0];
104 if (-1 != cpv->k_id)
105 mod_skeleton_merge_config(&p->defaults, cpv);
106 }
107
108 return HANDLER_GO_ON;
109 }
110
URIHANDLER_FUNC(mod_skeleton_uri_handler)111 URIHANDLER_FUNC(mod_skeleton_uri_handler) {
112 plugin_data * const p = p_d;
113
114 /* determine whether or not module participates in request */
115
116 if (NULL != r->handler_module) return HANDLER_GO_ON;
117 if (buffer_is_blank(&r->uri.path)) return HANDLER_GO_ON;
118
119 /* get module config for request */
120 mod_skeleton_patch_config(r, p);
121
122 if (NULL == p->conf.match
123 || NULL == array_match_value_suffix(p->conf.match, &r->uri.path)) {
124 return HANDLER_GO_ON;
125 }
126
127 /* module participates in request; business logic here */
128
129 r->http_status = 403; /* example: reject request with 403 Forbidden */
130 return HANDLER_FINISHED;
131 }
132
133
134 /* this function is called at dlopen() time and inits the callbacks */
135 __attribute_cold__
136 int mod_skeleton_plugin_init(plugin *p);
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