Exemplo n.º 1
0
dagent_cycle_t* cycle_init()
{
    /* init dagent_cycle_t*/
    dcycle = MALLOC(dagent_cycle_t, 1);
    
	/* init buffer */
    dcycle->length = 0;
	dcycle->buffer = (char*)MALLOC(char, MAX_PACKET_LEN);
    
    /* init dcenter socket */
    dcycle->socks = NULL;
    
    /* init timestamp */
    time_t tt;
    time(&tt);
    dcycle->timestamp = mktime(localtime(&tt));
    
    /* init req buffer */
    dcycle->req = http_new_request();
    dcycle->req->host = (char *)MALLOC(char, MAX_HOST_LEN);
    dcycle->req->referer = (char *)MALLOC(char, MAX_REF_LEN);
    dcycle->req->uri = (char *)MALLOC(char, MAX_URI_LEN);
    dcycle->req->url = (char *)MALLOC(char, MAX_URI_LEN);
    dcycle->req->user_agent = (char *)MALLOC(char, MAX_AGENT_LEN);
    dcycle->req->x_requested_with = (char *)MALLOC(char, MAX_REQ_WITH_LEN);
    dcycle->req->cookie = (char *)MALLOC(char, MAX_COOKIE_LEN);
    dcycle->req->saddr_str = (char *)MALLOC(char, 16);
    dcycle->req->daddr_str = (char *)MALLOC(char, 16);
    
    /* init mutex */
	pthread_mutex_t blank_mutex = PTHREAD_MUTEX_INITIALIZER;
	memcpy(&dcycle->mutex, &blank_mutex, sizeof(dcycle->mutex));

    //白名单过滤开关默认关闭
    dcycle->white_url_flag = FALSE;

    /* 快速匹配的hash表 */
    dcycle->hashmap = hashmap_create(MAX_BUCKETS);
    return dcycle;
}
/* 
 * This is annoying, but the caller needs to know the buffer size of
 * the request that we are using.  In most cases, the passed in buffer
 * is what we use, so it isn't an issue, but if we malloc our own
 * buffer (see the HTTP_REQ_PENDING case), then the total buffer size
 * can grow.  Thus the buff_sz argument.
 */
static struct http_request *connection_handle_request(struct connection *c, char *buff,
						      int amnt, int *buff_sz)
{
	struct http_request *r, *last;

	*buff_sz = amnt;
	r = http_new_request(c, buff, amnt);
	if (NULL == r) return NULL;
	last = r->prev;

	/* 
	 * If a previous request required more data to parse correctly
	 * (was pending), then we need to combine its buffer with the
	 * current one and try to parse again.
	 */
	if (last != r && last->flags & HTTP_REQ_PENDING) {
		char *new_buff;
		int new_len;

		if (last->prev != last && last->prev->flags & HTTP_REQ_PENDING) {
			http_free_request(r);
			return NULL;
		}
		new_len = amnt + last->req_len;
		new_buff = malloc(new_len + 1);
		if (NULL == new_buff) {
			printc("malloc fail 1\n"); fflush(stdout);
			http_free_request(r);
			return NULL;
		}
		memcpy(new_buff, last->req, last->req_len);
		memcpy(new_buff + last->req_len, buff, amnt);
		buff = new_buff;
		*buff_sz = amnt = new_len;
		new_buff[new_len] = '\0';
		http_free_request(last);

		if (r->flags & HTTP_REQ_MALLOC) free(r->req);
		r->req_len = new_len;
		r->req = new_buff;
		r->flags |= HTTP_REQ_MALLOC;
	}

	/*
	 * Process the list of requests first, then go through and
	 * actually make the requests.
	 */
	if (http_parse_request(r)) {
		char *save_buff;

		/* parse error?! Parsing broke somewhere _in_ the
		 * message, so we need to report this as an error */
		if (r->req_len != amnt) {
			/* FIXME: kill connection */
			http_free_request(r);
			return NULL;
		}		
		assert(r->req_len == amnt && r->req == buff);
		/*
		 * If we failed because we simply don't have a whole
		 * message (more data is pending), then store it away
		 * appropriately.
		 */
		save_buff = malloc(amnt + 1);
		if (NULL == save_buff) {
			printc("malloc fail 2\n"); fflush(stdout);
			/* FIXME: kill connection */
			http_free_request(r);
			return NULL;
		}
		memcpy(save_buff, buff, amnt);
		save_buff[amnt] = '\0';
		if (r->flags & HTTP_REQ_MALLOC) free(r->req);
		r->req = save_buff;
		r->flags |= (HTTP_REQ_PENDING | HTTP_REQ_MALLOC);
	}
	return r;
}