apr_status_t upload_progress_cache_init(apr_pool_t *pool, ServerConfig *config)
{

#if APR_HAS_SHARED_MEMORY
    apr_status_t result;
    apr_size_t size;
    upload_progress_cache_t *cache;
    apr_rmm_off_t block;

    if (config->cache_file) {
        /* Remove any existing shm segment with this name. */
        apr_shm_remove(config->cache_file, config->pool);
    }

    size = APR_ALIGN_DEFAULT(config->cache_bytes);
    result = apr_shm_create(&config->cache_shm, size, config->cache_file, config->pool);
    if (result != APR_SUCCESS) {
        return result;
    }

    /* Determine the usable size of the shm segment. */
    size = apr_shm_size_get(config->cache_shm);

    /* This will create a rmm "handler" to get into the shared memory area */
    result = apr_rmm_init(&config->cache_rmm, NULL,
                          apr_shm_baseaddr_get(config->cache_shm), size,
                          config->pool);
    if (result != APR_SUCCESS) {
        return result;
    }

    apr_pool_cleanup_register(config->pool, config , upload_progress_cache_module_kill, apr_pool_cleanup_null);
    
    /* init cache object */
    CACHE_LOCK();
    block = apr_rmm_calloc(config->cache_rmm, sizeof(upload_progress_cache_t));
    cache = block ? (upload_progress_cache_t *)apr_rmm_addr_get(config->cache_rmm, block) : NULL;
    if(cache == NULL) {
      CACHE_UNLOCK();
      return 0;
    }
    cache->head = NULL;
    config->cache_offset = block;
    config->cache = cache;
    CACHE_UNLOCK();
    
#endif

    return APR_SUCCESS;
}
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, &param_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 void clean_old_connections(request_rec *r) {
    upload_progress_node_t *prev = NULL;
    ServerConfig *config = get_server_config(r);
    CACHE_LOCK();
    upload_progress_node_t *node = fetch_first_node(config);
    while(node != NULL) {
        if(time(NULL) > node->expires && node->done == 1 && node->expires != -1) {
            /*clean*/
	    if(prev == NULL) {
		/* head */
		upload_progress_cache_t *cache = fetch_cache(config);
		cache->head = fetch_node(config, node->next);
		cache_free(config, node->key);
		cache_free(config, node);
		node = cache->head;
		continue;
	    } else {
		prev->next = node->next;
		cache_free(config, node->key);
		cache_free(config, node);
		node = prev;
		continue;
	    }
        }
	prev = node;
	node = fetch_node(config, node->next);
  }
  CACHE_UNLOCK();
}
upload_progress_node_t* insert_node(request_rec *r, const char *key) {
  upload_progress_node_t *node;
  upload_progress_cache_t *cache;
  
  ServerConfig *config = (ServerConfig*)ap_get_module_config(r->server->module_config, &upload_progress_module);
  
  CACHE_LOCK();
  upload_progress_node_t *head = fetch_first_node(config);
  node = store_node(config, key);
  
  if(head == NULL) { 
    /* list is empty */
    cache = fetch_cache(config);
    cache->head = node;
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
                         "Upload Progress: Inserted node into an empty list.");
  } else {
    upload_progress_node_t *tail = fetch_last_node(config);
    tail->next = node;
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
                         "Upload Progress: Inserted node at the end of the list.");
  }
  
  node->length = r->clength;
  node->received = 0;
  node->done = 0;
  node->err_status = 0;
  node->started_at = time(NULL);
  node->speed = 0;
  node->expires = -1;
  sscanf(apr_table_get(r->headers_in, "Content-Length"), "%d", &(node->length));
  node->next = NULL;
  CACHE_UNLOCK();
  return node;
}
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;
}
示例#6
0
int cache_table(char * sql, sqlite_cb cb, void * arg)
{
    CACHE_LOCK(pcache);
    if (sql_process(pcache->db, sql, cb, arg) < 0) {
        log_error(LOG_NOTICE, "cache_table");
    }
    CACHE_UNLOCK(pcache);
    return 0;
}
int add_upload_to_track(request_rec* r, const char* key) {
  ServerConfig *config = get_server_config(r);
  upload_progress_node_t* node;
  
  clean_old_connections(r);

  CACHE_LOCK();
  node = find_node(r, key);
  if(node == NULL) {
    node = insert_node(r, key);
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
                         "Upload Progress: Added upload with id=%s to list.", key);
    upload_progress_context_t *ctx = (upload_progress_context_t*)apr_pcalloc(r->pool, sizeof(upload_progress_context_t));
    ctx->node = node;
    ctx->r = r;
    CACHE_UNLOCK();
    apr_pool_cleanup_register(r->pool, ctx, upload_progress_cleanup, apr_pool_cleanup_null);
    return OK;
  }
  CACHE_UNLOCK();
  return OK;
}
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;
}
示例#9
0
int cache_search(TABLE_T table, char * sql, sqlite_cb cb, void * arg, SEARCH_T type)
{
    int is_find = -1;
    char **azResult;
    char *zErrMsg;
    int nrow, ncolumn;

    int i;
    if (table >= TBL_NULL )
        return is_find;

    CACHE_LOCK(pcache);

    do {
        if (sqlite3_get_table( pcache->db->sqlite_db , sql , &azResult , &nrow , &ncolumn , &zErrMsg)) {
            log_error(LOG_DEBUG, zErrMsg);
            break;
        }

        nrow += 1;

        if (cb == NULL) {
            if (nrow > 1) {
                is_find = 0;
                break;
            }
            is_find = -1;
            break;
        }

        for( i = 1 ; i < nrow ; i++ ) {
            cb(arg, ncolumn, azResult, azResult + (nrow * ncolumn));
            is_find = 0;
        }
        //释放掉  azResult 的内存空间
        sqlite3_free_table( azResult );

    } while (0);

    CACHE_UNLOCK(pcache);

    return is_find;
}
示例#10
0
int cache_opt_item(TABLE_T table, char * sql)       //插入 删除等操作
{
    int ret = -1;
    if (table >= TBL_NULL)
        return -1;
    //printf("\nxxx ret = %d\n", ret);
    CACHE_LOCK(pcache);

    do {

        if (sql_process(pcache->db, sql, NULL, NULL) < 0) {
            log_error(LOG_DEBUG, "sql_process");
            break;
        }

        pcache->item_cnt++;
        ret = 0;
    } while (0);
    //printf("\nxxx ret = %d\n", ret);
    CACHE_UNLOCK(pcache);

    return  ret;
}
示例#11
0
void D3DCacheFill(d3d_render_cache_system *pCacheSystem, d3d_render_pool_new *pPool, int numStages)
{
	u_int				curPacket, curChunk, count, indexOffset, numPackets;
	d3d_render_cache	*pRenderCache = (d3d_render_cache *)pCacheSystem->curCache->data;
	d3d_render_packet_new	*pPacket;
	d3d_render_chunk_new	*pChunk;
	list_type				list;

	CACHE_RESET(pRenderCache);
	CACHE_LOCK(pRenderCache);

	for (list = pPool->renderPacketList; list != pPool->curPacketList->next; list = list->next)
	{
		if (list == pPool->curPacketList)
			numPackets = pPool->curPacket;
		else
			numPackets = pPool->size;

		pPacket = (d3d_render_packet_new *)list->data;

		for (curPacket = 0; curPacket < numPackets; curPacket++, pPacket++)
		{
			for (curChunk = 0; curChunk < pPacket->curChunk; curChunk++)
			{
				pChunk = &pPacket->renderChunks[curChunk];

				if ((pRenderCache->indexBuffer.curIndex + pChunk->numIndices) >= pRenderCache->size)
				{
					CACHE_UNLOCK(pRenderCache);

					pRenderCache = D3DCacheSystemSwap(pCacheSystem);
					if (NULL == pRenderCache)
						return;

					CACHE_LOCK(pRenderCache);
				}

				pChunk->pRenderCache = pRenderCache;
				pChunk->startIndex = pRenderCache->indexBuffer.curIndex;
				indexOffset = pRenderCache->xyzBuffer.curIndex;

				for (count = 0; count < pChunk->numVertices; count++)
				{
					CACHE_XYZ_ADD(pRenderCache, pChunk->xyz[count].x, pChunk->xyz[count].z, pChunk->xyz[count].y);

					switch (numStages)
					{
						case 1:
							CACHE_ST_ADD(pRenderCache, 0, pChunk->st0[count].s, pChunk->st0[count].t);
						break;

						case 2:
							CACHE_ST_ADD(pRenderCache, 0, pChunk->st0[count].s, pChunk->st0[count].t);
							CACHE_ST_ADD(pRenderCache, 1, pChunk->st1[count].s, pChunk->st1[count].t);
						break;
					}

					CACHE_BGRA_ADD(pRenderCache, pChunk->bgra[count].b, pChunk->bgra[count].g, pChunk->bgra[count].r,
						pChunk->bgra[count].a);
				}

				for (count = 0; count < pChunk->numIndices; count++)
				{
					CACHE_INDEX_ADD(pRenderCache, pChunk->indices[count] + indexOffset);
				}
			}
		}
	}

	if (pRenderCache)
		CACHE_UNLOCK(pRenderCache);
}
示例#12
0
void cache_release_db(void)
{
    CACHE_UNLOCK(pcache);
}
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;
}