liGnuTLSFilter* li_gnutls_filter_new(
	liServer *srv, liWorker *wrk,
	const liGnuTLSFilterCallbacks *callbacks, gpointer data,
	gnutls_session_t session, liStream *crypt_source, liStream *crypt_drain
) {
	liEventLoop *loop = crypt_source->loop;
	liGnuTLSFilter *f;
	liCQLimit *out_limit;

	f = g_slice_new0(liGnuTLSFilter);
	f->refcount = 5; /* 1 + 4 streams */
	f->callbacks = callbacks;
	f->callback_data = data;
	f->srv = srv;
	f->wrk = wrk;

	f->session = session;
	gnutls_transport_set_ptr(f->session, (gnutls_transport_ptr_t) f);
	gnutls_transport_set_push_function(f->session, stream_push);
#ifdef HAVE_GIOVEC
	gnutls_transport_set_vec_push_function(f->session, stream_pushv);
#endif
	gnutls_transport_set_pull_function(f->session, stream_pull);

	gnutls_session_set_ptr(f->session, f);
	gnutls_handshake_set_post_client_hello_function(f->session, post_client_hello_cb);

	f->initial_handshaked_finished = 0;
	f->closing = f->aborted = 0;
	f->write_wants_read = 0;

	li_stream_init(&f->crypt_source, loop, stream_crypt_source_cb);
	li_stream_init(&f->crypt_drain, loop, stream_crypt_drain_cb);
	li_stream_init(&f->plain_source, loop, stream_plain_source_cb);
	li_stream_init(&f->plain_drain, loop, stream_plain_drain_cb);

	/* "virtual" connections - the content goes through SSL */
	li_stream_connect(&f->plain_drain, &f->crypt_source);
	li_stream_connect(&f->crypt_drain, &f->plain_source);

	li_stream_connect(crypt_source, &f->crypt_drain);
	li_stream_connect(&f->crypt_source, crypt_drain);

	/* separate limit for buffer of encrypted data
	 *
	 * f->plain_drain is already connected to f->crypt_source,
	 *   so they won't share the same limit */
	out_limit = li_cqlimit_new();
	out_limit->notify = stream_crypt_source_limit_notify_cb;
	out_limit->context = f;
	li_cqlimit_set_limit(out_limit, 32*1024);
	li_chunkqueue_set_limit(crypt_drain->out, out_limit);
	li_chunkqueue_set_limit(f->crypt_source.out, out_limit);
	li_cqlimit_release(out_limit);

	return f;
}
liStream* li_filter_buffer_on_disk(liVRequest *vr, goffset flush_limit, gboolean split_on_file_chunks) {
	bod_state *state = g_slice_new0(bod_state);
	state->vr = vr;
	state->flush_limit = flush_limit;
	state->split_on_file_chunks = split_on_file_chunks;
	li_stream_init(&state->stream, &vr->wrk->loop, bod_cb);
	return &state->stream;
}
LI_API liStream* li_stream_http_response_handle(liStream *http_in, liVRequest *vr, gboolean accept_cgi, gboolean accept_nph) {
	liStreamHttpResponse *shr = g_slice_new0(liStreamHttpResponse);
	shr->response_headers_finished = FALSE;
	shr->vr = vr;
	li_stream_init(&shr->stream, &vr->wrk->loop, stream_http_response_cb);
	li_http_response_parser_init(&shr->parse_response_ctx, &vr->response, http_in->out,
		accept_cgi, accept_nph);
	li_stream_connect(http_in, &shr->stream);
	return &shr->stream;
}
Exemple #4
0
void li_connection_start(liConnection *con, liSocketAddress remote_addr, int s, liServerSocket *srv_sock) {
	LI_FORCE_ASSERT(NULL == con->con_sock.data);

	con->srv_sock = srv_sock;
	con->state = LI_CON_STATE_REQUEST_START;
	con->mainvr->ts_started = con->ts_started = li_cur_ts(con->wrk);

	con->info.remote_addr = remote_addr;
	li_sockaddr_to_string(remote_addr, con->info.remote_addr_str, FALSE);

	con->info.local_addr = li_sockaddr_dup(srv_sock->local_addr);
	li_sockaddr_to_string(con->info.local_addr, con->info.local_addr_str, FALSE);

	con->info.aborted = FALSE;

	li_stream_init(&con->in, &con->wrk->loop, _connection_http_in_cb);
	li_stream_init(&con->out, &con->wrk->loop, _connection_http_out_cb);

	con->info.req = &con->in;
	con->info.resp = &con->out;

	li_connection_update_io_wait(con);

	if (srv_sock->new_cb) {
		if (!srv_sock->new_cb(con, s)) {
			li_connection_error(con);
			return;
		}
	} else {
		simple_tcp_new(con, s);
	}

	LI_FORCE_ASSERT(NULL != con->con_sock.raw_in || NULL != con->con_sock.raw_out);

	li_chunkqueue_use_limit(con->con_sock.raw_in->out, LI_CONNECTION_DEFAULT_CHUNKQUEUE_LIMIT);
	li_chunkqueue_use_limit(con->con_sock.raw_out->out, LI_CONNECTION_DEFAULT_CHUNKQUEUE_LIMIT);

	li_stream_connect(&con->out, con->con_sock.raw_out);
	li_stream_connect(con->con_sock.raw_in, &con->in);

	li_chunk_parser_init(&con->req_parser_ctx.chunk_ctx, con->con_sock.raw_in->out);
}