Skip to content

Port to libsoup3 and webkit2gtk-4.1 #728

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/cmake-ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,15 @@ jobs:
- mdview_packages:
- mdview_build_flag: off

- mdview_packages: libwebkit2gtk-4.0-dev libmarkdown2-dev
- mdview_packages: libwebkit2gtk-4.1-dev libmarkdown2-dev
build_mdview: mdview_on
- mdview_build_flag: on
build_mdview: mdview_on

- rest_packages:
- rest_build_flag: off

- rest_packages: libsoup2.4-dev libqrencode-dev libmarkdown2-dev
- rest_packages: libsoup-3.0-dev libqrencode-dev libmarkdown2-dev
build_rest: rest_on
- rest_build_flag: on
build_rest: rest_on
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/cmake-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
mingw-w64-x86_64-gstreamer
mingw-w64-x86_64-gst-plugins-base
mingw-w64-x86_64-json-glib
mingw-w64-x86_64-libsoup
mingw-w64-x86_64-libsoup3
mingw-w64-x86_64-qrencode
mingw-w64-x86_64-discount

Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.5)
project("pdfpc" C)
cmake_minimum_required(VERSION 3.0)

list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/vala)

Expand Down
11 changes: 4 additions & 7 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ Requirements

In order to compile and run pdfpc, the following requirements need to be met:

- cmake >= 3.0
- cmake >= 3.5
- vala >= 0.48
- gtk+ >= 3.22
- gee >= 0.8
Expand All @@ -107,15 +107,12 @@ In order to compile and run pdfpc, the following requirements need to be met:
- discount (aka markdown2)
- webkit2gtk
- json-glib
- libsoup
- libsoup3
- libqrencode

E.g., on Ubuntu 20.04 onward, you can install these dependencies with::
E.g., on Ubuntu 22.04 onward, you can install these dependencies with::

sudo apt-get install cmake valac libgee-0.8-dev libpoppler-glib-dev
libgtk-3-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
libjson-glib-dev libmarkdown2-dev libwebkit2gtk-4.0-dev libsoup2.4-dev
libqrencode-dev gstreamer1.0-gtk3
sudo apt-get install cmake valac libgee-0.8-dev libpoppler-glib-dev libgtk-3-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libjson-glib-dev libmarkdown2-dev libwebkit2gtk-4.1-dev libsoup3.0-dev libqrencode-dev gstreamer1.0-gtk3

(the last one is a run-time dependence). You should also consider installing all
plugins to support required video formats; chances are they are already present
Expand Down
8 changes: 4 additions & 4 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@ if (MDVIEW OR REST)
endif ()

if (MDVIEW)
pkg_check_modules(WEBKIT REQUIRED webkit2gtk-4.0)
set(MDVIEW_PACKAGES webkit2gtk-4.0)
pkg_check_modules(WEBKIT REQUIRED webkit2gtk-4.1)
set(MDVIEW_PACKAGES webkit2gtk-4.1)
endif ()

if (REST)
pkg_check_modules(SOUP REQUIRED libsoup-2.4)
pkg_check_modules(SOUP REQUIRED libsoup-3.0)
pkg_check_modules(QRENCODE REQUIRED libqrencode)
set(REST_PACKAGES
libsoup-2.4
libsoup-3.0
)

if (${CMAKE_HOST_WIN32})
Expand Down
70 changes: 34 additions & 36 deletions src/classes/rest_server.vala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*
* This file is part of pdfpc.
*
* Copyright (C) 2020 Evgeny Stambulchik
* Copyright (C) 2020,2024 Evgeny Stambulchik
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -242,10 +242,10 @@ namespace pdfpc {
}
}

private void static_handler(Soup.Server server, Soup.Message msg,
string path, GLib.HashTable? query, Soup.ClientContext client) {
private void static_handler(Soup.Server server, Soup.ServerMessage msg,
string path, GLib.HashTable? query) {

var fname = this.static_root + msg.uri.get_path();
var fname = this.static_root + path;
if (fname.has_suffix("/")) {
fname += "index.html";
}
Expand All @@ -261,51 +261,50 @@ namespace pdfpc {
out result_uncertain);
msg.set_response(mime, Soup.MemoryUse.COPY, raw_datau8);

msg.status_code = 200;
msg.set_status(200, null);
} catch (Error e) {
GLib.printerr("Failed opening file %s: %s\n", fname, e.message);
msg.status_code = 404;
msg.set_status(404, null);
}
}

private void api_handler(Soup.Server server, Soup.Message msg,
string path, GLib.HashTable<string, string>? query,
Soup.ClientContext client) {
private void api_handler(Soup.Server server, Soup.ServerMessage msg,
string path, GLib.HashTable<string, string>? query) {

// Once locked, serve only the single client
if (this.locked && this.client_host != client.get_host()) {
msg.status_code = 403;
if (this.locked && this.client_host != msg.get_remote_host()) {
msg.set_status(403, null);
GLib.printerr("Refused to serve client %s\n",
client.get_host());
msg.get_remote_host());
return;
}

var headers = msg.response_headers;
var headers = msg.get_response_headers();
headers.append("Access-Control-Allow-Origin", "*");
headers.append("Access-Control-Allow-Methods", "GET,PUT");
headers.append("Access-Control-Allow-Headers",
"authorization,content-type");

if (msg.method == "OPTIONS") {
msg.status_code = 204;
if (msg.get_method() == "OPTIONS") {
msg.set_status(204, null);
return;
}

// This must be the first call of the session
if (path == "/api/helo") {
if (!this.locked) {
this.locked = true;
this.client_host = client.get_host();
this.client_host = msg.get_remote_host();
// At this point the QR code may be withdrawn
this.metadata.controller.hide_qrcode();
}
} else if (!this.locked) {
// Anything else is forbidden until "lock-in" is in effect
msg.status_code = 412;
msg.set_status(412, null);
return;
}

msg.status_code = 200;
msg.set_status(200, null);

Json.Node root;

Expand All @@ -325,7 +324,7 @@ namespace pdfpc {
int slide_number = 0;
if (nparts < 2) {
root = this.error_data("Bad request");
msg.status_code = 400;
msg.set_status(400, null);
} else {
slide_number = int.parse(parts[1]);
if (nparts == 4 && query != null) {
Expand All @@ -345,14 +344,14 @@ namespace pdfpc {
}
}
root = this.error_data("Rendering failed");
msg.status_code = 500;
msg.set_status(500, null);
} else {
root = this.slide_data(slide_number);
}
}
} catch (Error e) {
root = this.error_data(e.message);
msg.status_code = 500;
msg.set_status(500, null);
}
} else if (path.has_prefix("/api/notes/")) {
try {
Expand All @@ -364,7 +363,7 @@ namespace pdfpc {
int slide_number = 0;
if (nparts < 2) {
root = this.error_data("Bad request");
msg.status_code = 400;
msg.set_status(400, null);
} else {
slide_number = int.parse(parts[1]);
if (nparts == 4) {
Expand Down Expand Up @@ -397,11 +396,11 @@ namespace pdfpc {
}
}
root = this.error_data("Rendering failed");
msg.status_code = 500;
msg.set_status(500, null);
break;
default:
root = this.error_data("Bad request");
msg.status_code = 400;
msg.set_status(400, null);
break;
}
} else {
Expand All @@ -410,10 +409,10 @@ namespace pdfpc {
}
} catch (Error e) {
root = this.error_data(e.message);
msg.status_code = 500;
msg.set_status(500, null);
}
} else if (path == "/api/control" && msg.method == "PUT") {
var body = msg.request_body;
} else if (path == "/api/control" && msg.get_method() == "PUT") {
var body = msg.get_request_body();
Json.Parser parser = new Json.Parser();
try {
parser.load_from_data((string) body.data,
Expand Down Expand Up @@ -450,19 +449,19 @@ namespace pdfpc {
}
} else {
root = this.error_data("Action not defined");
msg.status_code = 400;
msg.set_status(400, null);
}
} else {
root = this.error_data("Invalid request");
msg.status_code = 400;
msg.set_status(400, null);
}
} catch (Error e) {
root = this.error_data(e.message);
msg.status_code = 400;
msg.set_status(400, null);
}
} else {
root = this.error_data("Not found");
msg.status_code = 404;
msg.set_status(404, null);
}

if (root != null) {
Expand Down Expand Up @@ -531,9 +530,8 @@ namespace pdfpc {
}

// Perhaps optionally, the entire "/" path should be protected
var auth = new Soup.AuthDomainBasic(
Soup.AUTH_DOMAIN_REALM, "pdfpc REST service",
Soup.AUTH_DOMAIN_ADD_PATH, "/api");
var auth = new Soup.AuthDomainBasic("realm", "pdfpc REST service");
auth.add_path("/api");
auth.set_auth_callback((domain, msg, username, password) => {
if (username == "pdfpc" &&
password == Options.rest_passwd) {
Expand All @@ -546,10 +544,10 @@ namespace pdfpc {
});
auth.set_filter((domain, msg) => {
// Don't try to authenticate preflight CORS requests
if (msg.method == "OPTIONS") {
if (msg.get_method() == "OPTIONS") {
return false;
} else {
var path = msg.uri.get_path();
var path = msg.get_uri().get_path();
// Also, don't authenticate image or html "resources"
if (path.has_prefix("/api/slides") ||
path.has_prefix("/api/notes")) {
Expand Down
Loading