static gboolean redirect_rule_parse(liServer *srv, GString *regex, GString *str, redirect_rule *rule) { gchar *pattern_str = str->str; rule->pattern = NULL; rule->regex = NULL; rule->type = REDIRECT_ABSOLUTE_URI; if (pattern_str[0] == '/') { rule->type = REDIRECT_ABSOLUTE_PATH; } else if (pattern_str[0] == '?') { rule->type = REDIRECT_RELATIVE_QUERY; } else if (g_str_has_prefix(pattern_str, "./")) { pattern_str += 2; rule->type = REDIRECT_RELATIVE_PATH; } rule->pattern = li_pattern_new(srv, pattern_str); if (NULL == rule->pattern) { goto error; } if (NULL != regex) { GError *err = NULL; rule->regex = g_regex_new(regex->str, G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, &err); if (NULL == rule->regex || NULL != err) { ERROR(srv, "redirect: error compiling regex \"%s\": %s", regex->str, NULL != err ? err->message : "unknown error"); g_error_free(err); goto error; } } return TRUE; error: if (NULL != rule->pattern) { li_pattern_free(rule->pattern); rule->pattern = NULL; } if (NULL != rule->regex) { g_regex_unref(rule->regex); rule->regex = NULL; } return FALSE; }
static memcached_ctx* mc_ctx_parse(liServer *srv, liPlugin *p, liValue *config) { memcached_ctx *ctx; memcached_config *mconf = p->data; GString def_server = li_const_gstring(CONST_STR_LEN("127.0.0.1:11211")); if (config && config->type != LI_VALUE_HASH) { ERROR(srv, "%s", "memcache expects an optional hash of options"); return NULL; } ctx = g_slice_new0(memcached_ctx); ctx->srv = srv; ctx->refcount = 1; ctx->p = p; ctx->addr = li_sockaddr_from_string(&def_server, 11211); ctx->pattern = li_pattern_new(srv, "%{req.path}"); ctx->flags = 0; ctx->ttl = 30; ctx->maxsize = 64*1024; /* 64 kB */ ctx->headers = FALSE; if (config) { GHashTable *ht = config->data.hash; GHashTableIter it; gpointer pkey, pvalue; g_hash_table_iter_init(&it, ht); while (g_hash_table_iter_next(&it, &pkey, &pvalue)) { GString *key = pkey; liValue *value = pvalue; if (g_string_equal(key, &mon_server)) { if (value->type != LI_VALUE_STRING) { ERROR(srv, "memcache option '%s' expects string as parameter", mon_server.str); goto option_failed; } li_sockaddr_clear(&ctx->addr); ctx->addr = li_sockaddr_from_string(value->data.string, 11211); if (NULL == ctx->addr.addr) { ERROR(srv, "invalid socket address: '%s'", value->data.string->str); goto option_failed; } } else if (g_string_equal(key, &mon_key)) { if (value->type != LI_VALUE_STRING) { ERROR(srv, "memcache option '%s' expects string as parameter", mon_key.str); goto option_failed; } li_pattern_free(ctx->pattern); ctx->pattern = li_pattern_new(srv, value->data.string->str); if (NULL == ctx->pattern) { ERROR(srv, "memcache: couldn't parse pattern for key '%s'", value->data.string->str); goto option_failed; } } else if (g_string_equal(key, &mon_flags)) { if (value->type != LI_VALUE_NUMBER || value->data.number <= 0) { ERROR(srv, "memcache option '%s' expects positive integer as parameter", mon_flags.str); goto option_failed; } ctx->flags = value->data.number; } else if (g_string_equal(key, &mon_ttl)) { if (value->type != LI_VALUE_NUMBER || value->data.number < 0) { ERROR(srv, "memcache option '%s' expects non-negative integer as parameter", mon_ttl.str); goto option_failed; } ctx->ttl = value->data.number; } else if (g_string_equal(key, &mon_maxsize)) { if (value->type != LI_VALUE_NUMBER || value->data.number <= 0) { ERROR(srv, "memcache option '%s' expects positive integer as parameter", mon_maxsize.str); goto option_failed; } ctx->maxsize = value->data.number; } else if (g_string_equal(key, &mon_headers)) { if (value->type != LI_VALUE_BOOLEAN) { ERROR(srv, "memcache option '%s' expects boolean as parameter", mon_headers.str); goto option_failed; } ctx->headers = value->data.boolean; if (ctx->headers) { ERROR(srv, "%s", "memcache: lookup/storing headers not supported yet"); goto option_failed; } } else { ERROR(srv, "unknown option for memcache '%s'", key->str); goto option_failed; } } } if (LI_SERVER_INIT != g_atomic_int_get(&srv->state)) { ctx->worker_client_ctx = g_slice_alloc0(sizeof(liMemcachedCon*) * srv->worker_count); } else { ctx->mconf_link.data = ctx; g_queue_push_tail_link(&mconf->prepare_ctx, &ctx->mconf_link); } return ctx; option_failed: mc_ctx_release(NULL, ctx); return NULL; }