From 97cf261457db6c6e1181bb24c638dd6959ef3533 Mon Sep 17 00:00:00 2001 From: Guillaume Poirier-Morency Date: Fri, 8 Apr 2022 11:43:11 -0700 Subject: [PATCH 1/2] Migrate to libsoup3 --- meson.build | 2 +- src/meson.build | 4 ++ src/servers/meson.build | 1 + src/servers/vsgi-cgi.vala | 4 +- src/servers/vsgi-http.vala | 88 ++++++++++++++---------------- src/vsgi-application.vala | 2 +- src/vsgi-basic-authentication.vala | 4 +- src/vsgi-cookie-utils.vala | 12 ++-- src/vsgi-request.vala | 47 ++++++++++------ src/vsgi-server.vala | 2 +- src/vsgi-socket-server.vala | 37 ++++++++----- src/vsgi.vala | 7 +++ tests/cgi-test.vala | 10 ++-- tests/cookies-test.vala | 38 ++++++------- tests/http-server-test.vala | 2 +- tests/request-test.vala | 22 ++++---- tests/response-test.vala | 12 ++-- tests/socket-server-test.vala | 8 +-- 18 files changed, 165 insertions(+), 137 deletions(-) diff --git a/meson.build b/meson.build index 28ef8b07..9f175c75 100644 --- a/meson.build +++ b/meson.build @@ -15,7 +15,7 @@ gobject = dependency('gobject-2.0', version: '>=2.56') gio = dependency('gio-2.0', version: '>=2.56') gio_unix = dependency('gio-unix-2.0', version: '>=2.56') gmodule = dependency('gmodule-2.0', version: '>=2.40') -soup = dependency('libsoup-2.4', version: '>=2.62') +soup = dependency('libsoup-3.0') openssl = dependency('openssl') posix = meson.get_compiler('vala').find_library('posix') diff --git a/src/meson.build b/src/meson.build index 58c79b12..a453fad8 100644 --- a/src/meson.build +++ b/src/meson.build @@ -17,11 +17,15 @@ vsgi_sources = files( 'vsgi-server.vala', 'vsgi-socket-server.vala', 'vsgi-tee-output-stream.vala') +vsgi_internal_header = join_paths(meson.current_build_dir(), 'vsgi-@0@-internal.h'.format(api_version)) +vsgi_internal_vapi = join_paths(meson.current_build_dir(), 'vsgi-@0@-internal.vapi'.format(api_version)) vsgi_lib = library('vsgi-' + api_version, vsgi_sources, dependencies: [glib, gobject, gio, gio_unix, gmodule, soup, openssl, posix], vala_header: 'vsgi.h', vala_gir: 'VSGI-@0@.gir'.format(api_version), build_rpath: join_paths(meson.current_build_dir(), 'servers'), + vala_args: ['--internal-header', vsgi_internal_header, + '--internal-vapi', vsgi_internal_vapi], link_args: ['-Wl,--disable-new-dtags'], install: true, install_dir: [true, 'include/vsgi-' + api_version, true, true], diff --git a/src/servers/meson.build b/src/servers/meson.build index ffa21f0f..019c8e2c 100644 --- a/src/servers/meson.build +++ b/src/servers/meson.build @@ -1,5 +1,6 @@ shared_module('vsgi-http', ['vsgi-http.vala'], dependencies: [glib, gobject, gio, soup, vsgi_dep], + vala_args: ['--vapi', vsgi_internal_vapi], install: true, install_dir: join_paths(get_option('libdir'), 'vsgi-@0@/servers'.format(api_version))) diff --git a/src/servers/vsgi-cgi.vala b/src/servers/vsgi-cgi.vala index ab58181b..8781ecf5 100644 --- a/src/servers/vsgi-cgi.vala +++ b/src/servers/vsgi-cgi.vala @@ -42,9 +42,9 @@ namespace VSGI.CGI { [Version (since = "0.1")] public class Server : VSGI.Server { - public override SList uris { + public override SList uris { owned get { - return new SList (); + return new SList (); } } diff --git a/src/servers/vsgi-http.vala b/src/servers/vsgi-http.vala index f9d9e400..aa95a4b4 100644 --- a/src/servers/vsgi-http.vala +++ b/src/servers/vsgi-http.vala @@ -33,9 +33,9 @@ namespace VSGI.HTTP { public Soup.Server server { construct; get; } - public Soup.Message message { construct; get; } + public Soup.ServerMessage message { construct; get; } - public MessageBodyOutputStream (Soup.Server server, Soup.Message message) { + public MessageBodyOutputStream (Soup.Server server, Soup.ServerMessage message) { Object (server: server, message: message); } @@ -48,12 +48,12 @@ namespace VSGI.HTTP { // FIXME: throw a IOError here return -1; } - message.response_body.append_take (data); + message.get_response_body ().append_take (data); return data.length; } /** - * Resume I/O on the underlying {@link Soup.Message} to flush the + * Resume I/O on the underlying {@link Soup.ServerMessage} to flush the * written chunks. */ public override bool flush (Cancellable? cancellable = null) throws IOError { @@ -68,7 +68,7 @@ namespace VSGI.HTTP { if (finished) { throw new IOError.CONNECTION_CLOSED ("Connection closed by peer."); } - message.response_body.complete (); + message.get_response_body ().complete (); return true; } } @@ -83,9 +83,7 @@ namespace VSGI.HTTP { /** * Message underlying this request. */ - public Soup.Message message { construct; get; } - - public Soup.ClientContext client_context { construct; get; } + public Soup.ServerMessage message { construct; get; } /** * {@inheritDoc} @@ -96,18 +94,16 @@ namespace VSGI.HTTP { * @param msg message underlying this request * @param query parsed HTTP query provided by {@link Soup.ServerCallback} */ - public Request (Soup.Message msg, - Soup.ClientContext client_context, + public Request (Soup.ServerMessage msg, HashTable? query) { Object (message: msg, - client_context: client_context, - http_version: msg.http_version, + http_version: msg.get_http_version (), gateway_interface: "HTTP/1.1", - method: msg.method, - uri: msg.uri, + method: msg.get_method (), + uri: msg.get_uri (), query: query, - headers: msg.request_headers, - body: new MemoryInputStream.from_data (msg.request_body.data, null)); + headers: msg.get_request_headers (), + body: new MemoryInputStream.from_data (msg.get_request_body ().data, null)); } construct { @@ -119,9 +115,9 @@ namespace VSGI.HTTP { return null; } try { - return _client_context == null ? null : client_context.steal_connection (); + return _message == null ? null : message.steal_connection (); } finally { - _client_context = null; + _message = null; } } } @@ -138,16 +134,16 @@ namespace VSGI.HTTP { /** * Message underlying this response. */ - public Soup.Message message { construct; get; } + public Soup.ServerMessage message { construct; get; } public override uint status { - get { return this.message.status_code; } - set { this.message.status_code = value; } + get { return this.message.get_status (); } + set { this.message.set_status (value, null); } } public override string? reason_phrase { - owned get { return this.message.reason_phrase == "Unknown Error" ? null : this.message.reason_phrase; } - set { this.message.reason_phrase = value ?? Soup.Status.get_phrase (this.message.status_code); } + owned get { return this.message.get_reason_phrase () == "Unknown Error" ? null : this.message.get_reason_phrase (); } + set { this.message.set_status (this.message.get_status (), value ?? Soup.Status.get_phrase (this.message.get_status ())); } } /** @@ -155,11 +151,11 @@ namespace VSGI.HTTP { * * @param msg message underlying this response */ - public Response (Request req, Soup.Server soup_server, Soup.Message msg) { + public Response (Request req, Soup.Server soup_server, Soup.ServerMessage msg) { Object (request: req, soup_server: soup_server, message: msg, - headers: msg.response_headers, + headers: msg.get_response_headers (), body: new MessageBodyOutputStream (soup_server, msg)); } @@ -178,7 +174,7 @@ namespace VSGI.HTTP { /** * {@inheritDoc} * - * Implementation based on {@link Soup.Message} already handles the + * Implementation based on {@link Soup.ServerMessage} already handles the * writing of the status line. */ protected override bool write_status_line (Soup.HTTPVersion http_version, uint status, string reason_phrase, out size_t bytes_written, Cancellable? cancellable = null) throws IOError { @@ -192,7 +188,7 @@ namespace VSGI.HTTP { /** * {@inheritDoc} * - * Implementation based on {@link Soup.Message} already handles the + * Implementation based on {@link Soup.ServerMessage} already handles the * writing of the headers. */ protected override bool write_headers (Soup.MessageHeaders headers, out size_t bytes_written, Cancellable? cancellable = null) throws IOError { @@ -227,7 +223,7 @@ namespace VSGI.HTTP { [Description (blurb = "Percent-encoding in the Request-URI path will not be automatically decoded")] public bool raw_paths { construct; get; default = false; } - public override SList uris { + public override SList uris { owned get { return server.get_uris (); } @@ -240,36 +236,34 @@ namespace VSGI.HTTP { public bool init (Cancellable? cancellable = null) throws GLib.Error { if (https) { server = new Soup.Server ( - Soup.SERVER_RAW_PATHS, raw_paths, - Soup.SERVER_TLS_CERTIFICATE, tls_certificate); + "raw-paths", raw_paths, + "tls-certificate", tls_certificate); } else { - server = new Soup.Server ( - Soup.SERVER_RAW_PATHS, raw_paths, - Soup.SERVER_TLS_CERTIFICATE, tls_certificate); + server = new Soup.Server ("raw-paths", raw_paths); } // register a catch-all handler - server.add_handler (null, (server, msg, path, query, client) => { - msg.set_status (Soup.Status.OK); + server.add_handler (null, (server, msg, path, query) => { + msg.set_status (Soup.Status.OK, null); // prevent I/O as we handle everything asynchronously server.pause_message (msg); - var req = new Request (msg, client, query); + var req = new Request (msg, query); var res = new Response (req, server, msg); var auth = req.headers.get_one ("Authorization"); - if (auth != null) { - if (Soup.str_case_equal (auth.slice (0, 6), "Basic ")) { - var auth_data = (string) Base64.decode (auth.substring (6)); - if (auth_data.index_of_char (':') != -1) { - req.uri.set_user (auth_data.slice (0, auth.index_of_char (':'))); - } - } else if (Soup.str_case_equal (auth.slice (0, 7), "Digest ")) { - var auth_data = Soup.header_parse_param_list (auth.substring (7)); - req.uri.set_user (auth_data["username"]); - } - } + // if (auth != null) { + // if (VSGI.str_case_equal (auth.slice (0, 6), "Basic ")) { + // var auth_data = (string) Base64.decode (auth.substring (6)); + // if (auth_data.index_of_char (':') != -1) { + // req.uri.set_user (auth_data.slice (0, auth.index_of_char (':'))); + // } + // } else if (VSGI.str_case_equal (auth.slice (0, 7), "Digest ")) { + // var auth_data = Soup.header_parse_param_list (auth.substring (7)); + // req.uri.set_user (auth_data["username"]); + // } + // } handler.handle_async.begin (req, res, (obj, result) => { try { diff --git a/src/vsgi-application.vala b/src/vsgi-application.vala index 2f9807ee..ebac4b93 100644 --- a/src/vsgi-application.vala +++ b/src/vsgi-application.vala @@ -195,7 +195,7 @@ public class VSGI.Application : GLib.Application { } foreach (var uri in server.uris) { - message ("Listening on '%s'.", uri.to_string (false)); + message ("Listening on '%s'.", uri.to_string ()); } // keep the process (and workers) alive diff --git a/src/vsgi-basic-authentication.vala b/src/vsgi-basic-authentication.vala index 3b2b4e31..c6d6b5bd 100644 --- a/src/vsgi-basic-authentication.vala +++ b/src/vsgi-basic-authentication.vala @@ -37,13 +37,13 @@ public class VSGI.BasicAuthentication : Authentication { return false; } - if (!Soup.str_case_equal (header.slice (0, 5), "Basic")) { + if (!str_case_equal (header.slice (0, 5), "Basic")) { return false; } var authorization_data = (string) Base64.decode (header.substring (6)); - if (charset != null && !Soup.str_case_equal (charset, "UTF-8")) { + if (charset != null && !str_case_equal (charset, "UTF-8")) { try { authorization_data = convert (authorization_data, authorization_data.length, "UTF-8", charset); } catch (ConvertError err) { diff --git a/src/vsgi-cookie-utils.vala b/src/vsgi-cookie-utils.vala index 768e236c..f4d4d69f 100644 --- a/src/vsgi-cookie-utils.vala +++ b/src/vsgi-cookie-utils.vala @@ -41,9 +41,9 @@ namespace VSGI.CookieUtils { public void sign (Soup.Cookie cookie, ChecksumType checksum_type, uint8[] key) { var checksum = Hmac.compute_for_string (checksum_type, key, - Hmac.compute_for_string (checksum_type, key, cookie.@value) + cookie.name); + Hmac.compute_for_string (checksum_type, key, cookie.get_value ()) + cookie.get_name ()); - cookie.set_value (checksum + cookie.@value); + cookie.set_value (checksum + cookie.get_value ()); } /** @@ -63,19 +63,19 @@ namespace VSGI.CookieUtils { public bool verify (Soup.Cookie cookie, ChecksumType checksum_type, uint8[] key, out string? @value) { var checksum_length = Hmac.compute_for_string (checksum_type, key, "").length; - if (cookie.@value.length < checksum_length) { + if (cookie.get_value ().length < checksum_length) { @value = null; return false; } var checksum = Hmac.compute_for_string (checksum_type, key, - Hmac.compute_for_string (checksum_type, key, cookie.@value.substring (checksum_length)) + cookie.name); + Hmac.compute_for_string (checksum_type, key, cookie.get_value ().substring (checksum_length)) + cookie.get_name ()); assert (checksum_length == checksum.length); - if (OpenSSL.Crypto.memcmp (checksum, cookie.@value, checksum_length) == 0) { - @value = cookie.@value.substring (checksum_length); + if (OpenSSL.Crypto.memcmp (checksum, cookie.get_value (), checksum_length) == 0) { + @value = cookie.get_value ().substring (checksum_length); return true; } else { @value = null; diff --git a/src/vsgi-request.vala b/src/vsgi-request.vala index 5a98f120..8fe3d62d 100644 --- a/src/vsgi-request.vala +++ b/src/vsgi-request.vala @@ -121,6 +121,14 @@ namespace VSGI { [Version (since = "0.1")] public string method { get; construct; default = "GET"; } + /* all the necessary for building the URI during the construct phase if unset */ + private string? _uri_scheme; + private string? _uri_userinfo; + private string? _uri_host; + private int _uri_port; + private string? _uri_path_encoded; + private string? _uri_query; + /** * Request URI. * @@ -128,7 +136,7 @@ namespace VSGI { * made available through this property. */ [Version (since = "0.1")] - public Soup.URI uri { get; construct; } + public Uri uri { get; construct; } /** * HTTP query parsed if encoded according to percent-encoding, @@ -203,7 +211,7 @@ namespace VSGI { Soup.Cookie? found = null; foreach (var cookie in cookies) - if (cookie.name == name) + if (cookie.get_name () == name) found = cookie; return found; @@ -228,7 +236,7 @@ namespace VSGI { @value = null; foreach (var cookie in cookies) - if (cookie.name == name && CookieUtils.verify (cookie, checksum_type, key, out @value)) + if (cookie.get_name () == name && CookieUtils.verify (cookie, checksum_type, key, out @value)) found = cookie; return found; @@ -294,7 +302,7 @@ namespace VSGI { [Version (experimental = true)] public Request (IOStream? connection, string method, - Soup.URI uri, + Uri uri, HashTable? query = null, InputStream? body = null) { string[] empty_env = {}; // this is a hack for 'valac-0.24' and 'valac-0.26' @@ -317,7 +325,6 @@ namespace VSGI { [Version (experimental = true)] public Request.from_cgi_environment (IOStream? connection, [CCode (array_length = false, array_null_terminated = true)] string[] environment, InputStream? body = null) { base (connection: connection, - uri: new Soup.URI ("http://localhost/"), http_version: Environ.get_variable (environment, "SERVER_PROTOCOL") == "HTTP/1.1" ? Soup.HTTPVersion.@1_1 : Soup.HTTPVersion.@1_0, gateway_interface: Environ.get_variable (environment, "GATEWAY_INTERFACE") ?? "CGI/1.1", is_cgi: true, @@ -328,36 +335,36 @@ namespace VSGI { var https = Environ.get_variable (environment, "HTTPS"); var path_translated = Environ.get_variable (environment, "PATH_TRANSLATED"); if (https != null && https.length > 0 || path_translated != null && path_translated.has_prefix ("https://")) - uri.set_scheme ("https"); + _uri_scheme = "https"; else - uri.set_scheme ("http"); + _uri_scheme = "http"; - uri.set_user (Environ.get_variable (environment, "REMOTE_USER")); - uri.set_host (Environ.get_variable (environment, "SERVER_NAME")); + _uri_userinfo = Environ.get_variable (environment, "REMOTE_USER"); + _uri_host = Environ.get_variable (environment, "SERVER_NAME"); var port = Environ.get_variable (environment, "SERVER_PORT"); if (port != null) - uri.set_port (int.parse (port)); + _uri_port = int.parse (port); var path_info = Environ.get_variable (environment, "PATH_INFO"); var request_uri = Environ.get_variable (environment, "REQUEST_URI"); if (path_info != null && path_info.length > 0) - uri.set_path (Soup.URI.decode (path_info)); + _uri_path_encoded = path_info; else if (request_uri != null && request_uri.length > 0) - uri.set_path (Soup.URI.decode (request_uri.split ("?", 2)[0])); // strip the query + _uri_path_encoded = request_uri.split ("?", 2)[0]; // strip the query else - uri.set_path ("/"); + _uri_path_encoded = "/"; // raw & parsed HTTP query var query_string = Environ.get_variable (environment, "QUERY_STRING"); if (query_string != null && query_string.length > 0) { - uri.set_query (query_string); + _uri_query = query_string; _query = (HashTable) Soup.Form.decode (query_string); } else if (path_translated != null && "?" in path_translated) { - uri.set_query (path_translated.split ("?", 2)[1]); + _uri_query = path_translated.split ("?", 2)[1]; _query = (HashTable) Soup.Form.decode (path_translated.split ("?", 2)[1]); } else if (request_uri != null && "?" in request_uri) { - uri.set_query (request_uri.split ("?", 2)[1]); + _uri_query = request_uri.split ("?", 2)[1]; _query = (HashTable) Soup.Form.decode (request_uri.split ("?", 2)[1]); } @@ -389,9 +396,13 @@ namespace VSGI { _headers = new Soup.MessageHeaders (Soup.MessageHeadersType.REQUEST); } if (_query == null) { - _query = uri.get_query () == null ? null : (HashTable) Soup.Form.decode (uri.get_query ()); + _query = _uri.get_query () == null ? null : (HashTable) Soup.Form.decode (_uri.get_query ()); } else { - _uri.set_query_from_form (_query); + _uri_query = Soup.Form.encode (_query); + } + if (_uri == null) { + // TODO + _uri = Uri.build (UriFlags.ENCODED_PATH, _uri_scheme, _uri_userinfo, _uri_host, _uri_port, _uri_path_encoded, _uri_query, null); } } diff --git a/src/vsgi-server.vala b/src/vsgi-server.vala index 66b01844..2991797a 100644 --- a/src/vsgi-server.vala +++ b/src/vsgi-server.vala @@ -102,7 +102,7 @@ namespace VSGI { * URIs this server is listening on. */ [Version (since = "0.3")] - public abstract SList uris { owned get; } + public abstract SList uris { owned get; } /** * Prepare the server for listening on the provided socket address. diff --git a/src/vsgi-socket-server.vala b/src/vsgi-socket-server.vala index bb5d983e..2226aa6c 100644 --- a/src/vsgi-socket-server.vala +++ b/src/vsgi-socket-server.vala @@ -28,18 +28,19 @@ public abstract class VSGI.SocketServer : Server { public int backlog { construct; get; default = 10; } /** - * Scheme used for generated listening {@link Soup.URI}. + * Scheme used for generated listening {@link Uri}. */ [Version (since = "0.3")] protected abstract string scheme { get; } - private SList _uris = new SList (); + private SList _uris = new SList (); - public override SList uris { + public override SList uris { owned get { - var copy_uris = new SList (); + var copy_uris = new SList (); foreach (var uri in _uris) { - copy_uris.append (uri.copy ()); + // no need to copy the URI itself since it is immutable + copy_uris.append (uri); } return copy_uris; } @@ -63,27 +64,37 @@ public abstract class VSGI.SocketServer : Server { SocketProtocol.DEFAULT, null, out effective_address); + string scheme; + string? host; + string path; + int port; if (effective_address is InetSocketAddress) { var effective_inet_address = effective_address as InetSocketAddress; if (effective_inet_address.get_family () == SocketFamily.IPV4) { - _uris.append (new Soup.URI ("%s://%s:%u/".printf (scheme, - effective_inet_address.get_address ().to_string (), - effective_inet_address.get_port ()))); + scheme = "ipv4"; } else if (effective_inet_address.get_family () == SocketFamily.IPV6) { - _uris.append (new Soup.URI ("%s://[%s]:%u/".printf (scheme, - effective_inet_address.get_address ().to_string (), - effective_inet_address.get_port ()))); + scheme = "ipv6"; } + scheme = this.scheme; + host = effective_inet_address.get_address ().to_string (); + path = "/"; + port = effective_inet_address.get_port (); } else if (effective_address is UnixSocketAddress) { var effective_unix_address = effective_address as UnixSocketAddress; - _uris.append (new Soup.URI ("%s+unix://%s/".printf (scheme, effective_unix_address.get_path ()))); + scheme = this.scheme + "+unix"; + host = null; + path = effective_unix_address.get_path (); + port = 0; + } else { + assert_not_reached (); } + _uris.append (Uri.build (UriFlags.NONE, scheme, null, host, port, path, null, null)); } } public override void listen_socket (Socket socket) throws Error { socket_service.add_socket (socket, null); - _uris.append (new Soup.URI ("%s+fd://%d/".printf (scheme, socket.get_fd ()))); + _uris.append (Uri.build (UriFlags.NONE, scheme + "+fd", null, null, 0, socket.get_fd ().to_string (), null, null)); } public override void stop () { diff --git a/src/vsgi.vala b/src/vsgi.vala index 6dbb053b..412e8304 100644 --- a/src/vsgi.vala +++ b/src/vsgi.vala @@ -33,4 +33,11 @@ namespace VSGI { [Version (since = "0.3")] [CCode (has_target = false)] public delegate Type ServerInitFunc (TypeModule module); + + /** + * Replacement for what used to be Soup.str_case_equal but was removed in libsoup-3. + */ + internal bool str_case_equal (string s1, string s2) { + return s1.down() == s2.down(); + } } diff --git a/tests/cgi-test.vala b/tests/cgi-test.vala index a4063b58..a934ea0b 100644 --- a/tests/cgi-test.vala +++ b/tests/cgi-test.vala @@ -44,7 +44,7 @@ int main (string[] args) { assert ("root" == request.uri.get_user ()); assert ("0.0.0.0" == request.uri.get_host ()); assert ("a=b" == request.uri.get_query ()); - assert ("http://root@0.0.0.0:3003/?a=b" == request.uri.to_string (false)); + assert ("http://root@0.0.0.0:3003/?a=b" == request.uri.to_string ()); assert (request.query.contains ("a")); assert ("b" == request.query["a"]); assert (3003 == request.uri.get_port ()); @@ -119,7 +119,7 @@ int main (string[] args) { var request = new Request.from_cgi_environment (null, environment); - assert ("https" == request.uri.scheme); + assert ("https" == request.uri.get_scheme ()); }); /** @@ -137,7 +137,7 @@ int main (string[] args) { var request = new Request.from_cgi_environment (null, environment); - assert ("https" == request.uri.scheme); + assert ("https" == request.uri.get_scheme ()); }); /** @@ -155,7 +155,7 @@ int main (string[] args) { var request = new Request.from_cgi_environment (null, environment); assert ("GET" == request.method); - assert ("/home" == request.uri.path); + assert ("/home" == request.uri.get_path ()); assert ("a" in request.query); assert ("b" == request.query["a"]); }); @@ -174,7 +174,7 @@ int main (string[] args) { var request = new Request.from_cgi_environment (null, environment); - assert ("/home" == request.uri.path); + assert ("/home" == request.uri.get_path ()); }); /** diff --git a/tests/cookies-test.vala b/tests/cookies-test.vala index 1bd6b51d..f7bb26b3 100644 --- a/tests/cookies-test.vala +++ b/tests/cookies-test.vala @@ -24,7 +24,7 @@ public int main (string[] args) { * @since 0.1 */ Test.add_func ("/cookies/from_request", () => { - var req = new Request (null, "GET", new Soup.URI ("http://localhost/")); + var req = new Request (null, "GET", Uri.parse ("http://localhost/", UriFlags.NONE)); req.headers.append ("Cookie", "a=b, c=d"); req.headers.append ("Cookie", "e=f"); @@ -33,21 +33,21 @@ public int main (string[] args) { assert (3 == cookies.length ()); - assert ("a" == cookies.data.name); - assert ("b" == cookies.data.value); + assert ("a" == cookies.data.get_name ()); + assert ("b" == cookies.data.get_value ()); - assert ("c" == cookies.next.data.name); - assert ("d" == cookies.next.data.value); + assert ("c" == cookies.next.data.get_name ()); + assert ("d" == cookies.next.data.get_value ()); - assert ("e" == cookies.next.next.data.name); - assert ("f" == cookies.next.next.data.value); + assert ("e" == cookies.next.next.data.get_name ()); + assert ("f" == cookies.next.next.data.get_value ()); }); /** * @since 0.1 */ Test.add_func ("/cookies/from_response", () => { - var req = new Request (null, "GET", new Soup.URI ("http://localhost/")); + var req = new Request (null, "GET", Uri.parse ("http://localhost/", UriFlags.NONE)); var res = new Response (req); res.headers.append ("Set-Cookie", "a=b, c=d"); @@ -57,21 +57,21 @@ public int main (string[] args) { assert (3 == cookies.length ()); - assert ("a" == cookies.data.name); - assert ("b" == cookies.data.value); + assert ("a" == cookies.data.get_name ()); + assert ("b" == cookies.data.get_value ()); - assert ("c" == cookies.next.data.name); - assert ("d" == cookies.next.data.value); + assert ("c" == cookies.next.data.get_name ()); + assert ("d" == cookies.next.data.get_value ()); - assert ("e" == cookies.next.next.data.name); - assert ("f" == cookies.next.next.data.value); + assert ("e" == cookies.next.next.data.get_name ()); + assert ("f" == cookies.next.next.data.get_value ()); }); /** * @since 0.2 */ Test.add_func ("/cookies/lookup", () => { - var req = new Request (null, "GET", new Soup.URI ("http://localhost/")); + var req = new Request (null, "GET", Uri.parse ("http://localhost/", UriFlags.NONE)); req.headers.append ("Cookie", "a=b"); req.headers.append ("Cookie", "a=c"); // override @@ -80,8 +80,8 @@ public int main (string[] args) { var cookie = req.lookup_cookie ("a"); - assert ("a" == cookie.name); - assert ("c" == cookie.value); + assert ("a" == cookie.get_name ()); + assert ("c" == cookie.get_value ()); }); /** @@ -92,7 +92,7 @@ public int main (string[] args) { VSGI.CookieUtils.sign (cookie, ChecksumType.SHA256, "secret".data); - assert ("5d5305a844da2aa20b85bccd0067abf794ff439a9749c17527d8d9f7c2a6cf87value" == cookie.@value); + assert ("5d5305a844da2aa20b85bccd0067abf794ff439a9749c17527d8d9f7c2a6cf87value" == cookie.get_value ()); }); /** @@ -102,7 +102,7 @@ public int main (string[] args) { var cookie = new Soup.Cookie ("name", "", "0.0.0.0", "/", 3600); VSGI.CookieUtils.sign (cookie, ChecksumType.SHA256, "secret".data); - assert ("d6c8fc143254f1f9135210d09f6058414bbec029cc267f1e9c5e70da347eb3e9" == cookie.@value); + assert ("d6c8fc143254f1f9135210d09f6058414bbec029cc267f1e9c5e70da347eb3e9" == cookie.get_value ()); }); /** diff --git a/tests/http-server-test.vala b/tests/http-server-test.vala index 76f8d17b..ba380883 100644 --- a/tests/http-server-test.vala +++ b/tests/http-server-test.vala @@ -38,7 +38,7 @@ public int main (string[] args) { assert_not_reached (); } - assert ("https" == https_server.uris.data.scheme); + assert ("https" == https_server.uris.data.get_scheme ()); }); return Test.run (); diff --git a/tests/request-test.vala b/tests/request-test.vala index 618c2e28..01203ded 100644 --- a/tests/request-test.vala +++ b/tests/request-test.vala @@ -22,7 +22,7 @@ public int main (string[] args) { Test.init (ref args); Test.add_func ("/request/fill_query_from_uri", () => { - var req = new Request (null, "GET", new Soup.URI ("http://localhost/?a=b")); + var req = new Request (null, "GET", Uri.parse ("http://localhost/?a=b", UriFlags.NONE)); assert (req.query.contains ("a")); assert ("b" == req.query["a"]); @@ -31,13 +31,13 @@ public int main (string[] args) { Test.add_func ("/request/fill_uri_from_query", () => { var query = new HashTable (str_hash, str_equal); query.insert ("a", "b"); - var req = new Request (null, "GET", new Soup.URI ("http://localhost/"), query); + var req = new Request (null, "GET", Uri.parse ("http://localhost/", UriFlags.NONE), query); assert ("a=b" == req.uri.get_query ()); }); Test.add_func ("/request/convert/new_content_length", () => { - var req = new Request (null, "get", new Soup.URI ("http://localhost/")); + var req = new Request (null, "get", Uri.parse ("http://localhost/", UriFlags.NONE)); req.headers.set_content_length (50); @@ -47,7 +47,7 @@ public int main (string[] args) { }); Test.add_func ("/request/convert/eof_to_fixed_size", () => { - var req = new Request (null, "get", new Soup.URI ("http://localhost/")); + var req = new Request (null, "get", Uri.parse ("http://localhost/", UriFlags.NONE)); req.headers.set_encoding (Soup.Encoding.EOF); @@ -57,7 +57,7 @@ public int main (string[] args) { }); Test.add_func ("/request/convert/complete_sink", () => { - var req = new Request (null, "get", new Soup.URI ("http://localhost/")); + var req = new Request (null, "get", Uri.parse ("http://localhost/", UriFlags.NONE)); req.headers.set_content_length (50); @@ -68,7 +68,7 @@ public int main (string[] args) { }); Test.add_func ("/request/convert/chunked", () => { - var req = new Request (null, "get", new Soup.URI ("http://localhost/")); + var req = new Request (null, "get", Uri.parse ("http://localhost/", UriFlags.NONE)); req.headers.set_encoding (Soup.Encoding.CHUNKED); @@ -78,14 +78,14 @@ public int main (string[] args) { }); Test.add_func ("/request/lookup_query", () => { - assert (null == new Request (null, "GET", new Soup.URI ("http://localhost:3003/"), null).lookup_query ("a")); - assert (null == new Request (null, "GET", new Soup.URI ("http://localhost:3003/"), (HashTable) Soup.Form.decode ("b")).lookup_query ("a")); - assert (null == new Request (null, "GET", new Soup.URI ("http://localhost:3003/"), (HashTable) Soup.Form.decode ("a")).lookup_query ("a")); - assert ("b" == new Request (null, "GET", new Soup.URI ("http://localhost:3003/"), (HashTable) Soup.Form.decode ("a=b")).lookup_query ("a")); + assert (null == new Request (null, "GET", Uri.parse ("http://localhost:3003/", UriFlags.NONE), null).lookup_query ("a")); + assert (null == new Request (null, "GET", Uri.parse ("http://localhost:3003/", UriFlags.NONE), (HashTable) Soup.Form.decode ("b")).lookup_query ("a")); + assert (null == new Request (null, "GET", Uri.parse ("http://localhost:3003/", UriFlags.NONE), (HashTable) Soup.Form.decode ("a")).lookup_query ("a")); + assert ("b" == new Request (null, "GET", Uri.parse ("http://localhost:3003/", UriFlags.NONE), (HashTable) Soup.Form.decode ("a=b")).lookup_query ("a")); }); Test.add_func ("/request/steal_connection", () => { - var req = new Request (null, "GET", new Soup.URI ("http://localhost:3003/"), null); + var req = new Request (null, "GET", Uri.parse ("http://localhost:3003/", UriFlags.NONE), null); assert (req.connection != null); IOStream conn = req.steal_connection (); assert (conn != null); diff --git a/tests/response-test.vala b/tests/response-test.vala index 0a9699bc..af2424b9 100644 --- a/tests/response-test.vala +++ b/tests/response-test.vala @@ -4,7 +4,7 @@ public int main (string[] args) { Test.init (ref args); Test.add_func ("/response/write_head", () => { - var res = new Response (new Request (null, "GET", new Soup.URI ("http://localhost:3003/"))); + var res = new Response (new Request (null, "GET", Uri.parse ("http://localhost:3003/", UriFlags.NONE))); var wrote_status_line_emitted = false; var wrote_headers_emitted = false; @@ -32,7 +32,7 @@ public int main (string[] args) { }); Test.add_func ("/response/expand", () => { - var res = new Response (new Request (null, "GET", new Soup.URI ("http://localhost:3003/"))); + var res = new Response (new Request (null, "GET", Uri.parse ("http://localhost:3003/", UriFlags.NONE))); try { res.expand ("Hello world!".data); } catch (IOError err) { @@ -43,7 +43,7 @@ public int main (string[] args) { }); Test.add_func ("/response/expand_bytes", () => { - var res = new Response (new Request (null, "GET", new Soup.URI ("http://localhost:3003/"))); + var res = new Response (new Request (null, "GET", Uri.parse ("http://localhost:3003/", UriFlags.NONE))); try { res.expand_bytes (new Bytes.take ("Hello world!".data)); } catch (IOError err) { @@ -54,7 +54,7 @@ public int main (string[] args) { }); Test.add_func ("/response/expand_utf8", () => { - var res = new Response (new Request (null, "GET", new Soup.URI ("http://localhost:3003/"))); + var res = new Response (new Request (null, "GET", Uri.parse ("http://localhost:3003/", UriFlags.NONE))); try { res.expand_utf8 ("Hello world!"); } catch (IOError err) { @@ -68,7 +68,7 @@ public int main (string[] args) { }); Test.add_func ("/response/expand_utf8/preserve_existing_charset_attribute", () => { - var res = new Response (new Request (null, "GET", new Soup.URI ("http://localhost:3003/"))); + var res = new Response (new Request (null, "GET", Uri.parse ("http://localhost:3003/", UriFlags.NONE))); res.headers.set_content_type ("text/plain", Soup.header_parse_param_list ("charset=US-ASCII")); try { res.expand_utf8 ("Hello world!"); @@ -83,7 +83,7 @@ public int main (string[] args) { }); Test.add_func ("/response/tee", () => { - var res = new Response (new Request (null, "GET", new Soup.URI ("http://localhost:3003/"))); + var res = new Response (new Request (null, "GET", Uri.parse ("http://localhost:3003/", UriFlags.NONE))); var buffer = new MemoryOutputStream (null, realloc, free); res.tee (buffer); try { diff --git a/tests/socket-server-test.vala b/tests/socket-server-test.vala index e52c862f..b27c6fc4 100644 --- a/tests/socket-server-test.vala +++ b/tests/socket-server-test.vala @@ -40,8 +40,8 @@ public int main (string[] args) { assert_not_reached (); } - assert (server.uris.data.to_string (false).has_prefix ("mock://0.0.0.0:")); - assert (server.uris.next.data.to_string (false).has_prefix ("mock://[::]:")); + assert (server.uris.data.to_string ().has_prefix ("mock://0.0.0.0:")); + assert (server.uris.next.data.to_string ().has_prefix ("mock://[::]:")); }); Test.add_func ("/socket_server/listen/default", () => { @@ -69,7 +69,7 @@ public int main (string[] args) { FileUtils.unlink ("some-socket.sock"); } - assert ("mock+unix://some-socket.sock/" == server.uris.data.to_string (false)); + assert ("mock+unix://some-socket.sock/" == server.uris.data.to_string ()); }); Test.add_func ("/socket_server/listen_socket", () => { @@ -78,7 +78,7 @@ public int main (string[] args) { try { var socket = new Socket (SocketFamily.UNIX, SocketType.STREAM, SocketProtocol.DEFAULT); server.listen_socket (socket); - assert ("mock+fd://%d/".printf (socket.fd) == server.uris.data.to_string (false)); + assert ("mock+fd://%d/".printf (socket.fd) == server.uris.data.to_string ()); } catch (Error err) { assert_not_reached (); } finally { From 1e52fcc4ae6bf96a836f119935b51b4e86cef84c Mon Sep 17 00:00:00 2001 From: Guillaume Poirier-Morency Date: Sun, 10 Apr 2022 16:50:16 -0700 Subject: [PATCH 2/2] Add CI based on upcoming Ubuntu 22.04 LTS --- .github/workflows/main.yml | 47 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 .github/workflows/main.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 00000000..620f410a --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,47 @@ +name: CI + +on: [push, pull_request] + +jobs: + build: + runs-on: ${{ matrix.os }} + + strategy: + matrix: + os: [ubuntu-22.04] + + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v2 + + - name: Setup Vala PPA repository + run: sudo add-apt-repository --yes ppa:vala-team + + - name: Update APT cache + run: sudo apt-get update --quiet + + - name: Install dependencies + run: sudo apt-get install --yes valac libglib2.0-bin libglib2.0-dev libsoup3-dev libsystemd-dev libfcgi-dev gcovr valgrind ninja-build + + - name: Install Meson + run: pip3 install meson + + - name: Build + run: | + mkdir build + meson -D b_coverage=true -D enable_examples=true . build + ninja -C build -v + + - name: Test + run: | + meson test -C build --wrapper valgrind --print-errorlogs --num-processes=1 -v + DESTDIR=$(mktemp -d) ninja -C build -v install + +# - name: Generate coverage reports +# run: ninja -C build -v coverage + +# - name: Report coverage to Codecov +# uses: codecov/codecov-action@v2.1.0 +# with: +# directory: build +# fail_ci_if_error: true