Пример #1
0
static void cb_read(struct bufferevent *bev, void *arg)
{
	struct request_ctx *req = arg;
	char *line;
	size_t n;

	if (req->read_state == READ_NONE) {
		req->read_state = READ_STATUS;
	}

	while (req->read_state == READ_STATUS || req->read_state == READ_HEADERS) {

		line = read_line(bev, &n);
		if (line == NULL) {
			return;
		}

		if (req->read_state == READ_STATUS) {
			verbose(VERBOSE, "%s(): status line: '%s'\n", __func__, line);
			parse_status(req, line, n);
			set_read_state(req, READ_HEADERS);
		} else {
			while (line && req->read_state == READ_HEADERS) {
				if (*line == '\0') {
					set_read_state(req, READ_BODY);
				} else {
					char *key, *val;
					verbose(VERBOSE, "%s(): header line '%s'\n", __func__, line);
					header_keyval(&key, &val, line);
					handle_header(req, key, val);
					free(line);
					line = read_line(bev, &n);
				}
			}
		}

		free(line);

	}

	while (req->read_state == READ_BODY && evbuffer_get_length(bufferevent_get_input(bev)) > 0) {
		drain_body(req, bev);
	}

	if (req->read_state == READ_DONE) {
		request_done(req, bev);
	}

}
Пример #2
0
static void drain_body(struct request_ctx *req, struct bufferevent *bev)
{
	struct evbuffer *buf;
	struct evbuffer *saved;
	int before, after;

	if (req->chunked && req->chunk_size == -1) {
		/* Transfer-Encoding: chunked but we don't have size yet. */
		if (read_chunk_size(req, bev) != 0) {
			verbose(ERROR, "%s(): could not read chunk size!\n", __func__);
		}
	}

	buf = bufferevent_get_input(bev);

	saved = NULL;
	before = evbuffer_get_length(buf);
	if (req->chunked && req->chunk_size > 0 && req->chunk_left < before) {
		/*
		 * Save the real buffer away and give the callback
		 * a temporary one, just the chunk that remains.
		 */
		saved = buf;
		buf = evbuffer_new();
		evbuffer_remove_buffer(saved, buf, req->chunk_left);
		before = evbuffer_get_length(buf);
	}


	req->cb_ops->read(buf, req->cb_arg);
	after = evbuffer_get_length(buf);
	req->consumed += before - after;
	req->chunk_left -= (before - after);
	if (req->chunk_size > 0 && req->chunk_left == 0) {
		/* We've consumed the whole chunk.
		 * Signal that we need another one.
		 */
		req->chunk_size = -1;
	}

	if (saved != NULL) {
		/* saved is actually the buffer in bev */
		evbuffer_prepend_buffer(saved, buf);
		evbuffer_free(buf);
	}

	if ((req->chunked && req->chunk_size == 0) ||
	    (req->content_length > 0 && req->consumed == req->content_length)) {
		set_read_state(req, READ_DONE);
	}


}
Пример #3
0
void grpc_call_initial_metadata_complete(grpc_call_element *surface_element) {
  grpc_call *call = grpc_call_from_top_element(surface_element);
  set_read_state(call, READ_STATE_GOT_INITIAL_METADATA);
}
Пример #4
0
void grpc_call_stream_closed(grpc_call_element *elem) {
  grpc_call *call = CALL_FROM_TOP_ELEM(elem);
  set_read_state(call, READ_STATE_STREAM_CLOSED);
  grpc_call_internal_unref(call, 0);
}
Пример #5
0
void grpc_call_read_closed(grpc_call_element *elem) {
  set_read_state(CALL_FROM_TOP_ELEM(elem), READ_STATE_READ_CLOSED);
}