int script_client_run(struct script_client *sclient)
{
	int ret;

	sclient->ioloop = io_loop_create();

	if ( script_client_connect(sclient) >= 0 ) {
		/* run output */
		ret = 1;		
		if ( sclient->script_output != NULL &&
			(ret=o_stream_flush(sclient->script_output)) == 0 ) {
			o_stream_set_flush_callback
				(sclient->script_output, script_client_script_output, sclient);
		}

		/* run i/o event loop */
		if ( ret < 0 ) {
			sclient->error = SCRIPT_CLIENT_ERROR_IO;
		} else if ( sclient->io != NULL || ret == 0 ) {
			io_loop_run(sclient->ioloop);
		}

		/* finished */
		script_client_disconnect(sclient, FALSE);
	}

	io_loop_destroy(&sclient->ioloop);

	if ( sclient->error != SCRIPT_CLIENT_ERROR_NONE )
		return -1;

	return sclient->exit_code;
}
Пример #2
0
void http_client_wait(struct http_client *client)
{
	struct ioloop *prev_ioloop = current_ioloop;

	i_assert(client->ioloop == NULL);

	if (client->requests_count == 0)
		return;

	client->ioloop = io_loop_create();
	http_client_switch_ioloop(client);
	if (client->set.dns_client != NULL)
		dns_client_switch_ioloop(client->set.dns_client);
	/* either we're waiting for network I/O or we're getting out of a
	   callback using timeout_add_short(0) */
	i_assert(io_loop_have_ios(client->ioloop) ||
		 io_loop_have_immediate_timeouts(client->ioloop));

	do {
		http_client_debug(client,
			"Waiting for %d requests to finish", client->requests_count);
		io_loop_run(client->ioloop);
	} while (client->requests_count > 0);

	http_client_debug(client, "All requests finished");

	io_loop_set_current(prev_ioloop);
	http_client_switch_ioloop(client);
	if (client->set.dns_client != NULL)
		dns_client_switch_ioloop(client->set.dns_client);
	io_loop_set_current(client->ioloop);
	io_loop_destroy(&client->ioloop);
}
Пример #3
0
static int
cmd_dsync_server_run(struct doveadm_mail_cmd_context *_ctx,
		     struct mail_user *user)
{
	struct dsync_cmd_context *ctx = (struct dsync_cmd_context *)_ctx;
	struct dsync_ibc *ibc;
	struct dsync_brain *brain;
	string_t *temp_prefix, *state_str = NULL;
	enum dsync_brain_sync_type sync_type;
	const char *name;

	if (_ctx->conn != NULL) {
		/* doveadm-server connection. start with a success reply.
		   after that follows the regular dsync protocol. */
		ctx->fd_in = ctx->fd_out = -1;
		ctx->input = _ctx->conn->input;
		ctx->output = _ctx->conn->output;
		o_stream_nsend(ctx->output, "\n+\n", 3);
		i_set_failure_prefix("dsync-server(%s): ", user->username);
		name = i_stream_get_name(ctx->input);
	} else {
		/* the log messages go via stderr to the remote dsync,
		   so the names are reversed */
		i_set_failure_prefix("dsync-remote(%s): ", user->username);
		name = "local";
	}

	doveadm_user_init_dsync(user);

	temp_prefix = t_str_new(64);
	mail_user_set_get_temp_prefix(temp_prefix, user->set);

	ibc = cmd_dsync_icb_stream_init(ctx, name, str_c(temp_prefix));
	brain = dsync_brain_slave_init(user, ibc, FALSE);

	io_loop_run(current_ioloop);

	if (ctx->replicator_notify) {
		state_str = t_str_new(128);
		dsync_brain_get_state(brain, state_str);
	}
	sync_type = dsync_brain_get_sync_type(brain);

	if (dsync_brain_deinit(&brain) < 0)
		_ctx->exit_code = EX_TEMPFAIL;
	dsync_ibc_deinit(&ibc);

	if (_ctx->conn != NULL) {
		/* make sure nothing more is written by the generic doveadm
		   connection code */
		o_stream_close(_ctx->conn->output);
	}

	if (ctx->replicator_notify && _ctx->exit_code == 0)
		dsync_replicator_notify(ctx, sync_type, str_c(state_str));
	return _ctx->exit_code == 0 ? 0 : -1;
}
static void stats_top_start(struct top_context *ctx)
{
	struct timeout *to;

	stats_top_output(ctx);
	to = timeout_add(1000, stats_top_output, ctx);
	io_loop_run(current_ioloop);
	timeout_remove(&to);
}
Пример #5
0
static void fts_parser_tika_more(struct fts_parser *_parser,
				 struct message_block *block)
{
	struct tika_fts_parser *parser = (struct tika_fts_parser *)_parser;
	const unsigned char *data;
	size_t size;
	ssize_t ret;

	if (block->size > 0) {
		/* first we'll send everything to Tika */
		if (!parser->failed &&
		    http_client_request_send_payload(&parser->http_req,
						     block->data,
						     block->size) < 0)
			parser->failed = TRUE;
		block->size = 0;
		return;
	}

	if (parser->payload == NULL) {
		/* read the result from Tika */
		if (!parser->failed &&
		    http_client_request_finish_payload(&parser->http_req) < 0)
			parser->failed = TRUE;
		if (!parser->failed && parser->payload == NULL)
			http_client_wait(tika_http_client);
		if (parser->failed)
			return;
		i_assert(parser->payload != NULL);
	}
	/* continue returning data from Tika */
	while ((ret = i_stream_read_data(parser->payload, &data, &size, 0)) == 0) {
		if (parser->failed)
			return;
		/* wait for more input from Tika */
		if (parser->ioloop == NULL) {
			parser->ioloop = io_loop_create();
			parser->io = io_add_istream(parser->payload, io_loop_stop,
						    current_ioloop);
		} else {
			io_loop_set_current(parser->ioloop);
		}
		io_loop_run(current_ioloop);
	}
	if (size > 0) {
		i_assert(ret > 0);
		block->data = data;
		block->size = size;
		i_stream_skip(parser->payload, size);
	} else {
		/* finished */
		i_assert(ret == -1);
	}
}
Пример #6
0
int main(int argc, char **argv) {
    struct sigaction act;

    memset(&act, 0, sizeof(act));
    act.sa_handler = sigint_handler;

    DIE_IF_ERR(io_loop_init(&loop));
    DIE_IF_ERR(io_tcp_server(&loop, &server, "0.0.0.0", "5000"));
    DIE_IF_ERR(io_listen_start(&server, incoming_connection));
    DIE_IF_ERR(sigaction(SIGINT, &act, NULL));
    puts("echo server is up...");
    DIE_IF_ERR(io_loop_run(&loop));
    return 0;
}
Пример #7
0
static void cmd_proxy_list(int argc, char *argv[])
{
	struct proxy_context *ctx;
	bool seen_header = FALSE;

	ctx = cmd_proxy_init(argc, argv, "a:", cmd_proxy_list);

	doveadm_print_init(DOVEADM_PRINT_TYPE_TABLE);

	io_loop_set_running(current_ioloop);
	ipc_client_cmd(ctx->ipc, "proxy\t*\tLIST-FULL",
		       cmd_proxy_list_callback, &seen_header);
	if (io_loop_is_running(current_ioloop))
		io_loop_run(current_ioloop);
	ipc_client_deinit(&ctx->ipc);
}
Пример #8
0
void pop3c_client_run(struct pop3c_client *client)
{
	struct ioloop *ioloop, *prev_ioloop = current_ioloop;
	bool timeout_added = FALSE, failed = FALSE;

	i_assert(client->fd != -1 ||
		 client->state == POP3C_CLIENT_STATE_CONNECTING);

	ioloop = io_loop_create();
	pop3c_client_ioloop_changed(client);

	if (client->ip.family == 0) {
		/* we're connecting, start DNS lookup after our ioloop
		   is created */
		struct dns_lookup_settings dns_set;

		i_assert(client->state == POP3C_CLIENT_STATE_CONNECTING);
		memset(&dns_set, 0, sizeof(dns_set));
		dns_set.dns_client_socket_path =
			client->set.dns_client_socket_path;
		dns_set.timeout_msecs = POP3C_DNS_LOOKUP_TIMEOUT_MSECS;
		if (dns_lookup(client->set.host, &dns_set,
			       pop3c_dns_callback, client,
			       &client->dns_lookup) < 0)
			failed = TRUE;
	} else if (client->to == NULL) {
		client->to = timeout_add(POP3C_COMMAND_TIMEOUT_MSECS,
					 pop3c_client_timeout, client);
		timeout_added = TRUE;
	}

	if (!failed) {
		client->running = TRUE;
		io_loop_run(ioloop);
		client->running = FALSE;
	}

	if (timeout_added && client->to != NULL)
		timeout_remove(&client->to);

	current_ioloop = prev_ioloop;
	pop3c_client_ioloop_changed(client);
	current_ioloop = ioloop;
	io_loop_destroy(&ioloop);
}
Пример #9
0
int main(int argc, char **argv) {
   struct sigaction act;
   io_handle_t serv1, serv2, serv3, servr, watcher;
   sdp_session_t *session;

   memset(&act, 0, sizeof(act));
   act.sa_handler = sigint_handler;
   
   DIE_IF_ERR(storage_segregate(&storage, 12, 512));

   DIE_IF_ERR(io_loop_init(&loop));
   DIE_IF_ERR(io_file(&loop, &backup, "backup.txt", O_RDWR));
   DIE_IF_ERR(io_inotify(&loop, &watcher));
   DIE_IF_ERR(io_tcp_server(&loop, &serv1, "0.0.0.0", "3000"));
   DIE_IF_ERR(io_tcp_server(&loop, &serv2, "0.0.0.0", "4000"));
   DIE_IF_ERR(io_tcp_server(&loop, &serv3, "0.0.0.0", "5000"));
   DIE_IF_ERR(io_rfcomm_server(&loop, &servr, BDADDR_ANY, 4));
   
   lseek(backup.fd, 0, SEEK_END);

   DIE_IF_ERR(io_watch_start(&watcher, "/dev", IN_CREATE | IN_DELETE, file_changed));
   DIE_IF_ERR(io_channel(&channel));
   DIE_IF_ERR(io_channel_join(&channel, &backup, backup_updated));
   DIE_IF_ERR(io_channel_join(&channel, &tcp1, serl_updated));

   if(try_serial(&loop, &serl) == -1) puts("warning: arduino not connected.");
   else DIE_IF_ERR(io_publish_start(&serl, &channel, data_published));

   DIE_IF_ERR(io_listen_start(&serv1, new_tcp1_conn));
   DIE_IF_ERR(io_listen_start(&serv2, new_tcp2_conn));
   DIE_IF_ERR(io_listen_start(&serv3, new_tcp3_conn));
   DIE_IF_ERR(io_listen_start(&servr, new_rfcm_conn));

   session = io_rfcomm_advertise(4, name, desc, uuid128);
   DIE_IF_ERR(sigaction(SIGINT, &act, NULL));
   puts("pi server is up...");
   DIE_IF_ERR(io_loop_run(&loop));

   io_channel_close(&channel);
   storage_collapse(&storage);
   io_rfcomm_unadvertise(session);
   return 0;
}
Пример #10
0
static int fts_indexer_more_int(struct fts_indexer_context *ctx)
{
	struct ioloop *ioloop;
	struct io *io;
	struct timeout *to;
	int ret;

	if ((ret = fts_indexer_input(ctx)) != 0)
		return ret;

	/* wait for a while for the reply. FIXME: once search API supports
	   asynchronous waits, get rid of this wait and use the mail IO loop */
	ioloop = io_loop_create();
	io = io_add(ctx->fd, IO_READ, io_loop_stop, ioloop);
	to = timeout_add_short(INDEXER_WAIT_MSECS, io_loop_stop, ioloop);
	io_loop_run(ioloop);
	io_remove(&io);
	timeout_remove(&to);
	io_loop_destroy(&ioloop);

	return fts_indexer_input(ctx);
}
Пример #11
0
int program_client_run(struct program_client *pclient)
{
	int ret;

	/* reset */
	pclient->disconnected = FALSE;
	pclient->exit_code = 1;
	pclient->error = PROGRAM_CLIENT_ERROR_NONE;

	pclient->ioloop = io_loop_create();

	if ( (ret=program_client_connect(pclient)) >= 0 ) {
		/* run output */
		if ( ret > 0 && pclient->program_output != NULL &&
			(ret=o_stream_flush(pclient->program_output)) == 0 ) {
			o_stream_set_flush_callback
				(pclient->program_output, program_client_program_output, pclient);
		}

		/* run i/o event loop */
		if ( ret < 0 ) {
			pclient->error = PROGRAM_CLIENT_ERROR_IO;
		} else if ( !pclient->disconnected &&
			(ret == 0 || program_client_input_pending(pclient)) ) {
			io_loop_run(pclient->ioloop);
		}

		/* finished */
		program_client_disconnect(pclient, FALSE);
	}

	io_loop_destroy(&pclient->ioloop);

	if ( pclient->error != PROGRAM_CLIENT_ERROR_NONE )
		return -1;

	return pclient->exit_code;
}
Пример #12
0
static
void test_iostream_proxy_simple(void)
{
	size_t bytes;

	test_begin("iostream_proxy");
	int sfdl[2];
	int sfdr[2];

	int counter;

	test_assert(socketpair(AF_UNIX, SOCK_STREAM, 0, sfdl) == 0);
	test_assert(socketpair(AF_UNIX, SOCK_STREAM, 0, sfdr) == 0);

	fd_set_nonblock(sfdl[0], TRUE);
	fd_set_nonblock(sfdl[1], TRUE);
	fd_set_nonblock(sfdr[0], TRUE);
	fd_set_nonblock(sfdr[1], TRUE);

	struct ioloop *ioloop = io_loop_create();

	struct istream *left_in = i_stream_create_fd(sfdl[1], IO_BLOCK_SIZE);
	struct ostream *left_out = o_stream_create_fd(sfdl[1], IO_BLOCK_SIZE);

	struct istream *right_in = i_stream_create_fd(sfdr[1], IO_BLOCK_SIZE);
	struct ostream *right_out = o_stream_create_fd(sfdr[1], IO_BLOCK_SIZE);

	struct iostream_proxy *proxy;

	proxy = iostream_proxy_create(left_in, left_out, right_in, right_out);
	i_stream_unref(&left_in);
	o_stream_unref(&left_out);
	i_stream_unref(&right_in);
	o_stream_unref(&right_out);

	iostream_proxy_set_completion_callback(proxy, completed, &counter);
	iostream_proxy_start(proxy);

	left_in = i_stream_create_fd(sfdl[0], IO_BLOCK_SIZE);
	left_out = o_stream_create_fd(sfdl[0], IO_BLOCK_SIZE);

	right_in = i_stream_create_fd(sfdr[0], IO_BLOCK_SIZE);
	right_out = o_stream_create_fd(sfdr[0], IO_BLOCK_SIZE);

	test_assert(proxy != NULL);
	test_assert(o_stream_send_str(left_out, "hello, world") > 0);
	o_stream_flush(left_out);
	o_stream_unref(&left_out);
	test_assert(shutdown(sfdl[0], SHUT_WR) == 0);

	counter = 1;
	io_loop_run(ioloop);

	i_stream_read(right_in);
	test_assert(strcmp((const char*)i_stream_get_data(right_in, &bytes), "hello, world") == 0);
	i_stream_skip(right_in, bytes);

	test_assert(o_stream_send_str(right_out, "hello, world") > 0);
	o_stream_flush(right_out);
	o_stream_unref(&right_out);
	test_assert(shutdown(sfdr[0], SHUT_WR) == 0);

	counter = 1;
	io_loop_run(ioloop);

	i_stream_read(left_in);
	test_assert(strcmp((const char*)i_stream_get_data(left_in, &bytes), "hello, world") == 0);
	i_stream_skip(left_in, bytes);

	iostream_proxy_unref(&proxy);

	io_loop_destroy(&ioloop);

	i_stream_unref(&left_in);
	i_stream_unref(&right_in);

	/* close fd */
	close(sfdl[0]);
	close(sfdl[1]);
	close(sfdr[0]);
	close(sfdr[1]);

	test_end();
}
Пример #13
0
static void fts_parser_tika_more(struct fts_parser *_parser,
				 struct message_block *block)
{
	struct tika_fts_parser *parser = (struct tika_fts_parser *)_parser;
	struct ioloop *prev_ioloop = current_ioloop;
	const unsigned char *data;
	size_t size;
	ssize_t ret;

	if (block->size > 0) {
		/* first we'll send everything to Tika */
		if (!parser->failed &&
		    http_client_request_send_payload(&parser->http_req,
						     block->data,
						     block->size) < 0)
			parser->failed = TRUE;
		block->size = 0;
		return;
	}

	if (parser->payload == NULL) {
		/* read the result from Tika */
		if (!parser->failed &&
		    http_client_request_finish_payload(&parser->http_req) < 0)
			parser->failed = TRUE;
		if (!parser->failed && parser->payload == NULL)
			http_client_wait(tika_http_client);
		if (parser->failed)
			return;
		i_assert(parser->payload != NULL);
	}
	/* continue returning data from Tika. we'll create a new ioloop just
	   for reading this one payload. */
	while ((ret = i_stream_read_data(parser->payload, &data, &size, 0)) == 0) {
		if (parser->failed)
			break;
		/* wait for more input from Tika */
		if (parser->ioloop == NULL) {
			parser->ioloop = io_loop_create();
			parser->io = io_add_istream(parser->payload, io_loop_stop,
						    current_ioloop);
		} else {
			io_loop_set_current(parser->ioloop);
		}
		io_loop_run(current_ioloop);
	}
	/* switch back to original ioloop. */
	io_loop_set_current(prev_ioloop);

	if (parser->failed)
		;
	else if (size > 0) {
		i_assert(ret > 0);
		block->data = data;
		block->size = size;
		i_stream_skip(parser->payload, size);
	} else {
		/* finished */
		i_assert(ret == -1);
		if (parser->payload->stream_errno != 0) {
			i_error("read(%s) failed: %s",
				i_stream_get_name(parser->payload),
				i_stream_get_error(parser->payload));
			parser->failed = TRUE;
		}
	}
}
Пример #14
0
static int
dsync_connect_tcp(struct dsync_cmd_context *ctx,
		  const struct mail_storage_settings *mail_set,
		  const char *target, bool ssl, const char **error_r)
{
	struct doveadm_server *server;
	struct server_connection *conn;
	struct ioloop *ioloop;
	string_t *cmd;
	const char *error;

	server = p_new(ctx->ctx.pool, struct doveadm_server, 1);
	server->name = p_strdup(ctx->ctx.pool, target);
	if (ssl) {
		if (dsync_init_ssl_ctx(ctx, mail_set, &error) < 0) {
			*error_r = t_strdup_printf(
				"Couldn't initialize SSL context: %s", error);
			return -1;
		}
		server->ssl_ctx = ctx->ssl_ctx;
	}
	p_array_init(&server->connections, ctx->ctx.pool, 1);
	p_array_init(&server->queue, ctx->ctx.pool, 1);

	ioloop = io_loop_create();

	if (server_connection_create(server, &conn) < 0) {
		*error_r = "Couldn't create server connection";
		return -1;
	}

	/* <flags> <username> <command> [<args>] */
	cmd = t_str_new(256);
	if (doveadm_debug)
		str_append_c(cmd, 'D');
	str_append_c(cmd, '\t');
	str_append_tabescaped(cmd, ctx->ctx.cur_username);
	str_append(cmd, "\tdsync-server\t-u");
	str_append_tabescaped(cmd, ctx->ctx.cur_username);
	if (ctx->replicator_notify)
		str_append(cmd, "\t-U");
	str_append_c(cmd, '\n');

	ctx->tcp_conn = conn;
	server_connection_cmd(conn, str_c(cmd),
			      dsync_connected_callback, ctx);
	io_loop_run(ioloop);
	ctx->tcp_conn = NULL;

	if (array_count(&server->connections) > 0)
		server_connection_destroy(&conn);
	io_loop_destroy(&ioloop);

	if (ctx->error != NULL) {
		*error_r = ctx->error;
		ctx->error = NULL;
		return -1;
	}
	ctx->run_type = DSYNC_RUN_TYPE_STREAM;
	return 0;
}
Пример #15
0
static void cmd_dsync_run_remote(struct mail_user *user)
{
	i_set_failure_prefix("dsync-local(%s): ", user->username);
	io_loop_run(current_ioloop);
}
Пример #16
0
static int
http_client_request_continue_payload(struct http_client_request **_req,
	const unsigned char *data, size_t size)
{
	struct ioloop *prev_ioloop = current_ioloop;
	struct http_client_request *req = *_req;
	struct http_client_connection *conn = req->conn;
	struct http_client *client = req->client;
	int ret;

	i_assert(req->state == HTTP_REQUEST_STATE_NEW ||
		req->state == HTTP_REQUEST_STATE_PAYLOAD_OUT);
	i_assert(req->payload_input == NULL);

	if (conn != NULL)
		http_client_connection_ref(conn);
	http_client_request_ref(req);
	req->payload_wait = TRUE;

	if (data == NULL) {
		req->payload_input = NULL;
		if (req->state == HTTP_REQUEST_STATE_PAYLOAD_OUT)
			http_client_request_finish_payload_out(req);
	} else { 
		req->payload_input = i_stream_create_from_data(data, size);
		i_stream_set_name(req->payload_input, "<HTTP request payload>");
	}
	req->payload_size = 0;
	req->payload_chunked = TRUE;

	if (req->state == HTTP_REQUEST_STATE_NEW)
		http_client_request_submit(req);

	/* Wait for payload data to be written */

	i_assert(client->ioloop == NULL);
	client->ioloop = io_loop_create();
	http_client_switch_ioloop(client);
	if (client->set.dns_client != NULL)
		dns_client_switch_ioloop(client->set.dns_client);

	while (req->state < HTTP_REQUEST_STATE_PAYLOAD_IN) {
		http_client_request_debug(req, "Waiting for request to finish");
		
		if (req->state == HTTP_REQUEST_STATE_PAYLOAD_OUT)
			o_stream_set_flush_pending(req->payload_output, TRUE);
		io_loop_run(client->ioloop);

		if (req->state == HTTP_REQUEST_STATE_PAYLOAD_OUT &&
			req->payload_input->eof) {
			i_stream_unref(&req->payload_input);
			req->payload_input = NULL;
			break;
		}
	}

	io_loop_set_current(prev_ioloop);
	http_client_switch_ioloop(client);
	if (client->set.dns_client != NULL)
		dns_client_switch_ioloop(client->set.dns_client);
	io_loop_set_current(client->ioloop);
	io_loop_destroy(&client->ioloop);

	switch (req->state) {
	case HTTP_REQUEST_STATE_PAYLOAD_IN:
	case HTTP_REQUEST_STATE_FINISHED:
		ret = 1;
		break;
	case HTTP_REQUEST_STATE_ABORTED:
		ret = -1;
		break;
	default:
		ret = 0;
		break;
	}

	req->payload_wait = FALSE;

	/* callback may have messed with our pointer,
	   so unref using local variable */	
	if (!http_client_request_unref(&req))
		*_req = NULL;

	if (conn != NULL)
		http_client_connection_unref(&conn);

	/* Return status */
	return ret;
}
Пример #17
0
static ssize_t
http_server_istream_read(struct istream_private *stream)
{
	struct http_server_istream *hsristream =
		(struct http_server_istream *)stream;
	struct http_server_request *req = hsristream->req;
	struct http_server *server;
	struct http_server_connection *conn;
	bool blocking = stream->istream.blocking;
	ssize_t ret;

	if (req == NULL) {
		/* request already gone (we shouldn't get here) */
		stream->istream.stream_errno = EINVAL;
		return -1;
	}

	i_stream_seek(stream->parent, stream->parent_start_offset +
		      stream->istream.v_offset);

	server = hsristream->req->server;
	conn = hsristream->req->conn;

	ret = i_stream_read_copy_from_parent(&stream->istream);
	if (ret == 0 && blocking) {
		struct ioloop *prev_ioloop = current_ioloop;
		struct io *io;

		http_server_connection_ref(conn);
		http_server_request_ref(req);

		i_assert(server->ioloop == NULL);
		server->ioloop = io_loop_create();
		http_server_connection_switch_ioloop(conn);

		if (blocking && req->req.expect_100_continue &&
			!req->sent_100_continue)
			http_server_connection_trigger_responses(conn);

		hsristream->read_status = 0;
		io = io_add_istream(&stream->istream,
			http_server_istream_read_any, hsristream);
		while (req->state < HTTP_SERVER_REQUEST_STATE_FINISHED &&
			hsristream->read_status == 0) {
			io_loop_run(server->ioloop);
		}
		io_remove(&io);

		io_loop_set_current(prev_ioloop);
		http_server_connection_switch_ioloop(conn);
		io_loop_set_current(server->ioloop);
		io_loop_destroy(&server->ioloop);

		ret = hsristream->read_status;

		if (!http_server_request_unref(&req))
			hsristream->req = NULL;
		http_server_connection_unref(&conn);
	}

	return ret;
}