Пример #1
0
int ugh_client_del(ugh_client_t *c)
{
	ev_io_stop(loop, &c->wev_recv);
	ev_io_stop(loop, &c->wev_send);
	ev_timer_stop(loop, &c->wev_timeout);

	close(c->wev_recv.fd);

	JudyLFreeArray(&c->args_hash, PJE0);
	JudyLFreeArray(&c->headers_hash, PJE0);
	JudyLFreeArray(&c->headers_out_hash, PJE0);
	Judy1FreeArray(&c->cookies_out_hash, PJE0);
#if 1
	JudyLFreeArray(&c->vars_hash, PJE0);
#endif
	aux_pool_free(c->pool);

	return 0;
}
Пример #2
0
void RefMap::free()
{
  unsigned long idx = 0;
  Node** pp = (Node**) JudyLFirst(nodes, &idx, NULL);
  while (pp != NULL)
  {
    free_node(*pp);
    pp = (Node**) JudyLNext(nodes, &idx, NULL);
  }
  JudyLFreeArray(&nodes, NULL);

  if (overflow != NULL) { free_node(overflow); overflow = NULL; }
}
Пример #3
0
int ugh_subreq_del(ugh_subreq_t *r, uint32_t ft_type, int ft_errno)
{
	ev_io_stop(loop, &r->wev_recv);
	ev_io_stop(loop, &r->wev_send);
	ev_io_stop(loop, &r->wev_connect);
	ev_timer_stop(loop, &r->wev_timeout);
	ev_timer_stop(loop, &r->wev_timeout_connect);

	close(r->wev_recv.fd);

	switch (ft_type)
	{
	case UGH_UPSTREAM_FT_ERROR:
		log_warn("connection or read/write error (%d: %s) on upstream socket (%.*s:%.*s%.*s%s%.*s, addr=%s:%u) while %.*s%s%.*s"
			, ft_errno
			, aux_strerror(ft_errno)
			, (int) r->u.host.size, r->u.host.data
			, (int) r->u.port.size, r->u.port.data
			, (int) r->u.uri.size, r->u.uri.data
			, r->u.args.size ? "?" : ""
			, (int) r->u.args.size, r->u.args.data
			, inet_ntoa(r->addr.sin_addr)
			, ntohs(r->addr.sin_port)
			, (int) r->c->uri.size, r->c->uri.data
			, r->c->args.size ? "?" : ""
			, (int) r->c->args.size, r->c->args.data
		);
		break;
	case UGH_UPSTREAM_FT_TIMEOUT:
		log_warn("upstream timeout (%.*s:%.*s%.*s%s%.*s, addr=%s:%u) while %.*s%s%.*s"
			, (int) r->u.host.size, r->u.host.data
			, (int) r->u.port.size, r->u.port.data
			, (int) r->u.uri.size, r->u.uri.data
			, r->u.args.size ? "?" : ""
			, (int) r->u.args.size, r->u.args.data
			, inet_ntoa(r->addr.sin_addr)
			, ntohs(r->addr.sin_port)
			, (int) r->c->uri.size, r->c->uri.data
			, r->c->args.size ? "?" : ""
			, (int) r->c->args.size, r->c->args.data
		);
		break;
	case UGH_UPSTREAM_FT_INVALID_HEADER:
		log_warn("invalid header in upstream response (%.*s:%.*s%.*s%s%.*s, addr=%s:%u) while %.*s%s%.*s"
			, (int) r->u.host.size, r->u.host.data
			, (int) r->u.port.size, r->u.port.data
			, (int) r->u.uri.size, r->u.uri.data
			, r->u.args.size ? "?" : ""
			, (int) r->u.args.size, r->u.args.data
			, inet_ntoa(r->addr.sin_addr)
			, ntohs(r->addr.sin_port)
			, (int) r->c->uri.size, r->c->uri.data
			, r->c->args.size ? "?" : ""
			, (int) r->c->args.size, r->c->args.data
		);
		break;
	case UGH_UPSTREAM_FT_HTTP_500:
	case UGH_UPSTREAM_FT_HTTP_502:
	case UGH_UPSTREAM_FT_HTTP_503:
	case UGH_UPSTREAM_FT_HTTP_504:
	case UGH_UPSTREAM_FT_HTTP_404:
	case UGH_UPSTREAM_FT_HTTP_5XX:
	case UGH_UPSTREAM_FT_HTTP_4XX:
		log_warn("error status %u in upstream response (%.*s:%.*s%.*s%s%.*s, addr=%s:%u) while %.*s%s%.*s"
			, r->status
			, (int) r->u.host.size, r->u.host.data
			, (int) r->u.port.size, r->u.port.data
			, (int) r->u.uri.size, r->u.uri.data
			, r->u.args.size ? "?" : ""
			, (int) r->u.args.size, r->u.args.data
			, inet_ntoa(r->addr.sin_addr)
			, ntohs(r->addr.sin_port)
			, (int) r->c->uri.size, r->c->uri.data
			, r->c->args.size ? "?" : ""
			, (int) r->c->args.size, r->c->args.data
		);
		break;
	case UGH_UPSTREAM_FT_TIMEOUT_CONNECT:
		log_warn("upstream connect timeout (%.*s:%.*s%.*s%s%.*s, addr=%s:%u) while %.*s%s%.*s"
			, (int) r->u.host.size, r->u.host.data
			, (int) r->u.port.size, r->u.port.data
			, (int) r->u.uri.size, r->u.uri.data
			, r->u.args.size ? "?" : ""
			, (int) r->u.args.size, r->u.args.data
			, inet_ntoa(r->addr.sin_addr)
			, ntohs(r->addr.sin_port)
			, (int) r->c->uri.size, r->c->uri.data
			, r->c->args.size ? "?" : ""
			, (int) r->c->args.size, r->c->args.data
		);
		break;
	}

	/* stop if full timeout is already ticked out */
	if (UGH_TIMEOUT_FULL == r->timeout_type && r->timeout < ev_now(loop) - r->response_time)
	{
		goto ok;
	}

	if (r->upstream && r->upstream_tries <= r->upstream->values_size
		&& (r->c->s->cfg->next_upstream & ft_type))
	{
		strp u_host;

		if (r->upstream_tries < r->upstream->values_size)
		{
			r->upstream_current += 1;

			/*
			 * XXX MEGA HACK for antmat, if upstream has choose random
			 * directive, we add additional (upstreams_count - 1) to current
			 * upstream to imitate choosing random upstream right after FIRST
			 * failure
			 */

			if (r->upstream->choose == UGH_UPSTREAM_CHOOSE_RANDOM && r->upstream_tries == 1)
			{
				r->upstream_current += aux_random() % (r->upstream->values_size - 1);
			}

			r->upstream_current %= r->upstream->values_size;
			r->upstream_tries++;

			r->addr.sin_family = AF_INET;
			r->addr.sin_port = htons(r->upstream->values[r->upstream_current].port);

			u_host = &r->upstream->values[r->upstream_current].host;
		}
		else if (0 < r->upstream->backup_values_size)
		{
			r->upstream->backup_values_curr += 1;
			r->upstream->backup_values_curr %= r->upstream->backup_values_size;
			r->upstream_tries++;

			r->addr.sin_family = AF_INET;
			r->addr.sin_port = htons(r->upstream->backup_values[r->upstream->backup_values_curr].port);

			u_host = &r->upstream->backup_values[r->upstream->backup_values_curr].host;
		}
		else
		{
			goto ok;
		}

		r->state = 0; /* XXX maybe here we should reinit the whole subreq structure? */

		r->body.data = NULL;
		r->body.size = 0;

		r->b_send.rpos = 0;
		r->b_send.wpos = 0;

		r->buf_recv.data = r->buf_recv_data;
		r->buf_recv.size = UGH_SUBREQ_BUF;

		ugh_subreq_gen(r, u_host);

		JudyLFreeArray(&r->headers_hash, PJE0);

		return ugh_resolver_addq(r->c->s->resolver, u_host->data, u_host->size, r->resolver_ctx);
	}

ok:

	r->ft_type = ft_type;
	r->response_time = ev_now(loop) - r->response_time;

	if (r->connection_time == 0)
	{
		r->connection_time = r->response_time;
	}

	if (/* NULL == r->handle &&*/ (r->flags & UGH_SUBREQ_WAIT))
	{
		r->c->wait--;

		/* We check is_main_coro here, because we could possibly call
		 * ugh_subreq_del from module coroutine (e.g. when IP-address of
		 * subrequest was definitely mallformed) and in this case we don't need
		 * to call coro_transfer
		 */
		if (0 == r->c->wait && is_main_coro)
		{
			is_main_coro = 0;
			coro_transfer(&ctx_main, &r->c->ctx);
			is_main_coro = 1;
		}

		/* coro_transfer(&ctx_main, &r->c->ctx); */
	}

	if ((r->flags & UGH_SUBREQ_PUSH))
	{
		ugh_header_t *h_content_type = ugh_subreq_header_get_nt(r, "Content-Type");
		ugh_channel_add_message(r->ch, &r->body, &h_content_type->value, r);
	}

	JudyLFreeArray(&r->headers_hash, PJE0);

	aux_pool_free(r->c->pool);

	return 0;
}