From baa4a6a1eb4e98558acfef6e2a24c2c13d42db5c Mon Sep 17 00:00:00 2001 From: Marvin W Date: Sat, 9 Apr 2022 00:28:42 +0200 Subject: [PATCH] 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 --- cmake/FindSoup.cmake | 31 --------------- cmake/FindSoup2.cmake | 31 +++++++++++++++ cmake/FindSoup3.cmake | 31 +++++++++++++++ plugins/http-files/CMakeLists.txt | 12 +++++- plugins/http-files/src/file_provider.vala | 47 +++++++++++++---------- plugins/http-files/src/file_sender.vala | 36 ++++++++++------- 6 files changed, 123 insertions(+), 65 deletions(-) delete mode 100644 cmake/FindSoup.cmake create mode 100644 cmake/FindSoup2.cmake create mode 100644 cmake/FindSoup3.cmake diff --git a/cmake/FindSoup.cmake b/cmake/FindSoup.cmake deleted file mode 100644 index d5afab48..00000000 --- a/cmake/FindSoup.cmake +++ /dev/null @@ -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) diff --git a/cmake/FindSoup2.cmake b/cmake/FindSoup2.cmake new file mode 100644 index 00000000..07ffed14 --- /dev/null +++ b/cmake/FindSoup2.cmake @@ -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) diff --git a/cmake/FindSoup3.cmake b/cmake/FindSoup3.cmake new file mode 100644 index 00000000..07b4893a --- /dev/null +++ b/cmake/FindSoup3.cmake @@ -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) diff --git a/plugins/http-files/CMakeLists.txt b/plugins/http-files/CMakeLists.txt index 77579fdb..2da46731 100644 --- a/plugins/http-files/CMakeLists.txt +++ b/plugins/http-files/CMakeLists.txt @@ -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 Gee GLib GModule GObject GTK3 - Soup + ${Soup} ) vala_precompile(HTTP_FILES_VALA_C @@ -19,6 +27,8 @@ CUSTOM_VAPIS ${CMAKE_BINARY_DIR}/exports/qlite.vapi PACKAGES ${HTTP_FILES_PACKAGES} +DEFINITIONS + ${HTTP_FILES_DEFINITIONS} ) add_definitions(${VALA_CFLAGS}) diff --git a/plugins/http-files/src/file_provider.vala b/plugins/http-files/src/file_provider.vala index 11885721..3a3aeb94 100644 --- a/plugins/http-files/src/file_provider.vala +++ b/plugins/http-files/src/file_provider.vala @@ -98,24 +98,26 @@ public class FileProvider : Dino.FileProvider, Object { var session = new Soup.Session(); session.user_agent = @"Dino/$(Dino.get_short_version()) "; var head_message = new Soup.Message("HEAD", http_receive_data.url); + head_message.request_headers.append("Accept-Encoding", "identity"); - if (head_message != null) { - head_message.request_headers.append("Accept-Encoding", "identity"); - try { - yield session.send_async(head_message, null); - } catch (Error e) { - throw new FileReceiveError.GET_METADATA_FAILED("HEAD request failed"); - } + try { +#if SOUP_3 + yield session.send_async(head_message, GLib.Priority.LOW, null); +#else + yield session.send_async(head_message, null); +#endif + } catch (Error e) { + throw new FileReceiveError.GET_METADATA_FAILED("HEAD request failed"); + } - string? content_type = null, content_length = null; - head_message.response_headers.foreach((name, val) => { - if (name.down() == "content-type") content_type = val; - if (name.down() == "content-length") content_length = val; - }); - file_meta.mime_type = content_type; - if (content_length != null) { - file_meta.size = int64.parse(content_length); - } + string? content_type = null, content_length = null; + head_message.response_headers.foreach((name, val) => { + if (name.down() == "content-type") content_type = val; + if (name.down() == "content-length") content_length = val; + }); + file_meta.mime_type = content_type; + if (content_length != null) { + file_meta.size = int64.parse(content_length); } return file_meta; @@ -129,11 +131,16 @@ public class FileProvider : Dino.FileProvider, Object { HttpFileReceiveData? http_receive_data = receive_data as HttpFileReceiveData; 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 { - var session = new Soup.Session(); - session.user_agent = @"Dino/$(Dino.get_short_version()) "; - Soup.Request request = session.request(http_receive_data.url); - InputStream stream = yield request.send_async(file_transfer.cancellable); +#if SOUP_3 + InputStream stream = yield session.send_async(get_message, GLib.Priority.LOW, file_transfer.cancellable); +#else + InputStream stream = yield session.send_async(get_message, file_transfer.cancellable); +#endif if (file_meta.size != -1) { return new LimitInputStream(stream, file_meta.size); } else { diff --git a/plugins/http-files/src/file_sender.vala b/plugins/http-files/src/file_sender.vala index 8a22ffe1..ab81ffce 100644 --- a/plugins/http-files/src/file_sender.vala +++ b/plugins/http-files/src/file_sender.vala @@ -73,6 +73,7 @@ public class HttpFileSender : FileSender, Object { } } +#if !SOUP_3 private static void transfer_more_bytes(InputStream stream, Soup.MessageBody body) { uint8[] bytes = new uint8[4096]; ssize_t read = stream.read(bytes); @@ -83,26 +84,35 @@ public class HttpFileSender : FileSender, Object { bytes.length = (int)read; 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 { Xmpp.XmppStream? stream = stream_interactor.get_stream(file_transfer.account); if (stream == null) return; - Soup.Message message = new Soup.Message("PUT", file_send_data.url_up); - 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(); + var session = new Soup.Session(); 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 { - yield session.send_async(message, file_transfer.cancellable); - if (message.status_code < 200 || message.status_code >= 300) { - throw new FileSendError.UPLOAD_FAILED("HTTP status code %s".printf(message.status_code.to_string())); +#if SOUP_3 + yield session.send_async(put_message, GLib.Priority.LOW, file_transfer.cancellable); +#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) { throw new FileSendError.UPLOAD_FAILED("HTTP upload error: %s".printf(e.message));