static liHandlerResult progress_track(liVRequest *vr, gpointer param, gpointer *context) { gchar *id; guint id_len; liPlugin *p = (liPlugin*) param; gboolean debug = _OPTION(vr, p, 0).boolean; gint methods = _OPTION(vr, p, 1).number; mod_progress_data *pd = p->data; UNUSED(context); if (!(methods & (1 << vr->request.http_method))) { /* method not tracked */ } else if (g_ptr_array_index(vr->plugin_ctx, p->id)) { /* already tracked */ VR_WARNING(vr, "%s", "progress.track: already tracking request"); } else if (li_querystring_find(vr->request.uri.query, CONST_STR_LEN("X-Progress-Id"), &id, &id_len) && id_len <= 128) { /* progress id found, start tracking of connection */ mod_progress_node *node = g_slice_new0(mod_progress_node); node->timeout_queue_elem.data = node; node->id = g_strndup(id, id_len); node->worker_data = &pd->worker_data[vr->wrk->ndx]; node->vr = vr; g_ptr_array_index(vr->plugin_ctx, pd->p->id) = node; g_hash_table_replace(node->worker_data->hash_table, node->id, node); if (debug) VR_DEBUG(vr, "progress.track: tracking progress with id \"%s\"", node->id); } else if (debug) { VR_DEBUG(vr, "%s", "progress.track: X-Progress-Id parameter not found, cannot track request"); } return LI_HANDLER_GO_ON; }
static liHandlerResult vhost_map(liVRequest *vr, gpointer param, gpointer *context) { liValue *v; vhost_map_data *md = param; gboolean debug = _OPTION(vr, md->plugin, 0).boolean; UNUSED(context); v = g_hash_table_lookup(md->hash, vr->request.uri.host); if (NULL != v) { if (debug) { VR_DEBUG(vr, "vhost_map: host %s found in hashtable", vr->request.uri.host->str); } li_action_enter(vr, v->data.val_action.action); } else if (NULL != md->default_action) { if (debug) { VR_DEBUG(vr, "vhost_map: host %s not found in hashtable, executing default action", vr->request.uri.host->str); } li_action_enter(vr, md->default_action->data.val_action.action); } else { if (debug) { VR_DEBUG(vr, "vhost_map: neither host %s found in hashtable nor default action specified, doing nothing", vr->request.uri.host->str); } } return LI_HANDLER_GO_ON; }
static liHandlerResult progress_show(liVRequest *vr, gpointer param, gpointer *context) { mod_progress_show_param *psp = (mod_progress_show_param*) param; gboolean debug = _OPTION(vr, psp->p, 0).boolean; gchar *id; guint id_len; liCollectInfo *ci; mod_progress_job *job; if (*context) return LI_HANDLER_WAIT_FOR_EVENT; if (li_vrequest_is_handled(vr)) return LI_HANDLER_GO_ON; if (!li_querystring_find(vr->request.uri.query, CONST_STR_LEN("X-Progress-Id"), &id, &id_len) || id_len == 0 || id_len > 128) { if (debug) VR_DEBUG(vr, "%s", "progress.show: X-Progress-Id not specified"); return LI_HANDLER_GO_ON; } /* start collect job */ job = g_slice_new(mod_progress_job); job->vr = vr; job->context = context; job->format = psp->format; job->debug = debug; job->p = psp->p; job->id = g_strndup(id, id_len); ci = li_collect_start(vr->wrk, progress_collect_func, job, progress_collect_cb, NULL); *context = ci; /* may be NULL */ return ci ? LI_HANDLER_WAIT_FOR_EVENT : LI_HANDLER_GO_ON; }
static liHandlerResult redirect(liVRequest *vr, gpointer param, gpointer *context) { guint i; redirect_rule *rule; redirect_data *rd = param; gboolean debug = _OPTION(vr, rd->p, 0).boolean; GString *dest = vr->wrk->tmp_str; UNUSED(context); if (li_vrequest_is_handled(vr)) return LI_HANDLER_GO_ON; for (i = 0; i < rd->rules->len; i++) { rule = &g_array_index(rd->rules, redirect_rule, i); if (redirect_internal(vr, dest, rule)) { /* regex matched */ if (debug) { VR_DEBUG(vr, "redirect: \"%s\"", dest->str); } if (!li_vrequest_handle_direct(vr)) return LI_HANDLER_ERROR; vr->response.http_status = 301; li_http_header_overwrite(vr->response.headers, CONST_STR_LEN("Location"), GSTR_LEN(dest)); /* stop at first matching regex */ return LI_HANDLER_GO_ON; } } return LI_HANDLER_GO_ON; }
static liHandlerResult auth_handle_deny(liVRequest *vr, gpointer param, gpointer *context) { liPlugin *p = param; UNUSED(context); if (!li_vrequest_handle_direct(vr)) { if (_OPTION(vr, p, 0).boolean || CORE_OPTION(LI_CORE_OPTION_DEBUG_REQUEST_HANDLING).boolean) { VR_DEBUG(vr, "skipping auth.deny as request is already handled with current status %i", vr->response.http_status); } return LI_HANDLER_GO_ON; } vr->response.http_status = 403; return LI_HANDLER_GO_ON; }
static liHandlerResult vhost_map_regex(liVRequest *vr, gpointer param, gpointer *context) { guint i; vhost_map_regex_data *mrd = param; GArray *list = mrd->list; gboolean debug = _OPTION(vr, mrd->plugin, 0).boolean; liValue *v = NULL; vhost_map_regex_entry *entry = NULL; UNUSED(context); /* loop through all rules to find a match */ for (i = 0; i < list->len; i++) { entry = &g_array_index(list, vhost_map_regex_entry, i); if (!g_regex_match(entry->regex, vr->request.uri.host->str, 0, NULL)) continue; v = entry->action; break; } if (NULL != v) { if (debug) { VR_DEBUG(vr, "vhost_map_regex: host %s matches pattern \"%s\"", vr->request.uri.host->str, g_regex_get_pattern(entry->regex)); } li_action_enter(vr, v->data.val_action.action); } else if (NULL != mrd->default_action) { if (debug) { VR_DEBUG(vr, "vhost_map_regex: host %s didn't match, executing default action", vr->request.uri.host->str); } li_action_enter(vr, mrd->default_action->data.val_action.action); } else { if (debug) { VR_DEBUG(vr, "vhost_map_regex: neither did %s match nor default action specified, doing nothing", vr->request.uri.host->str); } } return LI_HANDLER_GO_ON; }
static liHandlerResult auth_basic(liVRequest *vr, gpointer param, gpointer *context) { liHttpHeader *hdr; gboolean auth_ok = FALSE; AuthBasicData *bdata = param; gboolean debug = _OPTION(vr, bdata->p, 0).boolean; UNUSED(context); if (li_vrequest_is_handled(vr)) { if (debug || CORE_OPTION(LI_CORE_OPTION_DEBUG_REQUEST_HANDLING).boolean) { VR_DEBUG(vr, "skipping auth.basic as request is already handled with current status %i", vr->response.http_status); } return LI_HANDLER_GO_ON; } /* check for Authorization header */ hdr = li_http_header_lookup(vr->request.headers, CONST_STR_LEN("Authorization")); if (!hdr || !g_str_has_prefix(LI_HEADER_VALUE(hdr), "Basic ")) { if (debug) { VR_DEBUG(vr, "requesting authorization from client for realm \"%s\"", bdata->realm->str); } } else { gchar *decoded, *username = NULL, *password; size_t len; /* auth_info contains username:password encoded in base64 */ if (NULL != (decoded = (gchar*)g_base64_decode(LI_HEADER_VALUE(hdr) + sizeof("Basic ") - 1, &len))) { /* bogus data? */ if (NULL != (password = strchr(decoded, ':'))) { *password = '******'; password++; username = decoded; } else { g_free(decoded); } } if (!username) { if (debug) { VR_DEBUG(vr, "couldn't parse authorization info from client for realm \"%s\"", bdata->realm->str); } } else { GString user = li_const_gstring(username, password - username - 1); GString pass = li_const_gstring(password, len - (password - username)); if (bdata->backend(vr, &user, &pass, bdata, debug)) { auth_ok = TRUE; li_environment_set(&vr->env, CONST_STR_LEN("REMOTE_USER"), username, password - username - 1); li_environment_set(&vr->env, CONST_STR_LEN("AUTH_TYPE"), CONST_STR_LEN("Basic")); } else { if (debug) { VR_DEBUG(vr, "wrong authorization info from client on realm \"%s\" (user: \"%s\")", bdata->realm->str, username); } } g_free(decoded); } } g_string_truncate(vr->wrk->tmp_str, 0); g_string_append_len(vr->wrk->tmp_str, CONST_STR_LEN("Basic realm=\"")); g_string_append_len(vr->wrk->tmp_str, GSTR_LEN(bdata->realm)); g_string_append_c(vr->wrk->tmp_str, '"'); /* generate header always */ if (!auth_ok) { li_http_header_overwrite(vr->response.headers, CONST_STR_LEN("WWW-Authenticate"), GSTR_LEN(vr->wrk->tmp_str)); /* we already checked for handled */ if (!li_vrequest_handle_direct(vr)) return LI_HANDLER_ERROR; vr->response.http_status = 401; return LI_HANDLER_GO_ON; } else { /* lets hope browser just ignore the header if status is not 401 * but this way it is easier to use a later "auth.deny;" */ li_http_header_overwrite(vr->response.headers, CONST_STR_LEN("WWW-Authenticate"), GSTR_LEN(vr->wrk->tmp_str)); } if (debug) { VR_DEBUG(vr, "client authorization successful for realm \"%s\"", bdata->realm->str); } return LI_HANDLER_GO_ON; }