[pattern] Fix vr->wrk->tmp_str usage, remove pattern.h from base.h, add pattern support to header.add* actions

personal/stbuehler/wip
Stefan Bühler 13 years ago
parent 93e442d5c9
commit 2941105e28

@ -59,7 +59,6 @@
#include <lighttpd/log.h>
#include <lighttpd/stat_cache.h>
#include <lighttpd/throttle.h>
#include <lighttpd/pattern.h>
#include <lighttpd/mimetype.h>
#include <lighttpd/connection.h>

@ -151,9 +151,8 @@ typedef struct {
} data;
} liConditionValue;
/* uses wrk->tmp_str for temporary (and returned) strings */
LI_API liHandlerResult li_condition_get_value(liVRequest *vr, liConditionLValue *lvalue, liConditionValue *res, liConditionValueType prefer);
/* uses wrk->tmp_str for temporary (and returned) strings, no conflict with the tmp string from li_condition_get_value */
LI_API gchar const* li_condition_value_to_string(liVRequest *vr, liConditionValue *value);
LI_API liHandlerResult li_condition_get_value(GString *tmpstr, liVRequest *vr, liConditionLValue *lvalue, liConditionValue *res, liConditionValueType prefer);
/* tmpstr can be the same as for li_condition_get_value */
LI_API gchar const* li_condition_value_to_string(GString *tmpstr, liConditionValue *value);
#endif

@ -15,6 +15,7 @@ typedef void (*liPatternCB) (GString *pattern_result, guint from, guint to, gpoi
LI_API liPattern *li_pattern_new(liServer *srv, const gchar* str);
LI_API void li_pattern_free(liPattern *pattern);
/* you can use vr->wrk->tmp_str as dest! */
LI_API void li_pattern_eval(liVRequest *vr, GString *dest, liPattern *pattern, liPatternCB nth_callback, gpointer nth_data, liPatternCB nth_prev_callback, gpointer nth_prev_data);
/* default array callback, expects a GArray* containing GString* elements */

@ -30,8 +30,8 @@ static const liConditionValueType cond_value_hints[] = {
};
#endif
/* uses wrk->tmp_str for temporary (and returned) strings */
liHandlerResult li_condition_get_value(liVRequest *vr, liConditionLValue *lvalue, liConditionValue *res, liConditionValueType prefer) {
/* uses tmpstr for temporary (and returned) strings */
liHandlerResult li_condition_get_value(GString *tmpstr, liVRequest *vr, liConditionLValue *lvalue, liConditionValue *res, liConditionValueType prefer) {
liConInfo *coninfo = vr->coninfo;
liHandlerResult r;
struct stat st;
@ -174,14 +174,14 @@ liHandlerResult li_condition_get_value(liVRequest *vr, liConditionLValue *lvalue
break;
case LI_COMP_REQUEST_HEADER:
res->match_type = LI_COND_VALUE_HINT_STRING;
li_http_header_get_all(vr->wrk->tmp_str, vr->request.headers, GSTR_LEN(lvalue->key));
res->data.str = vr->wrk->tmp_str->str;
li_http_header_get_all(tmpstr, vr->request.headers, GSTR_LEN(lvalue->key));
res->data.str = tmpstr->str;
break;
case LI_COMP_RESPONSE_HEADER:
VREQUEST_WAIT_FOR_RESPONSE_HEADERS(vr);
res->match_type = LI_COND_VALUE_HINT_STRING;
li_http_header_get_all(vr->wrk->tmp_str, vr->response.headers, GSTR_LEN(lvalue->key));
res->data.str = vr->wrk->tmp_str->str;
li_http_header_get_all(tmpstr, vr->response.headers, GSTR_LEN(lvalue->key));
res->data.str = tmpstr->str;
break;
case LI_COMP_ENVIRONMENT:
res->match_type = LI_COND_VALUE_HINT_STRING;
@ -198,7 +198,7 @@ liHandlerResult li_condition_get_value(liVRequest *vr, liConditionLValue *lvalue
return LI_HANDLER_GO_ON;
}
gchar const* li_condition_value_to_string(liVRequest *vr, liConditionValue *value) {
gchar const* li_condition_value_to_string(GString *tmpstr, liConditionValue *value) {
switch (value->match_type) {
case LI_COND_VALUE_HINT_ANY:
case LI_COND_VALUE_HINT_STRING:
@ -206,11 +206,11 @@ gchar const* li_condition_value_to_string(liVRequest *vr, liConditionValue *valu
case LI_COND_VALUE_HINT_BOOL:
return value->data.bool ? "TRUE" : "FALSE";
case LI_COND_VALUE_HINT_NUMBER:
g_string_printf(vr->wrk->tmp_str, "%"L_GOFFSET_FORMAT, value->data.number);
return vr->wrk->tmp_str->str;
g_string_printf(tmpstr, "%"L_GOFFSET_FORMAT, value->data.number);
return tmpstr->str;
case LI_COND_VALUE_HINT_SOCKADDR:
li_sockaddr_to_string(value->data.addr, vr->wrk->tmp_str, TRUE);
return vr->wrk->tmp_str->str;
li_sockaddr_to_string(value->data.addr, tmpstr, TRUE);
return tmpstr->str;
}
return "";
}
@ -579,7 +579,7 @@ static liHandlerResult li_condition_check_eval_bool(liVRequest *vr, liCondition
liHandlerResult r;
*res = FALSE;
r = li_condition_get_value(vr, cond->lvalue, &match_val, LI_COND_VALUE_HINT_BOOL);
r = li_condition_get_value(vr->wrk->tmp_str, vr, cond->lvalue, &match_val, LI_COND_VALUE_HINT_BOOL);
if (r != LI_HANDLER_GO_ON) return r;
switch (match_val.match_type) {
@ -613,10 +613,10 @@ static liHandlerResult li_condition_check_eval_string(liVRequest *vr, liConditio
const char *val = "";
*res = FALSE;
r = li_condition_get_value(vr, cond->lvalue, &match_val, LI_COND_VALUE_HINT_STRING);
r = li_condition_get_value(vr->wrk->tmp_str, vr, cond->lvalue, &match_val, LI_COND_VALUE_HINT_STRING);
if (r != LI_HANDLER_GO_ON) return r;
val = li_condition_value_to_string(vr, &match_val);
val = li_condition_value_to_string(vr->wrk->tmp_str, &match_val);
switch (cond->op) {
case LI_CONFIG_COND_EQ:
@ -679,7 +679,7 @@ static liHandlerResult li_condition_check_eval_int(liVRequest *vr, liCondition *
liHandlerResult r;
*res = FALSE;
r = li_condition_get_value(vr, cond->lvalue, &match_val, LI_COND_VALUE_HINT_NUMBER);
r = li_condition_get_value(vr->wrk->tmp_str, vr, cond->lvalue, &match_val, LI_COND_VALUE_HINT_NUMBER);
if (r != LI_HANDLER_GO_ON) return r;
switch (match_val.match_type) {
@ -756,7 +756,7 @@ static liHandlerResult li_condition_check_eval_ip(liVRequest *vr, liCondition *c
liHandlerResult r;
liConditionRValue ipval;
r = li_condition_get_value(vr, cond->lvalue, &match_val, LI_COND_VALUE_HINT_SOCKADDR);
r = li_condition_get_value(vr->wrk->tmp_str, vr, cond->lvalue, &match_val, LI_COND_VALUE_HINT_SOCKADDR);
if (r != LI_HANDLER_GO_ON) return r;
*res = (cond->op == LI_CONFIG_COND_NOTIP);

@ -1,5 +1,6 @@
#include <lighttpd/base.h>
#include <lighttpd/encoding.h>
#include <lighttpd/pattern.h>
typedef struct {
enum {
@ -254,6 +255,7 @@ void li_pattern_eval(liVRequest *vr, GString *dest, liPattern *pattern, liPatter
liHandlerResult res;
liConditionValue cond_val;
GArray *arr = (GArray*) pattern;
GString *tmpstr = NULL;
for (i = 0; i < arr->len; i++) {
liPatternPart *part = &g_array_index(arr, liPatternPart, i);
@ -279,18 +281,22 @@ void li_pattern_eval(liVRequest *vr, GString *dest, liPattern *pattern, liPatter
case PATTERN_VAR:
if (vr == NULL) continue;
res = li_condition_get_value(vr, part->data.lvalue, &cond_val, LI_COND_VALUE_HINT_STRING);
if (NULL == tmpstr) tmpstr = g_string_sized_new(127);
res = li_condition_get_value(tmpstr, vr, part->data.lvalue, &cond_val, LI_COND_VALUE_HINT_STRING);
if (res == LI_HANDLER_GO_ON) {
if (encoded) {
li_string_encode_append(li_condition_value_to_string(vr, &cond_val), dest, LI_ENCODING_URI);
li_string_encode_append(li_condition_value_to_string(tmpstr, &cond_val), dest, LI_ENCODING_URI);
} else {
g_string_append(dest, li_condition_value_to_string(vr, &cond_val));
g_string_append(dest, li_condition_value_to_string(tmpstr, &cond_val));
}
}
break;
}
}
if (NULL != tmpstr) g_string_free(tmpstr, TRUE);
}
void li_pattern_array_cb(GString *pattern_result, guint from, guint to, gpointer data) {

@ -1,5 +1,7 @@
#include <lighttpd/base.h>
#include <lighttpd/pattern.h>
#include <lighttpd/plugin_core.h>
#include <lighttpd/version.h>
@ -873,7 +875,6 @@ static void core_log_write_free(liServer *srv, gpointer param) {
static liHandlerResult core_handle_log_write(liVRequest *vr, gpointer param, gpointer *context) {
liPattern *pattern = param;
GString *str = g_string_sized_new(127);
GMatchInfo *match_info = NULL;
if (vr->action_stack.regex_stack->len) {
@ -884,10 +885,9 @@ static liHandlerResult core_handle_log_write(liVRequest *vr, gpointer param, gpo
UNUSED(context);
/* eval pattern, ignore $n */
li_pattern_eval(vr, str, pattern, NULL, NULL, li_pattern_regex_cb, match_info);
li_pattern_eval(vr, vr->wrk->tmp_str, pattern, NULL, NULL, li_pattern_regex_cb, match_info);
VR_INFO(vr, "%s", str->str);
g_string_free(str, TRUE);
VR_INFO(vr, "%s", vr->wrk->tmp_str->str);
return LI_HANDLER_GO_ON;
}
@ -1458,119 +1458,78 @@ static gboolean core_option_etag_use_parse(liServer *srv, liWorker *wrk, liPlugi
return TRUE;
}
static liHandlerResult core_handle_header_add(liVRequest *vr, gpointer param, gpointer *context) {
GArray *l = (GArray*)param;
GString *k = g_array_index(l, liValue*, 0)->data.string;
GString *v = g_array_index(l, liValue*, 1)->data.string;
UNUSED(param);
UNUSED(context);
li_http_header_insert(vr->response.headers, GSTR_LEN(k), GSTR_LEN(v));
typedef void (*header_cb)(liHttpHeaders *headers, const gchar *key, size_t keylen, const gchar *val, size_t valuelen);
return LI_HANDLER_GO_ON;
}
typedef struct header_ctx header_ctx;
struct header_ctx {
GString *key;
liPattern *value;
header_cb cb;
};
static void core_header_free(liServer *srv, gpointer param) {
UNUSED(srv);
li_value_list_free(param);
}
header_ctx *ctx = param;
static liAction* core_header_add(liServer *srv, liWorker *wrk, liPlugin* p, liValue *val, gpointer userdata) {
GArray *l;
UNUSED(wrk); UNUSED(p); UNUSED(userdata);
UNUSED(srv);
if (val->type != LI_VALUE_LIST) {
ERROR(srv, "'header.add' action expects a string tuple as parameter, %s given", li_value_type_string(val->type));
return NULL;
}
g_string_free(ctx->key, TRUE);
li_pattern_free(ctx->value);
g_slice_free(header_ctx, ctx);
}
l = val->data.list;
static liHandlerResult core_handle_header(liVRequest *vr, gpointer param, gpointer *context) {
header_ctx *ctx = param;
GMatchInfo *match_info = NULL;
if (l->len != 2) {
ERROR(srv, "'header.add' action expects a string tuple as parameter, list has %u entries", l->len);
return NULL;
}
UNUSED(context);
if (g_array_index(l, liValue*, 0)->type != LI_VALUE_STRING || g_array_index(l, liValue*, 0)->type != LI_VALUE_STRING) {
ERROR(srv, "%s", "'header.add' action expects a string tuple as parameter");
return NULL;
if (vr->action_stack.regex_stack->len) {
GArray *rs = vr->action_stack.regex_stack;
match_info = g_array_index(rs, liActionRegexStackElement, rs->len - 1).match_info;
}
return li_action_new_function(core_handle_header_add, NULL, core_header_free, li_value_extract_list(val));
}
static liHandlerResult core_handle_header_append(liVRequest *vr, gpointer param, gpointer *context) {
GArray *l = (GArray*)param;
GString *k = g_array_index(l, liValue*, 0)->data.string;
GString *v = g_array_index(l, liValue*, 1)->data.string;
UNUSED(param);
UNUSED(context);
g_string_truncate(vr->wrk->tmp_str, 0);
li_pattern_eval(vr, vr->wrk->tmp_str, ctx->value, NULL, NULL, li_pattern_regex_cb, match_info);
li_http_header_append(vr->response.headers, GSTR_LEN(k), GSTR_LEN(v));
ctx->cb(vr->response.headers, GSTR_LEN(ctx->key), GSTR_LEN(vr->wrk->tmp_str));
return LI_HANDLER_GO_ON;
}
static liAction* core_header_append(liServer *srv, liWorker *wrk, liPlugin* p, liValue *val, gpointer userdata) {
static liAction* core_header_add(liServer *srv, liWorker *wrk, liPlugin* p, liValue *val, gpointer userdata) {
GArray *l;
UNUSED(wrk); UNUSED(p); UNUSED(userdata);
liPattern *pat;
header_ctx *ctx;
UNUSED(wrk); UNUSED(p);
if (val->type != LI_VALUE_LIST) {
ERROR(srv, "'header.append' action expects a string tuple as parameter, %s given", li_value_type_string(val->type));
ERROR(srv, "'header.add/append/overwrite' action expects a string tuple as parameter, %s given", li_value_type_string(val->type));
return NULL;
}
l = val->data.list;
if (l->len != 2) {
ERROR(srv, "'header.append' action expects a string tuple as parameter, list has %u entries", l->len);
ERROR(srv, "'header.add/append/overwrite' action expects a string tuple as parameter, list has %u entries", l->len);
return NULL;
}
if (g_array_index(l, liValue*, 0)->type != LI_VALUE_STRING || g_array_index(l, liValue*, 0)->type != LI_VALUE_STRING) {
ERROR(srv, "%s", "'header.append' action expects a string tuple as parameter");
ERROR(srv, "%s", "'header.add/append/overwrite' action expects a string tuple as parameter");
return NULL;
}
return li_action_new_function(core_handle_header_append, NULL, core_header_free, li_value_extract_list(val));
}
static liHandlerResult core_handle_header_overwrite(liVRequest *vr, gpointer param, gpointer *context) {
GArray *l = (GArray*)param;
GString *k = g_array_index(l, liValue*, 0)->data.string;
GString *v = g_array_index(l, liValue*, 1)->data.string;
UNUSED(param);
UNUSED(context);
li_http_header_overwrite(vr->response.headers, GSTR_LEN(k), GSTR_LEN(v));
return LI_HANDLER_GO_ON;
}
static liAction* core_header_overwrite(liServer *srv, liWorker *wrk, liPlugin* p, liValue *val, gpointer userdata) {
GArray *l;
UNUSED(wrk); UNUSED(p); UNUSED(userdata);
if (val->type != LI_VALUE_LIST) {
ERROR(srv, "'header.overwrite' action expects a string tuple as parameter, %s given", li_value_type_string(val->type));
return NULL;
}
l = val->data.list;
if (l->len != 2) {
ERROR(srv, "'header.overwrite' action expects a string tuple as parameter, list has %u entries", l->len);
if (NULL == (pat = li_pattern_new(srv, g_array_index(l, liValue*, 1)->data.string->str))) {
ERROR(srv, "%s", "'header.add/append/overwrite': parsing value pattern failed");
return NULL;
}
if (g_array_index(l, liValue*, 0)->type != LI_VALUE_STRING || g_array_index(l, liValue*, 0)->type != LI_VALUE_STRING) {
ERROR(srv, "%s", "'header.overwrite' action expects a string tuple as parameter");
return NULL;
}
ctx = g_slice_new(header_ctx);
ctx->key = li_value_extract_string(g_array_index(l, liValue*, 0));
ctx->value = pat;
ctx->cb = (header_cb)(intptr_t)userdata;
return li_action_new_function(core_handle_header_overwrite, NULL, core_header_free, li_value_extract_list(val));
return li_action_new_function(core_handle_header, NULL, core_header_free, ctx);
}
static void core_header_remove_free(liServer *srv, gpointer param) {
@ -1919,9 +1878,9 @@ static const liPluginAction actions[] = {
{ "env.remove", core_env_remove, NULL },
{ "env.clear", core_env_clear, NULL },
{ "header.add", core_header_add, NULL },
{ "header.append", core_header_append, NULL },
{ "header.overwrite", core_header_overwrite, NULL },
{ "header.add", core_header_add, (void*)(intptr_t)li_http_header_insert },
{ "header.append", core_header_add, (void*)(intptr_t)li_http_header_append },
{ "header.overwrite", core_header_add, (void*)(intptr_t)li_http_header_overwrite },
{ "header.remove", core_header_remove, NULL },
{ "io.buffer_out", core_buffer_out, NULL },

@ -37,6 +37,7 @@
*/
#include <lighttpd/base.h>
#include <lighttpd/pattern.h>
#include <lighttpd/plugin_core.h>
#include <lighttpd/memcached.h>
@ -235,22 +236,18 @@ option_failed:
return NULL;
}
static GString* mc_ctx_build_key(memcached_ctx *ctx, liVRequest *vr) {
static void mc_ctx_build_key(GString *dest, memcached_ctx *ctx, liVRequest *vr) {
GMatchInfo *match_info = NULL;
GString *key = g_string_sized_new(255);
g_string_truncate(key, 0);
if (vr->action_stack.regex_stack->len) {
GArray *rs = vr->action_stack.regex_stack;
match_info = g_array_index(rs, liActionRegexStackElement, rs->len - 1).match_info;
}
li_pattern_eval(vr, key, ctx->pattern, NULL, NULL, li_pattern_regex_cb, match_info);
li_memcached_mutate_key(key);
g_string_truncate(dest, 0);
li_pattern_eval(vr, dest, ctx->pattern, NULL, NULL, li_pattern_regex_cb, match_info);
return key;
li_memcached_mutate_key(dest);
}
static liMemcachedCon* mc_ctx_prepare(memcached_ctx *ctx, liWorker *wrk) {
@ -356,7 +353,6 @@ static liHandlerResult mc_handle_lookup(liVRequest *vr, gpointer param, gpointer
return LI_HANDLER_GO_ON;
} else {
liMemcachedCon *con;
GString *key;
GError *err = NULL;
if (li_vrequest_is_handled(vr)) {
@ -367,15 +363,14 @@ static liHandlerResult mc_handle_lookup(liVRequest *vr, gpointer param, gpointer
}
con = mc_ctx_prepare(ctx, vr->wrk);
key = mc_ctx_build_key(ctx, vr);
mc_ctx_build_key(vr->wrk->tmp_str, ctx, vr);
if (CORE_OPTION(LI_CORE_OPTION_DEBUG_REQUEST_HANDLING).boolean) {
VR_DEBUG(vr, "memcached.lookup: looking up key '%s'", key->str);
VR_DEBUG(vr, "memcached.lookup: looking up key '%s'", vr->wrk->tmp_str->str);
}
req = g_slice_new0(memcache_request);
req->req = li_memcached_get(con, key, memcache_callback, req, &err);
g_string_free(key, TRUE);
req->req = li_memcached_get(con, vr->wrk->tmp_str, memcache_callback, req, &err);
if (NULL == req->req) {
if (NULL != err) {
@ -481,7 +476,6 @@ static liHandlerResult memcache_store_filter(liVRequest *vr, liFilter *f) {
/* finally: store response in memcached */
liMemcachedCon *con;
GString *key;
GError *err = NULL;
liMemcachedRequest *req;
memcached_ctx *ctx = mf->ctx;
@ -489,14 +483,13 @@ static liHandlerResult memcache_store_filter(liVRequest *vr, liFilter *f) {
f->out->is_closed = TRUE;
con = mc_ctx_prepare(ctx, vr->wrk);
key = mc_ctx_build_key(ctx, vr);
mc_ctx_build_key(vr->wrk->tmp_str, ctx, vr);
if (CORE_OPTION(LI_CORE_OPTION_DEBUG_REQUEST_HANDLING).boolean) {
VR_DEBUG(vr, "memcached.store: storing response for key '%s'", key->str);
VR_DEBUG(vr, "memcached.store: storing response for key '%s'", vr->wrk->tmp_str->str);
}
req = li_memcached_set(con, key, ctx->flags, ctx->ttl, mf->buf, NULL, NULL, &err);
g_string_free(key, TRUE);
req = li_memcached_set(con, vr->wrk->tmp_str, ctx->flags, ctx->ttl, mf->buf, NULL, NULL, &err);
li_buffer_release(mf->buf);
mf->buf = NULL;

@ -54,6 +54,7 @@
#include <lighttpd/base.h>
#include <lighttpd/encoding.h>
#include <lighttpd/pattern.h>
LI_API gboolean mod_redirect_init(liModules *mods, liModule *mod);
LI_API gboolean mod_redirect_free(liModules *mods, liModule *mod);

@ -59,6 +59,7 @@
#include <lighttpd/base.h>
#include <lighttpd/encoding.h>
#include <lighttpd/pattern.h>
LI_API gboolean mod_rewrite_init(liModules *mods, liModule *mod);
LI_API gboolean mod_rewrite_free(liModules *mods, liModule *mod);

Loading…
Cancel
Save