mod_socache_memcache.c revision 501e60e433e1914c64f642114fbb4fb9be9e2ca9
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "httpd.h"
#include "http_config.h"
#include "apr.h"
#include "apu_version.h"
/* apr_memcache support requires >= 1.3 */
#if APU_MAJOR_VERSION > 1 || \
#define HAVE_APU_MEMCACHE 1
#endif
#ifdef HAVE_APU_MEMCACHE
#include "ap_socache.h"
#include "ap_mpm.h"
#include "http_log.h"
#include "apr_memcache.h"
/* The underlying apr_memcache system is thread safe.. */
#define MC_KEY_LEN 254
#ifndef MC_DEFAULT_SERVER_PORT
#define MC_DEFAULT_SERVER_PORT 11211
#endif
#ifndef MC_DEFAULT_SERVER_MIN
#define MC_DEFAULT_SERVER_MIN 0
#endif
#ifndef MC_DEFAULT_SERVER_SMAX
#define MC_DEFAULT_SERVER_SMAX 1
#endif
#ifndef MC_DEFAULT_SERVER_TTL
#define MC_DEFAULT_SERVER_TTL 600
#endif
struct ap_socache_instance_t {
const char *servers;
const char *tag;
};
const char *arg,
{
return "List of server names required to create memcache socache.";
}
return NULL;
}
const char *namespace,
const struct ap_socache_hints *hints,
server_rec *s, apr_pool_t *p)
{
int thread_limit = 0;
int nservers = 0;
char *cache_config;
char *split;
char *tok;
/* Find all the servers in the first run to get a total count */
while (split) {
nservers++;
}
if (rv != APR_SUCCESS) {
"socache: Failed to create Memcache Object of '%d' size.",
nservers);
return rv;
}
/* Now add each server to the memcache */
while (split) {
char *host_str;
char *scope_id;
if (rv != APR_SUCCESS) {
"socache: Failed to Parse memcache Server: '%s'", split);
return rv;
}
"socache: Failed to Parse Server, "
"no hostname specified: '%s'", split);
return APR_EINVAL;
}
if (port == 0) {
}
&st);
if (rv != APR_SUCCESS) {
"socache: Failed to Create memcache Server: %s:%d",
return rv;
}
if (rv != APR_SUCCESS) {
"socache: Failed to Add memcache Server: %s:%d",
return rv;
}
}
/* socache API constraint: */
return APR_SUCCESS;
}
{
/* noop. */
}
/* Converts (binary) id into a key prefixed by the predetermined
* namespace tag; writes output to key buffer. Returns non-zero if
* the id won't fit in the key buffer. */
{
char *cp;
unsigned int n;
return 1;
for (n = 0; n < idlen; n++) {
cp += 2;
}
*cp = '\0';
return 0;
}
apr_pool_t *p)
{
char buf[MC_KEY_LEN];
return APR_EINVAL;
}
if (rv != APR_SUCCESS) {
"scache_mc: error setting key '%s' "
return rv;
}
return APR_SUCCESS;
}
apr_pool_t *p)
{
return APR_EINVAL;
}
/* ### this could do with a subpool, but _getp looks like it will
* eat memory like it's going out of fashion anyway. */
if (rv) {
if (rv != APR_NOTFOUND) {
"scache_mc: 'retrieve' FAIL");
}
return rv;
}
"scache_mc: 'retrieve' OVERFLOW");
return APR_ENOMEM;
}
return APR_SUCCESS;
}
const unsigned char *id,
unsigned int idlen, apr_pool_t *p)
{
char buf[MC_KEY_LEN];
return APR_EINVAL;
}
if (rv != APR_SUCCESS) {
"scache_mc: error deleting key '%s' ",
buf);
}
return rv;
}
{
/* SSLModConfigRec *mc = myModConfig(r->server); */
/* TODO: Make a mod_status handler. meh. */
}
static const ap_socache_provider_t socache_mc = {
"memcache",
0,
};
#endif /* HAVE_APU_MEMCACHE */
static void register_hooks(apr_pool_t *p)
{
#ifdef HAVE_APU_MEMCACHE
&socache_mc);
#endif
}
};