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); }
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); }
/* 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); }