static int upload_progress_handle_request(request_rec *r) { /**/up_log(APLOG_MARK, APLOG_DEBUG, 0, r->server, "upload_progress_handle_request()"); DirConfig* dir = (DirConfig*)ap_get_module_config(r->per_dir_config, &upload_progress_module); ServerConfig *config = get_server_config(r->server); if (dir && dir->track_enabled > 0) { if (r->method_number == M_POST) { int param_error; const char* id = get_progress_id(r, ¶m_error); if (id) { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "Upload Progress: Upload id='%s' in trackable location: %s.", id, r->uri); CACHE_LOCK(); clean_old_connections(r); upload_progress_node_t *node = find_node(r, id); if (node == NULL) { node = insert_node(r, id); if (node) up_log(APLOG_MARK, APLOG_DEBUG, 0, r->server, "Upload Progress: Added upload with id='%s' to list.", id); } else if (node->done) { fill_new_upload_node_data(node, r); up_log(APLOG_MARK, APLOG_DEBUG, 0, r->server, "Upload Progress: Reused existing node with id='%s'.", id); } else { node = NULL; ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server, "Upload Progress: Upload with id='%s' already exists, ignoring.", id); } if (node) { upload_progress_context_t *ctx = (upload_progress_context_t*)apr_pcalloc(r->pool, sizeof(upload_progress_context_t)); ctx->node = node; ctx->r = r; apr_pool_cleanup_register(r->pool, ctx, upload_progress_cleanup, apr_pool_cleanup_null); ap_add_input_filter("UPLOAD_PROGRESS", NULL, r, r->connection); } CACHE_UNLOCK(); } else if (param_error < 0) { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "Upload Progress: Upload with invalid ID in trackable location: %s.", r->uri); /* return HTTP_BAD_REQUEST; return HTTP_NOT_FOUND; */ } else { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "Upload Progress: Upload without ID in trackable location: %s.", r->uri); } } } return DECLINED; }
static int upload_progress_handle_request(request_rec *r) { DirConfig* dir = (DirConfig*)ap_get_module_config(r->per_dir_config, &upload_progress_module); ServerConfig *config = get_server_config(r); if(dir->track_enabled) { if(r->method_number == M_POST) { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "Upload Progress: Upload in trackable location: %s.", r->uri); const char* id = get_progress_id(r); if(id != NULL) { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "Upload Progress: Progress id found: %s.", id); CACHE_LOCK(); upload_progress_node_t *node = find_node(r, id); CACHE_UNLOCK(); if(node == NULL) { add_upload_to_track(r, id); ap_add_input_filter("UPLOAD_PROGRESS", NULL, r, r->connection); } else { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "Upload Progress: Node with id '%s' already exists.", id); } return DECLINED; } } } return DECLINED; }
static int track_upload_progress(ap_filter_t *f, apr_bucket_brigade *bb, ap_input_mode_t mode, apr_read_type_e block, apr_off_t readbytes) { apr_status_t rv; upload_progress_node_t *node; ServerConfig* config = get_server_config(f->r); if ((rv = ap_get_brigade(f->next, bb, mode, block, readbytes)) != APR_SUCCESS) { return rv; } apr_off_t length; apr_brigade_length(bb, 1, &length); const char* id = get_progress_id(f->r); if(id == NULL) return APR_SUCCESS; CACHE_LOCK(); node = find_node(f->r, id); CACHE_UNLOCK(); if(node == NULL) { return APR_SUCCESS; } else { CACHE_LOCK(); node->received += (int)length; int upload_time = time(NULL) - node->started_at; if(upload_time > 0) { node->speed = (int)(node->received / upload_time); } CACHE_UNLOCK(); } return APR_SUCCESS; }
static int reportuploads_handler(request_rec *r) { int length, received, done, speed, err_status, found=0; char *response; DirConfig* dir = (DirConfig*)ap_get_module_config(r->per_dir_config, &upload_progress_module); if(!dir->report_enabled) { return DECLINED; } if (r->method_number != M_GET) { return HTTP_METHOD_NOT_ALLOWED; } /* get the tracking id if any */ const char *id = get_progress_id(r); if (id == NULL) { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "Upload Progress: Not found id in location with reports enabled. uri=%s", id, r->uri); return HTTP_NOT_FOUND; } else { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "Upload Progress: Found id=%s in location with reports enables. uri=%s", id, r->uri); } ServerConfig *config = (ServerConfig*)ap_get_module_config(r->server->module_config, &upload_progress_module); if (config->cache_rmm == NULL) { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "Upload Progress: Cache error while generating report"); return HTTP_INTERNAL_SERVER_ERROR ; } CACHE_LOCK(); upload_progress_node_t *node = find_node(r, id); if (node != NULL) { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "Node with id=%s found for report", id); received = node->received; length = node->length; done = node->done; speed = node->speed; err_status = node->err_status; found = 1; CACHE_UNLOCK(); } else { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "Node with id=%s not found for report", id); } CACHE_UNLOCK(); ap_set_content_type(r, "text/javascript"); apr_table_set(r->headers_out, "Expires", "Mon, 28 Sep 1970 06:00:00 GMT"); apr_table_set(r->headers_out, "Cache-Control", "no-cache"); /* There are 4 possibilities * request not yet started: found = false * request in error: err_status >= NGX_HTTP_SPECIAL_RESPONSE * request finished: done = true * request not yet started but registered: length==0 && rest ==0 * reauest in progress: rest > 0 */ if (!found) { response = apr_psprintf(r->pool, "new Object({ 'state' : 'starting', 'uuid' : '%s' })", id); } else if (err_status >= HTTP_BAD_REQUEST ) { response = apr_psprintf(r->pool, "new Object({ 'state' : 'error', 'status' : %d, 'uuid' : '%s' })", err_status, id); } else if (done) { response = apr_psprintf(r->pool, "new Object({ 'state' : 'done', 'uuid' : '%s' })", id); } else if ( length == 0 && received == 0 ) { response = apr_psprintf(r->pool, "new Object({ 'state' : 'starting', 'uuid' : '%s' })", id); } else { response = apr_psprintf(r->pool, "new Object({ 'state' : 'uploading', 'received' : %d, 'size' : %d, 'speed' : %d, 'uuid' : '%s' })", received, length, speed, id); } char *completed_response; /* get the jsonp callback if any */ const char *jsonp = get_json_callback_param(r); // fix up response for jsonp request, if needed if (jsonp) { completed_response = apr_psprintf(r->pool, "%s(%s);\r\n", jsonp, response); } else { completed_response = apr_psprintf(r->pool, "%s\r\n", response); } ap_rputs(completed_response, r); return OK; }