73
73
/* create the cache context */
74
74
static void *oidc_cache_memcache_cfg_create(apr_pool_t *pool) {
75
oidc_cache_cfg_memcache_t *context = apr_pcalloc(pool, sizeof(oidc_cache_cfg_memcache_t));
75
oidc_cache_cfg_memcache_t *context = apr_pcalloc(pool,
76
sizeof(oidc_cache_cfg_memcache_t));
76
77
context->cache_memcache = NULL;
81
82
* initialize the memcache struct to a number of memcache servers
83
84
static int oidc_cache_memcache_post_config(server_rec *s) {
84
oidc_cfg *cfg = (oidc_cfg *) ap_get_module_config(
85
s->module_config, &auth_openidc_module);
85
oidc_cfg *cfg = (oidc_cfg *) ap_get_module_config(s->module_config,
86
&auth_openidc_module);
87
if (cfg->cache_cfg != NULL) return APR_SUCCESS;
88
oidc_cache_cfg_memcache_t *context = oidc_cache_memcache_cfg_create(s->process->pool);
88
if (cfg->cache_cfg != NULL)
90
oidc_cache_cfg_memcache_t *context = oidc_cache_memcache_cfg_create(
89
92
cfg->cache_cfg = context;
91
94
apr_status_t rv = APR_SUCCESS;
95
98
apr_pool_t *p = s->process->pool;
97
100
if (cfg->cache_memcache_servers == NULL) {
98
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
99
"oidc_cache_memcache_post_config: cache type is set to \"memcache\", but no valid OIDCMemCacheServers setting was found");
102
"cache type is set to \"memcache\", but no valid OIDCMemCacheServers setting was found");
100
103
return HTTP_INTERNAL_SERVER_ERROR;
111
114
/* allocated space for the number of servers */
112
115
rv = apr_memcache_create(p, nservers, 0, &context->cache_memcache);
113
116
if (rv != APR_SUCCESS) {
114
ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
115
"oidc_cache_memcache_init: failed to create memcache object of '%d' size",
117
oidc_serror(s, "failed to create memcache object of '%d' size",
117
119
return HTTP_INTERNAL_SERVER_ERROR;
129
131
/* parse out host and port */
130
132
rv = apr_parse_addr_port(&host_str, &scope_id, &port, split, p);
131
133
if (rv != APR_SUCCESS) {
132
ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
133
"oidc_cache_memcache_init: failed to parse cache server: '%s'",
134
oidc_serror(s, "failed to parse cache server: '%s'", split);
135
return HTTP_INTERNAL_SERVER_ERROR;
138
if (host_str == NULL) {
140
"failed to parse cache server, no hostname specified: '%s'",
135
142
return HTTP_INTERNAL_SERVER_ERROR;
138
if (host_str == NULL) {
139
ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
140
"oidc_cache_memcache_init: failed to parse cache server, "
141
"no hostname specified: '%s'", split);
142
return HTTP_INTERNAL_SERVER_ERROR;
149
149
// TODO: tune this
150
150
rv = apr_memcache_server_create(p, host_str, port, 0, 1, 1, 60, &st);
151
151
if (rv != APR_SUCCESS) {
152
ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
153
"oidc_cache_memcache_init: failed to create cache server: %s:%d",
152
oidc_serror(s, "failed to create cache server: %s:%d", host_str,
155
154
return HTTP_INTERNAL_SERVER_ERROR;
158
157
/* add the memcache server struct to the list */
159
158
rv = apr_memcache_add_server(context->cache_memcache, st);
160
159
if (rv != APR_SUCCESS) {
161
ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
162
"oidc_cache_memcache_init: failed to add cache server: %s:%d",
160
oidc_serror(s, "failed to add cache server: %s:%d", host_str, port);
164
161
return HTTP_INTERNAL_SERVER_ERROR;
172
* assemble single key name based on section/key input
174
static char *oidc_cache_memcache_get_key(apr_pool_t *pool, const char *section,
176
return apr_psprintf(pool, "%s:%s", section, key);
175
180
* get a name/value pair from memcache
177
static apr_byte_t oidc_cache_memcache_get(request_rec *r, const char *key,
178
const char **value) {
182
static apr_byte_t oidc_cache_memcache_get(request_rec *r, const char *section,
183
const char *key, const char **value) {
180
ap_log_rerror(APLOG_MARK, OIDC_DEBUG, 0, r,
181
"oidc_cache_memcache_get: entering \"%s\"", key);
185
oidc_debug(r, "enter, section=\"%s\", key=\"%s\"", section, key);
183
187
oidc_cfg *cfg = ap_get_module_config(r->server->module_config,
184
188
&auth_openidc_module);
185
oidc_cache_cfg_memcache_t *context = (oidc_cache_cfg_memcache_t *)cfg->cache_cfg;
189
oidc_cache_cfg_memcache_t *context =
190
(oidc_cache_cfg_memcache_t *) cfg->cache_cfg;
187
192
apr_size_t len = 0;
190
apr_status_t rv = apr_memcache_getp(context->cache_memcache, r->pool, key,
191
(char **)value, &len, NULL);
195
apr_status_t rv = apr_memcache_getp(context->cache_memcache, r->pool,
196
oidc_cache_memcache_get_key(r->pool, section, key), (char **) value,
193
199
// TODO: error strings ?
194
200
if (rv != APR_SUCCESS) {
195
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
196
"oidc_cache_memcache_get: apr_memcache_getp returned an error");
201
oidc_error(r, "apr_memcache_getp returned an error");
200
205
/* do sanity checking on the string value */
201
if ( (*value) && (strlen(*value) != len) ) {
202
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
203
"oidc_cache_memcache_get: apr_memcache_getp returned less bytes than expected: strlen(value) [%zu] != len [%" APR_SIZE_T_FMT "]", strlen(*value), len);
206
if ((*value) && (strlen(*value) != len)) {
208
"apr_memcache_getp returned less bytes than expected: strlen(value) [%zu] != len [%" APR_SIZE_T_FMT "]",
209
strlen(*value), len);
211
217
* store a name/value pair in memcache
213
static apr_byte_t oidc_cache_memcache_set(request_rec *r, const char *key,
214
const char *value, apr_time_t expiry) {
219
static apr_byte_t oidc_cache_memcache_set(request_rec *r, const char *section,
220
const char *key, const char *value, apr_time_t expiry) {
216
ap_log_rerror(APLOG_MARK, OIDC_DEBUG, 0, r,
217
"oidc_cache_memcache_set: entering \"%s\"", key);
222
oidc_debug(r, "enter, section=\"%s\", key=\"%s\"", section, key);
219
224
oidc_cfg *cfg = ap_get_module_config(r->server->module_config,
220
225
&auth_openidc_module);
221
oidc_cache_cfg_memcache_t *context = (oidc_cache_cfg_memcache_t *)cfg->cache_cfg;
226
oidc_cache_cfg_memcache_t *context =
227
(oidc_cache_cfg_memcache_t *) cfg->cache_cfg;
223
229
apr_status_t rv = APR_SUCCESS;
225
231
/* see if we should be clearing this entry */
226
232
if (value == NULL) {
228
rv = apr_memcache_delete(context->cache_memcache, key, 0);
234
rv = apr_memcache_delete(context->cache_memcache,
235
oidc_cache_memcache_get_key(r->pool, section, key), 0);
230
237
// TODO: error strings ?
231
238
if (rv != APR_SUCCESS) {
232
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
233
"oidc_cache_memcache_set: apr_memcache_delete returned an error");
239
oidc_error(r, "apr_memcache_delete returned an error");
239
245
apr_uint32_t timeout = apr_time_sec(expiry - apr_time_now());
242
rv = apr_memcache_set(context->cache_memcache, key, (char *)value,
243
strlen(value), timeout, 0);
248
rv = apr_memcache_set(context->cache_memcache,
249
oidc_cache_memcache_get_key(r->pool, section, key),
250
(char *) value, strlen(value), timeout, 0);
245
252
// TODO: error strings ?
246
253
if (rv != APR_SUCCESS) {
247
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
248
"oidc_cache_memcache_set: apr_memcache_set returned an error");
254
oidc_error(r, "apr_memcache_set returned an error");