Beispiel #1
0
static void memcache_callback(liMemcachedRequest *request, liMemcachedResult result, liMemcachedItem *item, GError **err) {
	memcache_request *req = request->cb_data;
	liVRequest *vr = req->vr;

	/* request done */
	req->req = NULL;

	if (!vr) {
		g_slice_free(memcache_request, req);
		return;
	}

	switch (result) {
	case LI_MEMCACHED_OK: /* STORED, VALUE, DELETED */
		/* steal buffer */
		req->buffer = item->data;
		item->data = NULL;
		if (CORE_OPTION(LI_CORE_OPTION_DEBUG_REQUEST_HANDLING).boolean) {
			VR_DEBUG(vr, "memcached.lookup: key '%s' found, flags = %u", item->key->str, (guint) item->flags);
		}
		break;
	case LI_MEMCACHED_NOT_FOUND:
		/* ok, nothing to do - we just didn't find an entry */
		if (CORE_OPTION(LI_CORE_OPTION_DEBUG_REQUEST_HANDLING).boolean) {
			VR_DEBUG(vr, "%s", "memcached.lookup: key not found");
		}
		break;
	case LI_MEMCACHED_NOT_STORED:
	case LI_MEMCACHED_EXISTS:
		VR_ERROR(vr, "memcached error: %s", "unexpected result");
		/* TODO (not possible for lookup) */
		break;
	case LI_MEMCACHED_RESULT_ERROR:
		if (err && *err) {
			if (LI_MEMCACHED_DISABLED != (*err)->code) {
				VR_ERROR(vr, "memcached error: %s", (*err)->message);
			}
		} else {
			VR_ERROR(vr, "memcached error: %s", "Unknown error");
		}
		break;
	}

	li_vrequest_joblist_append(vr);
}
Beispiel #2
0
static void stat_cache_finished(gpointer data) {
    liStatCacheEntry *sce = data;
    guint i;
    liVRequest *vr;

    if (sce->data.failed) {
        if (NULL != sce->sc) sce->sc->errors++;
    }

    /* queue pending vrequests */
    for (i = 0; i < sce->vrequests->len; i++) {
        vr = g_ptr_array_index(sce->vrequests, i);
        li_vrequest_joblist_append(vr);
    }

    /* release tasklet reference */
    stat_cache_entry_release(sce);
}
Beispiel #3
0
/* the CollectCallback */
static void progress_collect_cb(gpointer cbdata, gpointer fdata, GPtrArray *result, gboolean complete) {
	guint i;
	GString *output;
	mod_progress_node *node = NULL;
	mod_progress_job *job = fdata;
	liVRequest *vr = job->vr;
	gboolean debug = job->debug;
	mod_progress_format format = job->format;

	UNUSED(cbdata);

	if (complete) {
		/* clear context so it doesn't get cleaned up anymore */
		*(job->context) = NULL;

		for (i = 0; i < result->len; i++) {
			node = g_ptr_array_index(result, i);
			if (node)
				break;
		}

		output = g_string_sized_new(128);

		/* send mime-type. there seems to be no standard for javascript... using the most commong */
		li_http_header_overwrite(vr->response.headers, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("application/x-javascript"));

		if (format == PROGRESS_FORMAT_LEGACY) {
			g_string_append_len(output, CONST_STR_LEN("new Object("));
		} else if (format == PROGRESS_FORMAT_JSONP) {
			gchar *val;
			guint len;

			if (li_querystring_find(vr->request.uri.query, CONST_STR_LEN("X-Progress-Callback"), &val, &len)) {
				/* X-Progress-Callback specified, need to check for xss */
				gchar *c;

				for (c = val; c != val+len; c++) {
					if ((*c >= 'a' && *c <= 'z') || (*c >= 'A' && *c <= 'Z') || (*c >= '0' && *c <= '9') || *c == '.' || *c == '_')
						continue;
					break;
				}

				/* was there a bad char? */
				if (c != val+len) {
					g_string_append_len(output, CONST_STR_LEN("progress("));
				} else {
					g_string_append_len(output,val, len);
					g_string_append_c(output, '(');
				}
			} else {
				g_string_append_len(output, CONST_STR_LEN("progress("));
			}
		}

		if (!node) {
			/* progress id not known */
			if (debug)
				VR_DEBUG(vr, "progress.show: progress id \"%s\" unknown", job->id);
			
			g_string_append_len(output, CONST_STR_LEN("{\"state\": \"unknown\"}"));
		} else {
			if (debug)
				VR_DEBUG(vr, "progress.show: progress id \"%s\" found", job->id);

			if (node->vr) {
				/* still in progress */
				g_string_append_printf(output,
					"{\"state\": \"running\", \"received\": %"G_GUINT64_FORMAT", \"sent\": %"G_GUINT64_FORMAT", \"request_size\": %"G_GUINT64_FORMAT", \"response_size\": %"G_GUINT64_FORMAT"}",
					node->bytes_in, node->bytes_out, node->request_size, node->response_size
				);
			} else if (node->status_code == 200) {
				/* done, success */
				g_string_append_printf(output,
					"{\"state\": \"done\", \"received\": %"G_GUINT64_FORMAT", \"sent\": %"G_GUINT64_FORMAT", \"request_size\": %"G_GUINT64_FORMAT", \"response_size\": %"G_GUINT64_FORMAT"}",
					node->bytes_in, node->bytes_out, node->request_size, node->response_size
				);
			} else {
				/* done, error */
				g_string_append_printf(output,
					"{\"state\": \"error\", \"status\": %d}",
					node->status_code
				);
			}
		}

		if (format == PROGRESS_FORMAT_LEGACY || format == PROGRESS_FORMAT_JSONP) {
			g_string_append_c(output, ')');
		}

		vr->response.http_status = 200;
		li_chunkqueue_append_string(vr->out, output);
		li_vrequest_handle_direct(vr);
		li_vrequest_joblist_append(vr);
	}

	/* free results */
	for (i = 0; i < result->len; i++) {
		if (g_ptr_array_index(result, i))
			g_slice_free(mod_progress_node, g_ptr_array_index(result, i));
	}

	g_free(job->id);
	g_slice_free(mod_progress_job, job);
}