HTTP: Make LimitInputStream pollable for better async compatibility

Fixes #1307
This commit is contained in:
Marvin W 2022-11-04 15:29:18 -06:00
parent 6e37f3fe3f
commit e62955d3cf
No known key found for this signature in database
GPG key ID: 072E9235DB996F2A
3 changed files with 21 additions and 13 deletions

View file

@ -46,7 +46,7 @@ public class FileProvider : Dino.FileProvider, Object {
} }
} }
private class LimitInputStream : InputStream { private class LimitInputStream : InputStream, PollableInputStream {
InputStream inner; InputStream inner;
int64 remaining_size; int64 remaining_size;
@ -55,6 +55,20 @@ public class FileProvider : Dino.FileProvider, Object {
this.remaining_size = max_size; this.remaining_size = max_size;
} }
public bool can_poll() {
return inner is PollableInputStream && ((PollableInputStream)inner).can_poll();
}
public PollableSource create_source(Cancellable? cancellable = null) {
if (!can_poll()) throw new IOError.NOT_SUPPORTED("Stream is not pollable");
return ((PollableInputStream)inner).create_source(cancellable);
}
public bool is_readable() {
if (!can_poll()) throw new IOError.NOT_SUPPORTED("Stream is not pollable");
return ((PollableInputStream)inner).is_readable();
}
private ssize_t check_limit(ssize_t read) throws IOError { private ssize_t check_limit(ssize_t read) throws IOError {
this.remaining_size -= read; this.remaining_size -= read;
if (remaining_size < 0) throw new IOError.FAILED("Stream length exceeded limit"); if (remaining_size < 0) throw new IOError.FAILED("Stream length exceeded limit");
@ -69,6 +83,11 @@ public class FileProvider : Dino.FileProvider, Object {
return check_limit(yield inner.read_async(buffer, io_priority, cancellable)); return check_limit(yield inner.read_async(buffer, io_priority, cancellable));
} }
public ssize_t read_nonblocking_fn(uint8[] buffer) throws Error {
if (!is_readable()) throw new IOError.WOULD_BLOCK("Stream is not readable");
return read(buffer);
}
public override bool close(Cancellable? cancellable = null) throws IOError { public override bool close(Cancellable? cancellable = null) throws IOError {
return inner.close(cancellable); return inner.close(cancellable);
} }

View file

@ -7,15 +7,6 @@ find_packages(ENGINE_PACKAGES REQUIRED
ICU ICU
) )
set(ENGINE_DEFINITIONS "")
find_package(GIO)
if(GIO_VERSION VERSION_GREATER "2.60")
message(STATUS "ALPN support enabled")
set(ENGINE_DEFINITIONS ALPN_SUPPORT)
else()
message(STATUS "No ALPN support, needs GIO >= 2.60")
endif()
set(ENGINE_EXTRA_OPTIONS ${MAIN_EXTRA_OPTIONS} --vapidir=${CMAKE_CURRENT_SOURCE_DIR}/vapi) set(ENGINE_EXTRA_OPTIONS ${MAIN_EXTRA_OPTIONS} --vapidir=${CMAKE_CURRENT_SOURCE_DIR}/vapi)
vala_precompile(ENGINE_VALA_C vala_precompile(ENGINE_VALA_C
@ -154,8 +145,6 @@ GENERATE_HEADER
xmpp-vala xmpp-vala
CUSTOM_VAPIS CUSTOM_VAPIS
"${CMAKE_CURRENT_SOURCE_DIR}/src/glib_fixes.vapi" "${CMAKE_CURRENT_SOURCE_DIR}/src/glib_fixes.vapi"
DEFINITIONS
${ENGINE_DEFINITIONS}
OPTIONS OPTIONS
${ENGINE_EXTRA_OPTIONS} ${ENGINE_EXTRA_OPTIONS}
) )

View file

@ -19,7 +19,7 @@ public class Xmpp.DirectTlsXmppStream : TlsXmppStream {
debug("Connecting to %s:%i (tls)", host, port); debug("Connecting to %s:%i (tls)", host, port);
IOStream? io_stream = yield client.connect_to_host_async(host, port); IOStream? io_stream = yield client.connect_to_host_async(host, port);
TlsConnection tls_connection = TlsClientConnection.new(io_stream, new NetworkAddress(remote_name.to_string(), port)); TlsConnection tls_connection = TlsClientConnection.new(io_stream, new NetworkAddress(remote_name.to_string(), port));
#if ALPN_SUPPORT #if GLIB_2_60
tls_connection.set_advertised_protocols(ADVERTISED_PROTOCOLS); tls_connection.set_advertised_protocols(ADVERTISED_PROTOCOLS);
#endif #endif
tls_connection.accept_certificate.connect(on_invalid_certificate); tls_connection.accept_certificate.connect(on_invalid_certificate);