Compare commits

...

12 Commits

Author SHA1 Message Date
Marvin W
322cafdc46 Automatically select appropriate libsoup version 2022-11-03 13:55:29 -06:00
Marvin W
8a1d58cb6f Don't use splice when handling input streams from libsoup-3 2022-11-02 10:38:40 -06:00
Marvin W
bf0fecf04f DTLS: Use ECDSA key 2022-11-02 10:38:40 -06:00
rim
1c72f95988 Fix crash when calling contact from Conversations (#1259)
fixes #1227
2022-11-02 10:38:40 -06:00
Marvin W
6c258c2f28 CMake: Fix version checks 2022-11-02 10:13:37 -06:00
Matthew Egeler
aa90175852 Support devices with multiple framerate options in get_max_fps (#1224) 2022-11-02 10:07:39 -06:00
foucault
d9c1eca888 Fix calculation of best camera framerate
When the algorithm iterates over all the available v4l2 capabilities it tries to determine the best framerate for each one of YUYV (video/x-raw) modes presented by the hardware (best_fraction, line 357 in device.vala). Regardless of what's determined to be the "best" YUYV mode from within the conditional right after (line 385) the best fractional framerate will always point to the last iterated framerate, which might be an extremely low one, like 7 or 5 FPS. When the framerate is then stored in the Gst.Structure (line 394) the fractional framerate will always be that last value which might be different than the correct one as calculated by best_fps (line 386). This workaround solves this issue by only updating best_fraction when the conditional in line 385 is satisfied.

from issue #1195
2022-11-02 10:07:31 -06:00
Marvin W
8b4b2b584f 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
2022-11-02 10:07:23 -06:00
Marvin W
565df4c237 Fix build of tests 2022-11-02 10:07:11 -06:00
Marvin W
8b508bb6de Allow cancellation of file transfers 2022-11-02 10:07:05 -06:00
Marvin W
9646630e1e Fix Version handling, add function to retrieve short version without git commit 2022-11-02 10:06:58 -06:00
fiaxh
48404edf47 Fix quote formating to not (partially) expect a space after > 2022-11-02 10:05:03 -06:00
27 changed files with 282 additions and 87 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

@ -20,6 +20,7 @@ function(find_packages result)
find_package(${pkg} ${pkg_version} REQUIRED)
list(APPEND _res ${${pkg}_PKG_CONFIG_NAME})
list(APPEND _res_libs ${${pkg}_LIBRARIES})
set(${pkg}_VERSION "${${pkg}_VERSION}" PARENT_SCOPE)
endforeach(pkg)
foreach(pkg ${ARGS_OPTIONAL})
string(REPLACE ">=" ";" pkg_ ${pkg})
@ -38,6 +39,7 @@ function(find_packages result)
if(${pkg}_FOUND)
list(APPEND _res ${${pkg}_PKG_CONFIG_NAME})
list(APPEND _res_libs ${${pkg}_LIBRARIES})
set(${pkg}_VERSION "${${pkg}_VERSION}" PARENT_SCOPE)
endif()
endforeach(pkg)
set(${result} "${_res}" PARENT_SCOPE)

33
cmake/SoupVersion.cmake Normal file
View File

@ -0,0 +1,33 @@
find_package(Nice QUIET)
if (Nice_FOUND AND NOT SOUP_VERSION AND NOT USE_SOUP3)
file(GET_RUNTIME_DEPENDENCIES
RESOLVED_DEPENDENCIES_VAR Nice_DEPENDENCIES
UNRESOLVED_DEPENDENCIES_VAR Nice_UNRESOLVED_DEPENDENCIES
LIBRARIES ${Nice_LIBRARY}
PRE_INCLUDE_REGEXES "soup|gupnp"
PRE_EXCLUDE_REGEXES "."
)
foreach (lib ${Nice_DEPENDENCIES})
if (lib MATCHES ".*/libsoup-3.*")
set(SOUP_VERSION 3)
endif ()
endforeach ()
foreach (lib ${Nice_DEPENDENCIES})
if (lib MATCHES ".*/libsoup-2.*")
set(SOUP_VERSION 2)
endif ()
endforeach ()
set(SOUP_VERSION ${SOUP_VERSION} CACHE STRING "Version of libsoup to use")
set_property(CACHE SOUP_VERSION PROPERTY STRINGS "2" "3")
message(STATUS "Using Soup${SOUP_VERSION} to provide Soup")
elseif (NOT SOUP_VERSION)
find_package(Soup2 QUIET)
find_package(Soup3 QUIET)
# Only use libsoup 3 if specifically requested or when libsoup 2 is not available
if (Soup3_FOUND AND NOT Soup2_FOUND OR USE_SOUP3)
set(SOUP_VERSION 3)
else ()
set(SOUP_VERSION 2)
endif ()
endif ()
set(Soup "Soup${SOUP_VERSION}")

6
configure vendored
View File

@ -1,7 +1,7 @@
#!/bin/sh
OPTS=`getopt -o "h" --long \
help,fetch-only,no-debug,disable-fast-vapi,with-tests,release,with-libsignal-in-tree,\
help,fetch-only,no-debug,disable-fast-vapi,with-tests,release,with-libsignal-in-tree,with-libsoup3,\
enable-plugin:,disable-plugin:,\
prefix:,program-prefix:,exec-prefix:,lib-suffix:,\
bindir:,libdir:,includedir:,datadir:,\
@ -22,6 +22,7 @@ DISABLE_FAST_VAPI=
LIB_SUFFIX=
NO_DEBUG=
FETCH_ONLY=
USE_SOUP3=
EXEC_PREFIX=
BINDIR=
@ -56,6 +57,7 @@ Configuration:
--release Configure to build an optimized release version
--with-libsignal-in-tree Build libsignal-protocol-c in tree and link it
statically.
--with-libsoup3 Build with libsoup-3.0
--with-tests Also build tests.
Plugin configuration:
@ -111,6 +113,7 @@ while true; do
--valac-flags ) VALAC_FLAGS="$2"; shift; shift ;;
--lib-suffix ) LIB_SUFFIX="$2"; shift; shift ;;
--with-libsignal-in-tree ) BUILD_LIBSIGNAL_IN_TREE=yes; shift ;;
--with-libsoup3 ) USE_SOUP3=yes; shift ;;
--disable-fast-vapi ) DISABLE_FAST_VAPI=yes; shift ;;
--no-debug ) NO_DEBUG=yes; shift ;;
--fetch-only ) FETCH_ONLY=yes; shift ;;
@ -256,6 +259,7 @@ cmake -G "$cmake_type" \
-DDISABLED_PLUGINS="$DISABLED_PLUGINS" \
-DBUILD_TESTS="$BUILD_TESTS" \
-DBUILD_LIBSIGNAL_IN_TREE="$BUILD_LIBSIGNAL_IN_TREE" \
-DUSE_SOUP3="$USE_SOUP3" \
-DVALA_EXECUTABLE="$VALAC" \
-DCMAKE_VALA_FLAGS="$VALACFLAGS" \
-DDISABLE_FAST_VAPI="$DISABLE_FAST_VAPI" \

View File

@ -89,7 +89,7 @@ DEPENDS
${CMAKE_BINARY_DIR}/exports/dino_i18n.h
)
add_definitions(${VALA_CFLAGS} -DDINO_SYSTEM_PLUGIN_DIR="${PLUGIN_INSTALL_DIR}" -DDINO_SYSTEM_LIBDIR_NAME="${LIBDIR_NAME}" -DG_LOG_DOMAIN="libdino")
add_definitions(${VALA_CFLAGS} -DDINO_SYSTEM_PLUGIN_DIR="${PLUGIN_INSTALL_DIR}" -DDINO_SYSTEM_LIBDIR_NAME="${LIBDIR_NAME}" -DG_LOG_DOMAIN="libdino" -DDINO_VERSION=\"${PROJECT_VERSION}\")
add_library(libdino SHARED ${LIBDINO_VALA_C} ${CMAKE_BINARY_DIR}/exports/dino_i18n.h)
add_dependencies(libdino dino-vapi)
target_link_libraries(libdino xmpp-vala qlite ${LIBDINO_PACKAGES} m)

View File

@ -1,7 +1,13 @@
using Dino.Entities;
namespace Dino {
extern const string VERSION;
public string get_version() { return VERSION; }
public string get_short_version() {
if (!VERSION.contains("~")) return VERSION;
return VERSION.split("~")[0] + "+";
}
public interface Application : GLib.Application {

View File

@ -70,6 +70,7 @@ public class FileTransfer : Object {
public State state { get; set; default=State.NOT_STARTED; }
public int provider { get; set; }
public string info { get; set; }
public Cancellable cancellable { get; default=new Cancellable(); }
private Database? db;
private string storage_dir;

View File

@ -45,7 +45,10 @@ public class Dino.PeerState : Object {
this.stream_interactor = stream_interactor;
this.calls = stream_interactor.get_module(Calls.IDENTITY);
var session_info_type = stream_interactor.module_manager.get_module(call.account, Xep.JingleRtp.Module.IDENTITY).session_info_type;
Xep.JingleRtp.Module jinglertp_module = stream_interactor.module_manager.get_module(call.account, Xep.JingleRtp.Module.IDENTITY);
if (jinglertp_module == null) return;
var session_info_type = jinglertp_module.session_info_type;
session_info_type.mute_update_received.connect((session,mute, name) => {
if (this.sid != session.sid) return;

View File

@ -246,7 +246,15 @@ public class FileManager : StreamInteractionModule, Object {
File file = File.new_for_path(Path.build_filename(get_storage_dir(), filename));
OutputStream os = file.create(FileCreateFlags.REPLACE_DESTINATION);
yield os.splice_async(input_stream, OutputStreamSpliceFlags.CLOSE_SOURCE|OutputStreamSpliceFlags.CLOSE_TARGET);
uint8[] buffer = new uint8[1024];
ssize_t read;
while ((read = yield input_stream.read_async(buffer, Priority.LOW, file_transfer.cancellable)) > 0) {
buffer.length = (int) read;
yield os.write_async(buffer, Priority.LOW, file_transfer.cancellable);
buffer.length = 1024;
}
yield input_stream.close_async(Priority.LOW, file_transfer.cancellable);
yield os.close_async(Priority.LOW, file_transfer.cancellable);
file_transfer.path = file.get_basename();
file_transfer.input_stream = yield file.read_async();
@ -292,14 +300,15 @@ public class FileManager : StreamInteractionModule, Object {
if (is_sender_trustworthy(file_transfer, conversation)) {
try {
yield get_file_meta(file_provider, file_transfer, conversation, receive_data);
if (file_transfer.size >= 0 && file_transfer.size < 5000000) {
yield download_file_internal(file_provider, file_transfer, conversation);
}
} catch (Error e) {
warning("Error downloading file: %s", e.message);
file_transfer.state = FileTransfer.State.FAILED;
}
if (file_transfer.size >= 0 && file_transfer.size < 5000000) {
download_file_internal.begin(file_provider, file_transfer, conversation, (_, res) => {
download_file_internal.end(res);
});
}
}
conversation.last_active = file_transfer.time;

View File

@ -48,7 +48,7 @@ public abstract class Gee.TestCase : Object {
}
public GLib.TestSuite get_suite () {
return this.suite;
return (owned) this.suite;
}
private class Adaptor {

View File

@ -212,7 +212,7 @@ OPTIONS
${MAIN_EXTRA_OPTIONS}
)
add_definitions(${VALA_CFLAGS} -DGETTEXT_PACKAGE=\"${GETTEXT_PACKAGE}\" -DLOCALE_INSTALL_DIR=\"${LOCALE_INSTALL_DIR}\" -DDINO_VERSION=\"${PROJECT_VERSION}\")
add_definitions(${VALA_CFLAGS} -DGETTEXT_PACKAGE=\"${GETTEXT_PACKAGE}\" -DLOCALE_INSTALL_DIR=\"${LOCALE_INSTALL_DIR}\")
add_executable(dino ${MAIN_VALA_C} ${MAIN_GRESOURCES_TARGET} src/emojichooser.c)
add_dependencies(dino ${GETTEXT_PACKAGE}-translations)
target_include_directories(dino PRIVATE src)

View File

@ -42,7 +42,7 @@ public class Dino.Ui.Application : Gtk.Application, Dino.Application {
startup.connect(() => {
if (print_version) {
print(@"Dino $(Dino.VERSION)\n");
print(@"Dino $(Dino.get_version())\n");
Process.exit(0);
}
@ -270,7 +270,7 @@ public class Dino.Ui.Application : Gtk.Application, Dino.Application {
}
private void show_about_window() {
string? version = Dino.VERSION.strip().length == 0 ? null : Dino.VERSION;
string? version = Dino.get_version().strip().length == 0 ? null : Dino.get_version();
if (version != null && !version.contains("git")) {
switch (version.substring(0, 3)) {
case "0.2": version = @"$version - <span font_style='italic'>Mexican Caribbean Coral Reefs</span>"; break;

View File

@ -19,6 +19,7 @@ public class FileDefaultWidget : EventBox {
public ModelButton file_open_button;
public ModelButton file_save_button;
public ModelButton cancel_button;
private FileTransfer.State state;
@ -27,6 +28,7 @@ public class FileDefaultWidget : EventBox {
this.leave_notify_event.connect(on_pointer_left_event);
file_open_button = new ModelButton() { text=_("Open"), visible=true };
file_save_button = new ModelButton() { text=_("Save as…"), visible=true };
cancel_button = new ModelButton() { text=_("Cancel"), visible=true };
}
public void update_file_info(string? mime_type, FileTransfer.State state, long size) {
@ -59,6 +61,18 @@ public class FileDefaultWidget : EventBox {
mime_label.label = _("Downloading %s…").printf(get_size_string(size));
spinner.active = true;
image_stack.set_visible_child_name("spinner");
// Create a menu
Gtk.PopoverMenu popover_menu = new Gtk.PopoverMenu();
Box file_menu_box = new Box(Orientation.VERTICAL, 0) { margin=10, visible=true };
file_menu_box.add(cancel_button);
popover_menu.add(file_menu_box);
file_menu.popover = popover_menu;
file_menu.button_release_event.connect(() => {
popover_menu.visible = true;
return true;
});
popover_menu.closed.connect(on_pointer_left);
break;
case FileTransfer.State.NOT_STARTED:
if (mime_description != null) {
@ -84,7 +98,7 @@ public class FileDefaultWidget : EventBox {
if (state == FileTransfer.State.NOT_STARTED) {
image_stack.set_visible_child_name("download_image");
}
if (state == FileTransfer.State.COMPLETE) {
if (state == FileTransfer.State.COMPLETE || state == FileTransfer.State.IN_PROGRESS) {
file_menu.opacity = 1;
}
return false;

View File

@ -131,6 +131,7 @@ public class FileDefaultWidgetController : Object {
widget.button_release_event.connect(on_clicked);
widget.file_open_button.clicked.connect(open_file);
widget.file_save_button.clicked.connect(save_file);
widget.cancel_button.clicked.connect(cancel_download);
}
public void set_file_transfer(FileTransfer file_transfer, StreamInteractor stream_interactor) {
@ -186,6 +187,10 @@ public class FileDefaultWidgetController : Object {
}
}
private void cancel_download() {
file_transfer.cancellable.cancel();
}
private bool on_clicked(EventButton event_button) {
switch (state) {
case FileTransfer.State.COMPLETE:

View File

@ -259,7 +259,7 @@ public static string parse_add_markup_theme(string s_, string? highlight_word, b
theme_dependent = true;
quote_match_info.fetch_pos(0, out start, out end);
return parse_add_markup_theme(s[0:start], highlight_word, parse_links, parse_text_markup, parse_quotes, dark_theme, ref theme_dependent, already_escaped) +
@"<span color='$dim_color'>$gt " + parse_add_markup_theme(s[start + gt.length + 1:end], highlight_word, parse_links, parse_text_markup, false, dark_theme, ref theme_dependent, already_escaped) + "</span>" +
@"<span color='$dim_color'>$gt" + parse_add_markup_theme(s[start + gt.length:end], highlight_word, parse_links, parse_text_markup, false, dark_theme, ref theme_dependent, already_escaped) + "</span>" +
parse_add_markup_theme(s[end:s.length], highlight_word, parse_links, parse_text_markup, parse_quotes, dark_theme, ref theme_dependent, already_escaped);
}
}

View File

@ -1,12 +1,19 @@
include(SoupVersion)
find_packages(HTTP_FILES_PACKAGES REQUIRED
Gee
GLib
GModule
GObject
GTK3
Soup
${Soup}
)
set(HTTP_FILES_DEFINITIONS)
if(${Soup}_VERSION VERSION_GREATER_EQUAL "3.0")
set(HTTP_FILES_DEFINITIONS ${HTTP_FILES_DEFINITIONS} SOUP_3_0)
endif()
vala_precompile(HTTP_FILES_VALA_C
SOURCES
src/file_provider.vala
@ -19,6 +26,8 @@ CUSTOM_VAPIS
${CMAKE_BINARY_DIR}/exports/qlite.vapi
PACKAGES
${HTTP_FILES_PACKAGES}
DEFINITIONS
${HTTP_FILES_DEFINITIONS}
)
add_definitions(${VALA_CFLAGS})

View File

@ -46,6 +46,38 @@ public class FileProvider : Dino.FileProvider, Object {
}
}
private class LimitInputStream : InputStream {
InputStream inner;
int64 remaining_size;
public LimitInputStream(InputStream inner, int64 max_size) {
this.inner = inner;
this.remaining_size = max_size;
}
private ssize_t check_limit(ssize_t read) throws IOError {
this.remaining_size -= read;
if (remaining_size < 0) throw new IOError.FAILED("Stream length exceeded limit");
return read;
}
public override ssize_t read(uint8[] buffer, Cancellable? cancellable = null) throws IOError {
return check_limit(inner.read(buffer, cancellable));
}
public override async ssize_t read_async(uint8[]? buffer, int io_priority = GLib.Priority.DEFAULT, Cancellable? cancellable = null) throws IOError {
return check_limit(yield inner.read_async(buffer, io_priority, cancellable));
}
public override bool close(Cancellable? cancellable = null) throws IOError {
return inner.close(cancellable);
}
public override async bool close_async(int io_priority = GLib.Priority.DEFAULT, Cancellable? cancellable = null) throws IOError {
return yield inner.close_async(io_priority, cancellable);
}
}
private void on_file_message(Entities.Message message, Conversation conversation) {
var additional_info = message.id.to_string();
@ -64,24 +96,28 @@ public class FileProvider : Dino.FileProvider, Object {
if (http_receive_data == null) return file_meta;
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) {
try {
yield session.send_async(head_message, null);
} catch (Error e) {
throw new FileReceiveError.GET_METADATA_FAILED("HEAD request failed");
}
try {
#if SOUP_3_0
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 == "Content-Type") content_type = val;
if (name == "Content-Length") content_length = val;
});
file_meta.mime_type = content_type;
if (content_length != null) {
file_meta.size = int.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;
@ -95,11 +131,21 @@ public class FileProvider : Dino.FileProvider, Object {
HttpFileReceiveData? http_receive_data = receive_data as HttpFileReceiveData;
if (http_receive_data == null) assert(false);
try {
var session = new Soup.Session();
Soup.Request request = session.request(http_receive_data.url);
var session = new Soup.Session();
session.user_agent = @"Dino/$(Dino.get_short_version()) ";
var get_message = new Soup.Message("GET", http_receive_data.url);
return yield request.send_async(null);
try {
#if SOUP_3_0
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 {
return stream;
}
} catch (Error e) {
throw new FileReceiveError.DOWNLOAD_FAILED("Downloading file error: %s".printf(e.message));
}

View File

@ -73,6 +73,7 @@ public class HttpFileSender : FileSender, Object {
}
}
#if !SOUP_3_0
private static void transfer_more_bytes(InputStream stream, Soup.MessageBody body) {
uint8[] bytes = new uint8[4096];
ssize_t read = stream.read(bytes);
@ -83,25 +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);
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_0
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) {
message.request_headers.append(entry.key, entry.value);
put_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();
try {
yield session.send_async(message);
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_0
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));

View File

@ -76,7 +76,7 @@ public class Handler {
int err = 0;
X509.PrivateKey private_key = X509.PrivateKey.create();
err = private_key.generate(PKAlgorithm.RSA, 2048);
err = private_key.generate(PKAlgorithm.ECDSA, 256);
throw_if_error(err);
var start_time = new DateTime.now_local().add_days(1);

View File

@ -221,7 +221,8 @@ namespace GnuTLS {
public enum PKAlgorithm {
UNKNOWN,
RSA,
DSA;
DSA,
ECDSA;
}
[CCode (cname = "gnutls_digest_algorithm_t", cprefix = "GNUTLS_DIG_", has_type_id = false)]

View File

@ -15,15 +15,15 @@ find_packages(RTP_PACKAGES REQUIRED
set(RTP_DEFINITIONS)
if(GstRtp_VERSION VERSION_GREATER "1.16")
if(GstRtp_VERSION VERSION_GREATER_EQUAL "1.16")
set(RTP_DEFINITIONS ${RTP_DEFINITIONS} GST_1_16)
endif()
if(GstRtp_VERSION VERSION_GREATER "1.18")
if(GstRtp_VERSION VERSION_GREATER_EQUAL "1.18")
set(RTP_DEFINITIONS ${RTP_DEFINITIONS} GST_1_18)
endif()
if(GLib_VERSION VERSION_GREATER "2.64")
if(GLib_VERSION VERSION_GREATER_EQUAL "2.64")
set(RTP_DEFINITIONS ${RTP_DEFINITIONS} GLIB_2_64)
endif()

View File

@ -354,6 +354,7 @@ public class Dino.Plugins.Rtp.Device : MediaDevice, Object {
int best_height = 0;
for (int i = 0; i < device.caps.get_size(); i++) {
unowned Gst.Structure? that = device.caps.get_structure(i);
Value? best_fraction_now = null;
if (!that.has_name("video/x-raw")) continue;
int num = 0, den = 0, width = 0, height = 0;
if (!that.has_field("framerate")) continue;
@ -369,7 +370,7 @@ public class Dino.Plugins.Rtp.Device : MediaDevice, Object {
int fps = den > 0 ? (num/den) : 0;
int in_fps = in_den > 0 ? (in_num/in_den) : 0;
if (in_fps > fps) {
best_fraction = fraction;
best_fraction_now = fraction;
num = in_num;
den = in_den;
}
@ -386,6 +387,7 @@ public class Dino.Plugins.Rtp.Device : MediaDevice, Object {
best_width = width;
best_height = height;
best_index = i;
best_fraction = best_fraction_now;
}
}
Gst.Caps res = caps_copy_nth(device.caps, best_index);

View File

@ -382,9 +382,27 @@ public class Dino.Plugins.Rtp.Plugin : RootInterface, VideoCallPlugin, Object {
int fps = 0;
for (int i = 0; i < device.device.caps.get_size(); i++) {
unowned Gst.Structure structure = device.device.caps.get_structure(i);
int num = 0, den = 0;
if (structure.has_field("framerate") && structure.get_fraction("framerate", out num, out den)) fps = int.max(fps, num / den);
if (structure.has_field("framerate")) {
Value framerate = structure.get_value("framerate");
if (framerate.type() == typeof(Gst.Fraction)) {
int num = Gst.Value.get_fraction_numerator(framerate);
int den = Gst.Value.get_fraction_denominator(framerate);
fps = int.max(fps, num / den);
} else if (framerate.type() == typeof(Gst.ValueList)) {
for(uint j = 0; j < Gst.ValueList.get_size(framerate); j++) {
Value fraction = Gst.ValueList.get_value(framerate, j);
int num = Gst.Value.get_fraction_numerator(fraction);
int den = Gst.Value.get_fraction_denominator(fraction);
fps = int.max(fps, num / den);
}
} else {
debug("Unknown type for framerate %s on device %s", framerate.type_name(), device.display_name);
}
}
}
debug("Max framerate for device %s: %d", device.display_name, fps);
return fps;
}

View File

@ -48,7 +48,7 @@ public abstract class Gee.TestCase : Object {
}
public GLib.TestSuite get_suite () {
return this.suite;
return (owned) this.suite;
}
private class Adaptor {

View File

@ -56,7 +56,7 @@ public abstract class Gee.TestCase : Object {
}
public GLib.TestSuite get_suite () {
return this.suite;
return (owned) this.suite;
}
}