Prepare http-files plugin for libsoup-3 support

Note: ice plugin still depends on libsoup-2.4 and one can't have both
in the same process, so this remains disabled by default
This commit is contained in:
Marvin W 2022-04-09 00:28:42 +02:00
parent a0eac798cd
commit baa4a6a1eb
No known key found for this signature in database
GPG key ID: 072E9235DB996F2A
6 changed files with 123 additions and 65 deletions

View file

@ -1,31 +0,0 @@
include(PkgConfigWithFallback)
find_pkg_config_with_fallback(Soup
PKG_CONFIG_NAME libsoup-2.4
LIB_NAMES soup-2.4
INCLUDE_NAMES libsoup/soup.h
INCLUDE_DIR_SUFFIXES libsoup-2.4 libsoup-2.4/include libsoup libsoup/include
DEPENDS GIO
)
if(Soup_FOUND AND NOT Soup_VERSION)
find_file(Soup_VERSION_HEADER "libsoup/soup-version.h" HINTS ${Soup_INCLUDE_DIRS})
mark_as_advanced(Soup_VERSION_HEADER)
if(Soup_VERSION_HEADER)
file(STRINGS "${Soup_VERSION_HEADER}" Soup_MAJOR_VERSION REGEX "^#define SOUP_MAJOR_VERSION +\\(?([0-9]+)\\)?$")
string(REGEX REPLACE "^#define SOUP_MAJOR_VERSION \\(?([0-9]+)\\)?$" "\\1" Soup_MAJOR_VERSION "${Soup_MAJOR_VERSION}")
file(STRINGS "${Soup_VERSION_HEADER}" Soup_MINOR_VERSION REGEX "^#define SOUP_MINOR_VERSION +\\(?([0-9]+)\\)?$")
string(REGEX REPLACE "^#define SOUP_MINOR_VERSION \\(?([0-9]+)\\)?$" "\\1" Soup_MINOR_VERSION "${Soup_MINOR_VERSION}")
file(STRINGS "${Soup_VERSION_HEADER}" Soup_MICRO_VERSION REGEX "^#define SOUP_MICRO_VERSION +\\(?([0-9]+)\\)?$")
string(REGEX REPLACE "^#define SOUP_MICRO_VERSION \\(?([0-9]+)\\)?$" "\\1" Soup_MICRO_VERSION "${Soup_MICRO_VERSION}")
set(Soup_VERSION "${Soup_MAJOR_VERSION}.${Soup_MINOR_VERSION}.${Soup_MICRO_VERSION}")
unset(Soup_MAJOR_VERSION)
unset(Soup_MINOR_VERSION)
unset(Soup_MICRO_VERSION)
endif()
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Soup
REQUIRED_VARS Soup_LIBRARY
VERSION_VAR Soup_VERSION)

31
cmake/FindSoup2.cmake Normal file
View file

@ -0,0 +1,31 @@
include(PkgConfigWithFallback)
find_pkg_config_with_fallback(Soup2
PKG_CONFIG_NAME libsoup-2.4
LIB_NAMES soup-2.4
INCLUDE_NAMES libsoup/soup.h
INCLUDE_DIR_SUFFIXES libsoup-2.4 libsoup-2.4/include libsoup libsoup/include
DEPENDS GIO
)
if(Soup2_FOUND AND NOT Soup2_VERSION)
find_file(Soup2_VERSION_HEADER "libsoup/soup-version.h" HINTS ${Soup_INCLUDE_DIRS})
mark_as_advanced(Soup2_VERSION_HEADER)
if(Soup_VERSION_HEADER)
file(STRINGS "${Soup2_VERSION_HEADER}" Soup2_MAJOR_VERSION REGEX "^#define SOUP_MAJOR_VERSION +\\(?([0-9]+)\\)?$")
string(REGEX REPLACE "^#define SOUP_MAJOR_VERSION \\(?([0-9]+)\\)?$" "\\1" Soup_MAJOR_VERSION "${Soup2_MAJOR_VERSION}")
file(STRINGS "${Soup2_VERSION_HEADER}" Soup2_MINOR_VERSION REGEX "^#define SOUP_MINOR_VERSION +\\(?([0-9]+)\\)?$")
string(REGEX REPLACE "^#define SOUP_MINOR_VERSION \\(?([0-9]+)\\)?$" "\\1" Soup_MINOR_VERSION "${Soup2_MINOR_VERSION}")
file(STRINGS "${Soup2_VERSION_HEADER}" Soup2_MICRO_VERSION REGEX "^#define SOUP_MICRO_VERSION +\\(?([0-9]+)\\)?$")
string(REGEX REPLACE "^#define SOUP_MICRO_VERSION \\(?([0-9]+)\\)?$" "\\1" Soup_MICRO_VERSION "${Soup2_MICRO_VERSION}")
set(Soup_VERSION "${Soup2_MAJOR_VERSION}.${Soup2_MINOR_VERSION}.${Soup2_MICRO_VERSION}")
unset(Soup2_MAJOR_VERSION)
unset(Soup2_MINOR_VERSION)
unset(Soup2_MICRO_VERSION)
endif()
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Soup2
REQUIRED_VARS Soup2_LIBRARY
VERSION_VAR Soup2_VERSION)

31
cmake/FindSoup3.cmake Normal file
View file

@ -0,0 +1,31 @@
include(PkgConfigWithFallback)
find_pkg_config_with_fallback(Soup3
PKG_CONFIG_NAME libsoup-3.0
LIB_NAMES soup-3.0
INCLUDE_NAMES libsoup/soup.h
INCLUDE_DIR_SUFFIXES libsoup-2.4 libsoup-2.4/include libsoup libsoup/include
DEPENDS GIO
)
if(Soup3_FOUND AND NOT Soup3_VERSION)
find_file(Soup3_VERSION_HEADER "libsoup/soup-version.h" HINTS ${Soup3_INCLUDE_DIRS})
mark_as_advanced(Soup3_VERSION_HEADER)
if(Soup3_VERSION_HEADER)
file(STRINGS "${Soup3_VERSION_HEADER}" Soup3_MAJOR_VERSION REGEX "^#define SOUP_MAJOR_VERSION +\\(?([0-9]+)\\)?$")
string(REGEX REPLACE "^#define SOUP_MAJOR_VERSION \\(?([0-9]+)\\)?$" "\\1" Soup3_MAJOR_VERSION "${Soup3_MAJOR_VERSION}")
file(STRINGS "${Soup3_VERSION_HEADER}" Soup3_MINOR_VERSION REGEX "^#define SOUP_MINOR_VERSION +\\(?([0-9]+)\\)?$")
string(REGEX REPLACE "^#define SOUP_MINOR_VERSION \\(?([0-9]+)\\)?$" "\\1" Soup3_MINOR_VERSION "${Soup3_MINOR_VERSION}")
file(STRINGS "${Soup3_VERSION_HEADER}" Soup3_MICRO_VERSION REGEX "^#define SOUP_MICRO_VERSION +\\(?([0-9]+)\\)?$")
string(REGEX REPLACE "^#define SOUP_MICRO_VERSION \\(?([0-9]+)\\)?$" "\\1" Soup3_MICRO_VERSION "${Soup3_MICRO_VERSION}")
set(Soup3_VERSION "${Soup3_MAJOR_VERSION}.${Soup3_MINOR_VERSION}.${Soup3_MICRO_VERSION}")
unset(Soup3_MAJOR_VERSION)
unset(Soup3_MINOR_VERSION)
unset(Soup3_MICRO_VERSION)
endif()
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Soup3
REQUIRED_VARS Soup3_LIBRARY
VERSION_VAR Soup3_VERSION)

View file

@ -1,10 +1,18 @@
set(HTTP_FILES_DEFINITIONS)
if(USE_SOUP3)
set(Soup Soup3)
set(HTTP_FILES_DEFINITIONS ${HTTP_FILES_DEFINITIONS} SOUP_3)
else()
set(Soup Soup2)
endif()
find_packages(HTTP_FILES_PACKAGES REQUIRED find_packages(HTTP_FILES_PACKAGES REQUIRED
Gee Gee
GLib GLib
GModule GModule
GObject GObject
GTK3 GTK3
Soup ${Soup}
) )
vala_precompile(HTTP_FILES_VALA_C vala_precompile(HTTP_FILES_VALA_C
@ -19,6 +27,8 @@ CUSTOM_VAPIS
${CMAKE_BINARY_DIR}/exports/qlite.vapi ${CMAKE_BINARY_DIR}/exports/qlite.vapi
PACKAGES PACKAGES
${HTTP_FILES_PACKAGES} ${HTTP_FILES_PACKAGES}
DEFINITIONS
${HTTP_FILES_DEFINITIONS}
) )
add_definitions(${VALA_CFLAGS}) add_definitions(${VALA_CFLAGS})

View file

@ -98,24 +98,26 @@ public class FileProvider : Dino.FileProvider, Object {
var session = new Soup.Session(); var session = new Soup.Session();
session.user_agent = @"Dino/$(Dino.get_short_version()) "; session.user_agent = @"Dino/$(Dino.get_short_version()) ";
var head_message = new Soup.Message("HEAD", http_receive_data.url); var head_message = new Soup.Message("HEAD", http_receive_data.url);
head_message.request_headers.append("Accept-Encoding", "identity");
if (head_message != null) { try {
head_message.request_headers.append("Accept-Encoding", "identity"); #if SOUP_3
try { yield session.send_async(head_message, GLib.Priority.LOW, null);
yield session.send_async(head_message, null); #else
} catch (Error e) { yield session.send_async(head_message, null);
throw new FileReceiveError.GET_METADATA_FAILED("HEAD request failed"); #endif
} } catch (Error e) {
throw new FileReceiveError.GET_METADATA_FAILED("HEAD request failed");
}
string? content_type = null, content_length = null; string? content_type = null, content_length = null;
head_message.response_headers.foreach((name, val) => { head_message.response_headers.foreach((name, val) => {
if (name.down() == "content-type") content_type = val; if (name.down() == "content-type") content_type = val;
if (name.down() == "content-length") content_length = val; if (name.down() == "content-length") content_length = val;
}); });
file_meta.mime_type = content_type; file_meta.mime_type = content_type;
if (content_length != null) { if (content_length != null) {
file_meta.size = int64.parse(content_length); file_meta.size = int64.parse(content_length);
}
} }
return file_meta; return file_meta;
@ -129,11 +131,16 @@ public class FileProvider : Dino.FileProvider, Object {
HttpFileReceiveData? http_receive_data = receive_data as HttpFileReceiveData; HttpFileReceiveData? http_receive_data = receive_data as HttpFileReceiveData;
if (http_receive_data == null) assert(false); if (http_receive_data == null) assert(false);
var session = new Soup.Session();
session.user_agent = @"Dino/$(Dino.get_short_version()) ";
var get_message = new Soup.Message("GET", http_receive_data.url);
try { try {
var session = new Soup.Session(); #if SOUP_3
session.user_agent = @"Dino/$(Dino.get_short_version()) "; InputStream stream = yield session.send_async(get_message, GLib.Priority.LOW, file_transfer.cancellable);
Soup.Request request = session.request(http_receive_data.url); #else
InputStream stream = yield request.send_async(file_transfer.cancellable); InputStream stream = yield session.send_async(get_message, file_transfer.cancellable);
#endif
if (file_meta.size != -1) { if (file_meta.size != -1) {
return new LimitInputStream(stream, file_meta.size); return new LimitInputStream(stream, file_meta.size);
} else { } else {

View file

@ -73,6 +73,7 @@ public class HttpFileSender : FileSender, Object {
} }
} }
#if !SOUP_3
private static void transfer_more_bytes(InputStream stream, Soup.MessageBody body) { private static void transfer_more_bytes(InputStream stream, Soup.MessageBody body) {
uint8[] bytes = new uint8[4096]; uint8[] bytes = new uint8[4096];
ssize_t read = stream.read(bytes); ssize_t read = stream.read(bytes);
@ -83,26 +84,35 @@ public class HttpFileSender : FileSender, Object {
bytes.length = (int)read; bytes.length = (int)read;
body.append_buffer(new Soup.Buffer.take(bytes)); body.append_buffer(new Soup.Buffer.take(bytes));
} }
#endif
private async void upload(FileTransfer file_transfer, HttpFileSendData file_send_data, FileMeta file_meta) throws FileSendError { private async void upload(FileTransfer file_transfer, HttpFileSendData file_send_data, FileMeta file_meta) throws FileSendError {
Xmpp.XmppStream? stream = stream_interactor.get_stream(file_transfer.account); Xmpp.XmppStream? stream = stream_interactor.get_stream(file_transfer.account);
if (stream == null) return; if (stream == null) return;
Soup.Message message = new Soup.Message("PUT", file_send_data.url_up); var session = new Soup.Session();
message.request_headers.set_content_type(file_meta.mime_type, null);
message.request_headers.set_content_length(file_meta.size);
foreach (var entry in file_send_data.headers.entries) {
message.request_headers.append(entry.key, entry.value);
}
message.request_body.set_accumulate(false);
message.wrote_headers.connect(() => transfer_more_bytes(file_transfer.input_stream, message.request_body));
message.wrote_chunk.connect(() => transfer_more_bytes(file_transfer.input_stream, message.request_body));
Soup.Session session = new Soup.Session();
session.user_agent = @"Dino/$(Dino.get_short_version()) "; session.user_agent = @"Dino/$(Dino.get_short_version()) ";
var put_message = new Soup.Message("PUT", file_send_data.url_up);
#if SOUP_3
put_message.set_request_body(file_meta.mime_type, file_transfer.input_stream, (ssize_t) file_meta.size);
#else
put_message.request_headers.set_content_type(file_meta.mime_type, null);
put_message.request_headers.set_content_length(file_meta.size);
put_message.request_body.set_accumulate(false);
put_message.wrote_headers.connect(() => transfer_more_bytes(file_transfer.input_stream, put_message.request_body));
put_message.wrote_chunk.connect(() => transfer_more_bytes(file_transfer.input_stream, put_message.request_body));
#endif
foreach (var entry in file_send_data.headers.entries) {
put_message.request_headers.append(entry.key, entry.value);
}
try { try {
yield session.send_async(message, file_transfer.cancellable); #if SOUP_3
if (message.status_code < 200 || message.status_code >= 300) { yield session.send_async(put_message, GLib.Priority.LOW, file_transfer.cancellable);
throw new FileSendError.UPLOAD_FAILED("HTTP status code %s".printf(message.status_code.to_string())); #else
yield session.send_async(put_message, file_transfer.cancellable);
#endif
if (put_message.status_code < 200 || put_message.status_code >= 300) {
throw new FileSendError.UPLOAD_FAILED("HTTP status code %s".printf(put_message.status_code.to_string()));
} }
} catch (Error e) { } catch (Error e) {
throw new FileSendError.UPLOAD_FAILED("HTTP upload error: %s".printf(e.message)); throw new FileSendError.UPLOAD_FAILED("HTTP upload error: %s".printf(e.message));