Projects
openEuler:Mainline
libsoup3
Sign Up
Log In
Username
Password
We truncated the diff of some files because they were too big. If you want to see the full diff for every file,
click here
.
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 2
View file
_service:tar_scm:libsoup3.spec
Changed
@@ -1,15 +1,15 @@ -%global glib2_version 2.58.0 +%global glib2_version 2.69.1 Name: libsoup3 -Version: 3.0.6 +Version: 3.2.2 Release: 1 Summary: Soup, an HTTP library implementation License: LGPLv2 URL: https://wiki.gnome.org/Projects/libsoup -Source0: https://download.gnome.org/sources/libsoup/3.0/libsoup-%{version}.tar.xz -Patch0: xgettext.patch +Source0: https://download.gnome.org/sources/libsoup/3.2/libsoup-%{version}.tar.xz -BuildRequires: gcc meson gettext vala gtk-doc krb5-devel samba-winbind-clients +BuildRequires: gcc meson gettext vala krb5-devel samba-winbind-clients +BuildRequires: gi-docgen >= 2021.1 BuildRequires: pkgconfig(glib-2.0) BuildRequires: pkgconfig(gio-2.0) BuildRequires: glib-networking @@ -20,7 +20,7 @@ BuildRequires: pkgconfig(sysprof-capture-4) BuildRequires: pkgconfig(libnghttp2) -Recommends: glib-networking >= %{glib2_version} +Recommends: glib-networking >= %{glib2_version} %description Libsoup is an HTTP library implementation in C. It was originally part @@ -45,11 +45,10 @@ %package_help %prep -%autosetup -p0 -n libsoup-%{version} +%autosetup -p1 -n libsoup-%{version} %build -%global gtkdoc_flags -Dgtk_doc=true -%meson %gtkdoc_flags -Dtests=false -Dautobahn=disabled -Dhttp2_tests=disabled -Dpkcs11_tests=disabled +%meson -Ddocs=enabled -Dtests=false -Dautobahn=disabled -Dpkcs11_tests=disabled %meson_build %install @@ -72,8 +71,11 @@ %files help %doc README NEWS AUTHORS -%{_datadir}/gtk-doc/html/libsoup-3.0 +%{_datadir}/doc %changelog +* Mon Jan 2 2023 lin zhang <lin.zhang@turbolinux.com.cn> - 3.2.2-1 +- Update 3.2.2 + * Mon Apr 11 2022 lin zhang <lin.zhang@turbolinux.com.cn> - 3.0.6-1 - Initial packaging
View file
_service
Changed
@@ -2,7 +2,7 @@ <service name="tar_scm"> <param name="scm">git</param> <param name="url">git@gitee.com:src-openeuler/libsoup3.git</param> - <param name="revision">0ebfbf8ca5401f44e339b10bf310647970334d83</param> + <param name="revision">master</param> <param name="exclude">*</param> <param name="extract">*</param> </service>
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/.gitlab-ci/check-docs.py
Deleted
@@ -1,24 +0,0 @@ -#!/usr/bin/env python3 - -import sys - -with open('_build/docs/reference/libsoup-3.0-unused.txt') as f: - unused_docs = f.read() - -if unused_docs: - print('There is documentation not listed in libsoup-3.0-sections.txt:') - print(unused_docs) - sys.exit(1) - -with open('_build/docs/reference/libsoup-3.0-undocumented.txt') as f: - # The file starts with a summary - # undocumented_summary = ''.join(f.readline() for i in range(6)).strip() - print(f.readline()) # e.g. 95% symbol docs coverage. - for i in range(4): - f.readline() - undocumented_list = f.read().strip() - -if undocumented_list: - print('There is missing documentation for these symbols:') - print(undocumented_list) - sys.exit(1)
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/docs/reference/build-howto.xml
Deleted
@@ -1,70 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<?xml-model href="http://docbook.org/xml/5.1/rng/docbook.rng" schematypens="http://relaxng.org/ns/structure/1.0"?> -<?xml-model href="http://docbook.org/xml/5.1/sch/docbook.sch" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?> -<sect1 xmlns="http://docbook.org/ns/docbook" - xmlns:xlink="http://www.w3.org/1999/xlink" version="5.1"> - <title>Building with libsoup</title> - <sect3> - <title>Buildsystem Integration</title> - <para>Like other GNOME libraries, <application>libsoup</application> uses - <application>pkg-config</application> to provide compiler options. The package name is - "<literal>libsoup-3.0</literal>". </para> - <para>For example if you use Autotools:<informalexample> - <programlisting>PKG_CHECK_MODULES(LIBSOUP, libsoup-3.0) -AC_SUBST(LIBSOUP_CFLAGS) -AC_SUBST(LIBSOUP_LIBS)</programlisting> - </informalexample></para> - <para>If you use Meson: <informalexample> - <programlisting>libsoup_dep = dependency('libsoup-3.0')</programlisting> - </informalexample></para> - </sect3> - - <sect3> - <title>API Availability and Deprecation Warnings</title> -<para> -If you want to restrict your program to a particular -<application>libsoup</application> version or range of versions, you -can define <link -linkend="SOUP-VERSION-MIN-REQUIRED:CAPS"><literal>SOUP_VERSION_MIN_REQUIRED</literal></link> -and/or <link -linkend="SOUP-VERSION-MAX-ALLOWED:CAPS"><literal>SOUP_VERSION_MAX_ALLOWED</literal></link>. -For example with Autotools: -</para> - -<informalexample><programlisting>LIBSOUP_CFLAGS="$LIBSOUP_CFLAGS -DSOUP_VERSION_MIN_REQUIRED=SOUP_VERSION_3_0" -LIBSOUP_CFLAGS="$LIBSOUP_CFLAGS -DSOUP_VERSION_MAX_ALLOWED=SOUP_VERSION_3_2"</programlisting></informalexample> - - <para>Or with Meson:</para> - - <informalexample><programlisting>add_project_arguments( - '-DSOUP_VERSION_MIN_REQUIRED=SOUP_VERSION_2_99', - '-DSOUP_VERSION_MAX_ALLOWED=SOUP_VERSION_3_0', - language: 'c' -)</programlisting></informalexample> - -<para>The <literal>SOUP_VERSION_MIN_REQUIRED</literal> declaration states that the code is not - expected to compile on versions of <application>libsoup</application> older than the - indicated version, and so the compiler should print warnings if the code uses - functions that were deprecated as of that release.</para> - -<para>The <literal>SOUP_VERSION_MAX_ALLOWED</literal> declaration states that the code - <emphasis>is</emphasis> expected to compile on versions of - <application>libsoup</application> up to the indicated version, and so, when - compiling the program against a newer version than that, the compiler should print warnings - if the code uses functions that did not yet exist in the max-allowed release.</para> - -<para>You can use <link linkend="SOUP-CHECK-VERSION:CAPS"><literal>SOUP_CHECK_VERSION</literal></link> to check the version of libsoup at compile - time, to compile different code for different <application>libsoup</application> versions. - (If you are setting <literal>SOUP_VERSION_MIN_REQUIRED</literal> and - <literal>SOUP_VERSION_MAX_ALLOWED</literal> to different versions, as in the example - above, then you almost certainly need to be doing this.)</para> - </sect3> - <sect3> - <title>Headers</title> - - <para>Code using <application>libsoup</application> should include the header like so:</para> -<informalexample><programlisting> -#include <libsoup/soup.h> -</programlisting></informalexample> - </sect3> -</sect1>
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/docs/reference/client-advanced.xml
Deleted
@@ -1,171 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<?xml-model href="http://docbook.org/xml/5.1/rng/docbook.rng" schematypens="http://relaxng.org/ns/structure/1.0"?> -<?xml-model href="http://docbook.org/xml/5.1/sch/docbook.sch" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?> -<sect1 xmlns="http://docbook.org/ns/docbook" - xmlns:xlink="http://www.w3.org/1999/xlink" version="5.1"> - <title>Advanced Usage</title> - <sect2> - <title>Customizing Session Options</title> - <para>When you create the session with <link linkend="soup-session-new-with-options"><function>soup_session_new_with_options()</function></link>, - you can specify various additional options. See the <link -linkend="SoupSession"><type>SoupSession</type> documentation</link> for more details but these may be interesting: - <link linkend="SoupSession:max-conns"><literal>SoupSession:max-conns</literal></link> and <link linkend="SoupSession:max-conns-per-host"><literal>SoupSession:max-conns-per-host</literal></link>, - <link linkend="SoupSession:user-agent"><literal>SoupSession:user-agent</literal></link>, <link linkend="SoupSession:timeout"><literal>SoupSession:timeout</literal></link>, - <link linkend="SoupSession:accept-language"><literal>SoupSession:accept-language</literal></link> and <link linkend="SoupSession:accept-language-auto"><literal>SoupSession:accept-language-auto</literal></link></para> - </sect2> - <sect2> - <title>Adding Session Features</title> - <para>Additional session functionality is provided as <link -linkend="SoupSessionFeature"><type>SoupSessionFeature</type></link>s, -which can be added to or removed from a session.</para> - - <para>One such feature is <link linkend="SoupContentDecoder"><type>SoupContentDecoder</type></link> - which is added by default. This advertises to servers that the -client supports compression, and automatically decompresses compressed -responses. -</para> -<para> -Some other available features that you can add include: -</para> - -<variablelist> - <varlistentry> - <term><link linkend="SoupLogger"><type>SoupLogger</type></link></term> - <listitem><para> - A debugging aid, which logs all of libsoup's HTTP traffic - to <literal>stdout</literal> (or another place you specify). - </para></listitem> - </varlistentry> - <varlistentry> - <term> - <link linkend="SoupCookieJar"><type>SoupCookieJar</type></link>, - <link linkend="SoupCookieJarText"><type>SoupCookieJarText</type></link>, - and <link linkend="SoupCookieJarDB"><type>SoupCookieJarDB</type></link> - </term> - <listitem><para> - Support for HTTP cookies. <type>SoupCookieJar</type> - provides non-persistent cookie storage, while - <type>SoupCookieJarText</type> uses a text file to keep - track of cookies between sessions, and - <type>SoupCookieJarDB</type> uses a - <application>SQLite</application> database. - </para></listitem> - </varlistentry> - <varlistentry> - <term><link linkend="SoupContentSniffer"><type>SoupContentSniffer</type></link></term> - <listitem><para> - Uses the HTML5 sniffing rules to attempt to - determine the Content-Type of a response when the - server does not identify the Content-Type, or appears to - have provided an incorrect one. - </para></listitem> - </varlistentry> -</variablelist> - -<para> -Use the <link -linkend="soup-session-add-feature-by-type"><function>soup_session_add_feature_by_type()</function></link> function to -add features that don't require any configuration (such as <link -linkend="SoupContentSniffer"><type>SoupContentSniffer</type></link>), -and the <link -linkend="soup-session-add-feature"><function>soup_session_add_feature()</function></link>function to add features that must be -constructed first (such as <link -linkend="SoupLogger"><type>SoupLogger</type></link>). For example, an -application might do something like the following: -</para> - -<informalexample><programlisting><!CDATAsession = soup_session_new (); -soup_session_add_feature_by_type (session, SOUP_TYPE_CONTENT_SNIFFER); - -if (debug_level) { - SoupLogger *logger = soup_logger_new (debug_level); - soup_session_add_feature (session, SOUP_SESSION_FEATURE (logger)); - g_object_unref (logger); -}></programlisting></informalexample> - - <para>You can also remove features by calling <link -linkend="soup-session-remove-feature"><function>soup_session_remove_feature()</function></link> or -<link -linkend="soup-session-remove-feature-by-type"><function>soup_session_remove_feature_by_type()</function></link></para>. - - <para>See the <link linkend="additional-features">Additional Features</link> section for other features. - </para> - </sect2> - <sect2> - <title>Using a proxy</title> - <para>By default libsoup tries to respect the default proxy (as best as <link -linkend="g-proxy-resolver-get-default"><function>g_proxy_resolver_get_default()</function></link> knows), however you can set - a custom one or disable it outright using the <link linkend="SoupSession:proxy-resolver"><literal>SoupSession:proxy-resolver</literal></link> - property. For example:</para> -<informalexample><programlisting><!CDATA -{ - GProxyResolver *resolver = g_simple_proxy_resolver_new ("https://my-proxy-example.org", NULL); - SoupSession *session = soup_session_new_with_options ("proxy-resolver", resolver, NULL); - g_object_unref (resolver); -}> -</programlisting></informalexample> - </sect2> - <sect2> - <title>Using the SoupMessage API</title> - <para>The <type>SoupMessage</type> type contains all the state for a request and response pair that you send and recieve - to a server. For many more complex tasks you will have to create one of these and send it with the <function>soup_session_send()</function> - function. For example this sends a request with the <literal>HEAD</literal> method: - </para> -<informalexample><programlisting><!CDATA -{ - SoupSession *session = soup_session_new (); - SoupMessage *msg = soup_message_new (SOUP_METHOD_HEAD, "https://example.org"); - - // This allows you to also customize the request headers: - SoupMessageHeaders *request_headers = soup_message_get_request_headers (msg); - soup_message_headers_replace (request_headers, "Foo", "Bar"); - - GInputStream *in_stream = soup_session_send (session, msg, NULL, NULL); - if (in_stream) { - g_print ("Message was sent and recived a response of %u (%s)\n", - soup_message_get_status (msg), soup_message_get_reason_phrase (msg)); - // You can also inspect the response headers via soup_message_get_response_headers(); - g_object_unref (in_stream); - } - - g_object_unref (msg); - g_object_unref (session); -}> -</programlisting></informalexample> - </sect2> - <sect2> - <title>Handling authentication</title> -<informalexample><programlisting><!CDATA -static gboolean -authenticate_callback (SoupMessage *msg, SoupAuth *auth, gboolean retrying, gpointer user_data) -{ - if (retrying) { - // Maybe don't try again if our password failed - return FALSE; - } - - soup_auth_authenticate (auth, "username", "password"); - - // Returning TRUE means we have or *will* handle it. - // soup_auth_authenticate() or soup_auth_cancel() can be called later - // for example after showing a prompt to the user or loading the password - // from a keyring. - return TRUE; -} - -int main (int argc, char **argv) -{ - SoupSession *session = soup_session_new (); - SoupMessage *msg = soup_message_new (SOUP_METHOD_GET, "https://example.org"); - g_signal_connect (msg, "authenticate", G_CALLBACK (authenticate_callback), NULL); - GInputStream *in_stream = soup_session_send (session, msg, NULL, NULL); - - if (in_stream) { - g_object_unref (in_stream); - } - - return 0; -}> -</programlisting></informalexample> - </sect2> -</sect1> \ No newline at end of file
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/docs/reference/client-basic.xml
Deleted
@@ -1,183 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<?xml-model href="http://docbook.org/xml/5.1/rng/docbook.rng" schematypens="http://relaxng.org/ns/structure/1.0"?> -<?xml-model href="http://docbook.org/xml/5.1/sch/docbook.sch" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?> -<sect1 xmlns="http://docbook.org/ns/docbook" - xmlns:xlink="http://www.w3.org/1999/xlink" version="5.1"> - <title>Creating a Basic Client</title> - <para>libsoup provides a feature rich and complete HTTP client feature-set however in this guide - we will just be touching the basics. See … for a more in-depth example.</para> - <sect2> - <title>Creating a SoupSession</title> - <para>The core of libsoup is <type>SoupSession</type>; It contains all of the state of a - client including managing connections, queuing messages, handling authentication and - redirects, and much more. For now lets assume the default set of options and - features it provides are acceptable for most usage in which case you simply need to - create one with <link linkend="soup-session-new"><function>soup_session_new()</function></link>.</para> - </sect2> - <sect2> - <title>Downloading Into Memory</title> - <para>A common use case is that you simply want to request an HTTP resource and store it - for later use. There are a few methods of doing this but libsoup provides a high - level API to accomplish this:</para> -<informalexample><programlisting><!CDATA#include <libsoup/soup.h> - -int main (int argc, char **argv) -{ - SoupSession *session = soup_session_new (); - SoupMessageHeaders *response_headers; - const char *content_type; - SoupMessage *msg = soup_message_new (SOUP_METHOD_GET, "https://upload.wikimedia.org/wikipedia/commons/5/5f/BBB-Bunny.png"); - GError *error = NULL; - GBytes *bytes = soup_session_send_and_read ( - session, - msg, - NULL, // Pass a GCancellable here if you want to cancel a download - &error); - - if (error) { - g_printerr ("Failed to download: %s\n", error->message); - g_error_free (error); - g_object_unref (msg); - g_object_unref (session); - return 1; - } - - response_headers = soup_message_get_response_headers (msg); - content_type = soup_message_headers_get_content_type (response_headers); - - // content_type = "image/png" - // bytes contains the raw data that can be used elsewhere - g_print ("Downloaded %zu bytes of type %s\n", - g_bytes_get_size (bytes), content_type); - - g_bytes_unref (bytes); - g_object_unref (msg); - g_object_unref (session); - return 0; -}> -</programlisting></informalexample> - </sect2> - <sect2> - <title>Efficiently Streaming Data</title> - <para>While sometimes you want to store an entire download in memory it is often more - efficient to stream the data in chunks. In this example we will write the output to - a file.</para> - <para> -<informalexample><programlisting><!CDATA#include <libsoup/soup.h> - -int main (int argc, char **argv) -{ - SoupSession *session = soup_session_new (); - SoupMessageHeaders *response_headers; - const char *content_type; - goffset content_length; - SoupMessage *msg = soup_message_new (SOUP_METHOD_GET, "https://upload.wikimedia.org/wikipedia/commons/5/5f/BBB-Bunny.png"); - GError *error = NULL; - GInputStream *in_stream = soup_session_send ( - session, - msg, - NULL, - &error); - - if (error) { - g_printerr ("Failed to download: %s\n", error->message); - g_error_free (error); - g_object_unref (msg); - g_object_unref (session); - return 1; - } - - GFile *output_file = g_file_new_tmp ("BBB-Bunny-XXXXXX.png"); - GOutputStream *out_stream = g_file_create (output_file, - G_FILE_CREATE_NONE, NULL, &error); - - if (error) { - g_printerr ("Failed to create file \"%s\": %s\n", - g_file_peek_path (output_file), error->message); - g_error_free (error); - g_object_unref (output_file); - g_object_unref (in_stream); - g_object_unref (msg); - g_object_unref (session); - return 1; - } - - response_headers = soup_message_get_response_headers (msg); - content_type = soup_message_headers_get_content_type (response_headers); - content_length = soup_message_headers_get_content_length (response_headers); - - // content_type = "image/png" - g_print ("Downloading %zu bytes of type %s to %s\n", - content_length, content_type, - g_file_peek_path (output_file)); - - g_output_stream_splice (out_stream, in_stream, - G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, - NULL, &error); - - if (error) { - g_print ("Download failed: %s\n", error->message); - g_error_free (error); - } else { - g_print ("Download completed\n"); - } - - g_object_unref (output_file); - g_object_unref (in_stream); - g_object_unref (out_stream); - g_object_unref (msg); - g_object_unref (session); - return error ? 1 : 0; -}> -</programlisting></informalexample> - </para> - </sect2> - <sect2> - <title>Using Asynchronously</title> - <para>If you are using libsoup in an application with a <link linkend="GMainLoop"><type>GMainLoop</type></link> such as a GTK application - you do not want to block the mainloop by doing IO. To accomplish this libsoup provides an - asynchronous version of each of the APIs: <link linkend="soup-session-send-and-read-async"><function>soup_session_send_and_read_async()</function></link> - and <link linkend="soup-session-send-async"><function>soup_session_send_async()</function></link>. These behave the same as all async GLib - APIs, for example:</para> -<informalexample><programlisting><!CDATA#include <libsoup/soup.h> - -static void on_load_callback (GObject *source, GAsyncResult *result, gpointer user_data) -{ - GMainLoop *loop = user_data; - GError *error = NULL; - GBytes *bytes = soup_session_send_and_read_finish (SOUP_SESSION (source), result, &error); - - // Usage here is the same as before - if (error) { - g_error_free (error); - } else { - g_bytes_unref (bytes); - } - - g_main_loop_quit (loop); -} - -int main (int argc, char **argv) -{ - SoupSession *session = soup_session_new (); - GMainLoop *loop = g_main_loop_new (NULL, FALSE); - SoupMessage *msg = soup_message_new (SOUP_METHOD_GET, "https://upload.wikimedia.org/wikipedia/commons/5/5f/BBB-Bunny.png"); - - soup_session_send_and_read_async ( - session, - msg, - G_PRIORITY_DEFAULT, - NULL, - on_load_callback, - loop); - - g_main_loop_run (loop); - - g_main_loop_unref (loop); - g_object_unref (msg); - g_object_unref (session); - return 0; -}> -</programlisting></informalexample> - </sect2> -</sect1>
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/docs/reference/client-howto.xml
Deleted
@@ -1,535 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" - "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd"> -<refentry id="libsoup-client-howto"> -<refmeta> -<refentrytitle>libsoup Client Basics</refentrytitle> -<manvolnum>3</manvolnum> -<refmiscinfo>LIBSOUP Library</refmiscinfo> -</refmeta> - -<refnamediv> -<refname>libsoup Client Basics</refname><refpurpose>Client-side tutorial</refpurpose> -</refnamediv> - -<refsect2> -<para> -This section explains how to use <application>libsoup</application> as -an HTTP client using several new APIs introduced in version 2.42. If -you want to be compatible with older versions of -<application>libsoup</application>, consult the documentation for that -version. -</para> -</refsect2> - -<refsect2> -<title>Creating a <type>SoupSession</type></title> - -<para> -The first step in using the client API is to create a <link -linkend="SoupSession"><type>SoupSession</type></link>. The session object -encapsulates all of the state that <application>libsoup</application> -is keeping on behalf of your program; cached HTTP connections, -authentication information, etc. -</para> - -<para> -When you create the session with <link -linkend="soup-session-new-with-options"><function>soup_session_new_with_options</function></link>, -you can specify various additional options: -</para> - -<variablelist> - <varlistentry> - <term><link linkend="SoupSession:max-conns"><literal>"max-conns"</literal></link></term> - <listitem><para> - Allows you to set the maximum total number of connections - the session will have open at one time. (Once it reaches - this limit, it will either close idle connections, or - wait for existing connections to free up before starting - new requests.) The default value is 10. - </para></listitem> - </varlistentry> - <varlistentry> - <term><link linkend="SoupSession:max-conns-per-host"><literal>"max-conns-per-host"</literal></link></term> - <listitem><para> - Allows you to set the maximum total number of connections - the session will have open <emphasis>to a single - host</emphasis> at one time. The default value is 2. - </para></listitem> - </varlistentry> - <varlistentry> - <term><link linkend="SoupSession:user-agent"><literal>"user-agent"</literal></link></term> - <listitem><para> - Allows you to set a User-Agent string that will be sent - on all outgoing requests. - </para></listitem> - </varlistentry> - <varlistentry> - <term><link linkend="SoupSession:accept-language"><literal>"accept-language"</literal></link> - and <link linkend="SoupSession:accept-language-auto"><literal>"accept-language-auto"</literal></link></term> - <listitem><para> - Allow you to set an Accept-Language header on all outgoing - requests. <literal>"accept-language"</literal> - takes a list of language tags to use, while - <literal>"accept-language-auto"</literal> - automatically generates the list from the user's locale - settings. - </para></listitem> - </varlistentry> - <varlistentry> - <term><link linkend="SoupSession:proxy-resolver"><literal>"proxy-resolver"</literal></link></term> - <listitem> - <para> - <link linkend="SoupSession:proxy-resolver"><literal>"proxy-resolver"</literal></link> - specifies a <link - linkend="GProxyResolver"><type>GProxyResolver</type></link> - to use to determine the HTTP proxies to use. By default, - this is set to the resolver returned by <link - linkend="g-proxy-resolver-get-default"><function>g_proxy_resolver_get_default</function></link>, - so you do not need to set it yourself. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term><link linkend="SoupSession:add-feature"><literal>"add-feature"</literal></link> and <link linkend="SOUP-SESSION-ADD-FEATURE-BY-TYPE:CAPS"><literal>"add-feature-by-type"</literal></link></term> - <listitem><para> - These allow you to specify <link - linkend="SoupSessionFeature"><type>SoupSessionFeature</type></link>s - (discussed <link linkend="session-features">below</link>) - to add at construct-time. - </para></listitem> - </varlistentry> -</variablelist> - -<para> -Other properties are also available; see the <link -linkend="SoupSession"><type>SoupSession</type></link> documentation for -more details. -</para> - -<para> -If you don't need to specify any options, you can just use <link -linkend="soup-session-new"><function>soup_session_new</function></link>, -which takes no arguments. -</para> - -</refsect2> - -<refsect2 id="session-features"> -<title>Session features</title> - -<para> -Additional session functionality is provided as <link -linkend="SoupSessionFeature"><type>SoupSessionFeature</type></link>s, -which can be added to a session, via the <link -linkend="SoupSession:add-feature"><literal>"add-feature"</literal></link> -and <link -linkend="SoupSession:add-feature-by-type"><literal>"add-feature-by-type"</literal></link> -options at session-construction-time, or afterward via the <link -linkend="soup-session-add-feature"><function>soup_session_add_feature</function></link> -and <link -linkend="soup-session-add-feature-by-type"><function>soup_session_add_feature_by_type</function></link> -functions. -</para> - -<para> -A <link -linkend="SoupContentDecoder"><type>SoupContentDecoder</type></link> is -added for you automatically. This advertises to servers that the -client supports compression, and automatically decompresses compressed -responses. -</para> - -<para> -Some other available features that you can add include: -</para> - -<variablelist> - <varlistentry> - <term><link linkend="SoupLogger"><type>SoupLogger</type></link></term> - <listitem><para> - A debugging aid, which logs all of libsoup's HTTP traffic - to <literal>stdout</literal> (or another place you specify). - </para></listitem> - </varlistentry> - <varlistentry> - <term> - <link linkend="SoupCookieJar"><type>SoupCookieJar</type></link>, - <link linkend="SoupCookieJarText"><type>SoupCookieJarText</type></link>, - and <link linkend="SoupCookieJarDB"><type>SoupCookieJarDB</type></link> - </term> - <listitem><para> - Support for HTTP cookies. <type>SoupCookieJar</type> - provides non-persistent cookie storage, while - <type>SoupCookieJarText</type> uses a text file to keep - track of cookies between sessions, and - <type>SoupCookieJarDB</type> uses a - <application>SQLite</application> database. - </para></listitem> - </varlistentry> - <varlistentry> - <term><link linkend="SoupContentSniffer"><type>SoupContentSniffer</type></link></term> - <listitem><para> - Uses the HTML5 sniffing rules to attempt to - determine the Content-Type of a response when the - server does not identify the Content-Type, or appears to - have provided an incorrect one. - </para></listitem> - </varlistentry> -</variablelist> - -<para> -Use the "add_feature_by_type" property/function to add features that -don't require any configuration (such as <link -linkend="SoupContentSniffer"><type>SoupContentSniffer</type></link>), -and the "add_feature" property/function to add features that must be -constructed first (such as <link -linkend="SoupLogger"><type>SoupLogger</type></link>). For example, an -application might do something like the following: -</para> - -<informalexample><programlisting> - session = soup_session_new_with_options ( - "add-feature-by-type", SOUP_TYPE_CONTENT_SNIFFER, - NULL); - - if (debug_level) { - SoupLogger *logger; -
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/docs/reference/client-tls.xml
Deleted
@@ -1,102 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<?xml-model href="http://docbook.org/xml/5.1/rng/docbook.rng" schematypens="http://relaxng.org/ns/structure/1.0"?> -<?xml-model href="http://docbook.org/xml/5.1/sch/docbook.sch" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?> -<sect1 xmlns="http://docbook.org/ns/docbook" - xmlns:xlink="http://www.w3.org/1999/xlink" version="5.1"> - <title>Everything TLS Related</title> - <para>libsoup comes with TLS support provided by glib-networking. This has multiple backends - including gnutls (default on all platforms), SChannel on Windows, or OpenSSL.</para> - <sect2> - <title>Accepting Invalid or Pinned Certificates</title> - <para>This makes use of the <literal>SoupMessage::accept-certificate</literal> signal.</para> -<informalexample><programlisting><!CDATA -static gboolean -accept_certificate_callback (SoupMessage *msg, GTlsCertificate *certificate, - GTlsCertificateFlags tls_errors, gpointer user_data) -{ - // Here you can inspect @certificate or compare it against a trusted one - // and you can see what is considered invalid by @tls_errors. - // Returning TRUE trusts it anyway. - return TRUE; -} - -int main (int argc, char **argv) -{ - SoupSession *session = soup_session_new (); - SoupMessage *msg = soup_message_new (SOUP_METHOD_GET, "https://example.org"); - g_signal_connect (msg, "accept-certificate", G_CALLBACK (accept_certificate_callback), NULL); - GInputStream *in_stream = soup_session_send (session, msg, NULL, NULL); - - if (in_stream) { - g_object_unref (in_stream); - } - - return 0; -}> -</programlisting></informalexample> - </sect2> - <sect2> - <title>Setting a Custom CA</title> -<informalexample><programlisting><!CDATA -{ - GError *error = NULL; - // NOTE: This is blocking IO - GTlsDatabase *tls_db = g_tls_file_database_new ("/foo/ca.pem", &error); - - if (error) { - g_printerr ("Failed to load certificates: %s\n", error->message); - g_error_free (error); - return; - } - - SoupSession *session = soup_session_new_with_options ("tls-database", tls_db, NULL); - g_object_unref (tls_db); -}> -</programlisting></informalexample> - </sect2> - <sect2> - <title>Using Client Certificates</title> -<informalexample><programlisting><!CDATA -static gboolean -on_request_certificate (SoupMessage *msg, GTlsClientConnection *conn, gpointer user_data) -{ - GTlsCertificate *client_cert = user_data; - - /* We immediately set this however you can set this later in an async function. */ - soup_message_set_tls_client_certificate (msg, client_cert); - - return TRUE; /* We handled the request */ -} - -int main (int argc, char **argv) -{ - GError *error = NULL; - GTlsCertificate *client_cert = g_tls_certificate_new_from_file ("/foo/cert.pem", &error); - - if (error) { - g_printerr ("Failed to load certificate: %s\n", error->message); - g_error_free (error); - return 1; - } - - SoupSession *session = soup_session_new (); - SoupMessage *msg = soup_message_new ("GET", "https://example.org"); - - /* We can set the certificate ahead of time if we already have one */ - // soup_message_set_tls_client_certificate (msg, client_cert) - - /* However we can also dynamically request one which is useful in - * applications that show a graphical prompt for example. */ - g_signal_connect (msg, "request-certificate", - G_CALLBACK (on_request_certificate), client_cert); - - // Send the message... - - g_object_unref (msg); - g_object_unref (session); - g_object_unref (client_cert); - return 0; -}> -</programlisting></informalexample> - </sect2> -</sect1> \ No newline at end of file
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/docs/reference/libsoup-3.0-docs.xml
Deleted
@@ -1,118 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"> -<book xmlns="http://docbook.org/ns/docbook" id="index" - xmlns:xi="http://www.w3.org/2003/XInclude"> - <bookinfo> - <title>libsoup Reference Manual</title> - <releaseinfo> - This documentation is for libsoup 3.0. - You can find older versions online at <ulink role="online-location" url="https://libsoup.org/libsoup-2.4/index.html">https://libsoup.org/libsoup-2.4/</ulink>. - </releaseinfo> - </bookinfo> - - <part> - <title>Overview</title> - <chapter> - <title>Tutorial</title> - <xi:include href="build-howto.xml"/> - <xi:include href="client-basic.xml"/> - <xi:include href="client-advanced.xml"/> - <xi:include href="client-tls.xml"/> - <xi:include href="server-howto.xml"/> - </chapter> - - <xi:include href="migrating-from-libsoup-2.xml"/> - </part> - - <part> - <title>API Reference</title> - <chapter> - <title>Core HTTP API</title> - <xi:include href="xml/soup-cookie.xml"/> - <xi:include href="xml/soup-message.xml"/> - <xi:include href="xml/soup-message-headers.xml"/> - <xi:include href="xml/soup-headers.xml"/> - <xi:include href="xml/soup-method.xml"/> - <xi:include href="xml/soup-multipart.xml"/> - <xi:include href="xml/soup-multipart-input-stream.xml"/> - <xi:include href="xml/soup-session.xml"/> - <xi:include href="xml/soup-status.xml"/> - </chapter> - - <chapter> - <title>HTTP Server</title> - <xi:include href="xml/soup-server.xml"/> - <xi:include href="xml/soup-server-message.xml"/> - <xi:include href="xml/soup-message-body.xml"/> - </chapter> - - <chapter id="additional-features"> - <title>Additional Features</title> - <xi:include href="xml/soup-session-feature.xml"/> - <xi:include href="xml/soup-content-decoder.xml"/> - <xi:include href="xml/soup-content-sniffer.xml"/> - <xi:include href="xml/soup-logger.xml"/> - <section> - <title>Authentication</title> - <xi:include href="xml/soup-auth-manager.xml"/> - <xi:include href="xml/soup-auth.xml"/> - <xi:include href="xml/soup-auth-domain.xml"/> - <xi:include href="xml/soup-auth-domain-basic.xml"/> - <xi:include href="xml/soup-auth-domain-digest.xml"/> - </section> - <section> - <title>Caching</title> - <xi:include href="xml/soup-cache.xml"/> - </section> - <section> - <title>Cookie Storage Support</title> - <xi:include href="xml/soup-cookie-jar.xml"/> - <xi:include href="xml/soup-cookie-jar-text.xml"/> - <xi:include href="xml/soup-cookie-jar-db.xml"/> - </section> - <section> - <title>HSTS Support</title> - <xi:include href="xml/soup-hsts-enforcer.xml"/> - <xi:include href="xml/soup-hsts-enforcer-db.xml"/> - <xi:include href="xml/soup-hsts-policy.xml"/> - </section> - <section> - <title>Metrics</title> - <xi:include href="xml/soup-message-metrics.xml"/> - </section> - </chapter> - - <chapter> - <title>Web Services APIs</title> - <xi:include href="xml/soup-form.xml"/> - <section> - <title>WebSocket Support</title> - <xi:include href="xml/soup-websocket.xml"/> - <xi:include href="xml/soup-websocket-extension.xml"/> - </section> - </chapter> - - <chapter> - <title>Utility API</title> - <xi:include href="xml/soup-date-utils.xml"/> - <xi:include href="xml/soup-tld.xml"/> - <xi:include href="xml/soup-uri-utils.xml"/> - <xi:include href="xml/soup-version.xml"/> - </chapter> - </part> - - <index id="api-index-full"> - <title>Index of all symbols</title> - <xi:include href="xml/api-index-full.xml"></xi:include> - </index> - <index id="api-index-deprecated" role="deprecated"> - <title>Index of deprecated symbols</title> - <xi:include href="xml/api-index-deprecated.xml"></xi:include> - </index> - - <xi:include href="xml/annotation-glossary.xml"> - <xi:fallback /> - </xi:include> - - -</book>
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/docs/reference/libsoup-3.0-sections.txt
Deleted
@@ -1,1033 +0,0 @@ -<INCLUDE>libsoup/soup.h</INCLUDE> -<SECTION> -<FILE>soup-message</FILE> -<TITLE>SoupMessage</TITLE> -SoupMessage -<SUBSECTION> -soup_message_new -soup_message_new_from_uri -soup_message_new_from_encoded_form -soup_message_new_from_multipart -soup_message_set_request_body -soup_message_set_request_body_from_bytes -<SUBSECTION> -soup_message_new_options_ping -soup_message_get_is_options_ping -soup_message_set_is_options_ping -<SUBSECTION> -SoupHTTPVersion -soup_message_get_http_version -soup_message_get_uri -soup_message_set_uri -soup_message_get_method -soup_message_set_method -soup_message_get_status -soup_message_get_reason_phrase -<SUBSECTION> -soup_message_get_request_headers -soup_message_get_response_headers -<SUBSECTION> -soup_message_is_keepalive -soup_message_get_connection_id -soup_message_get_remote_address -soup_message_get_tls_peer_certificate -soup_message_get_tls_peer_certificate_errors -soup_message_get_tls_protocol_version -soup_message_get_tls_ciphersuite_name -soup_message_set_tls_client_certificate -soup_message_tls_client_certificate_password_request_complete -<SUBSECTION> -soup_message_set_first_party -soup_message_get_first_party -<SUBSECTION> -soup_message_add_header_handler -soup_message_add_status_code_handler -<SUBSECTION> -SoupMessageFlags -soup_message_set_flags -soup_message_get_flags -soup_message_add_flags -soup_message_remove_flags -soup_message_query_flags -<SUBSECTION> -soup_message_disable_feature -soup_message_is_feature_disabled -<SUBSECTION> -SoupMessagePriority -soup_message_get_priority -soup_message_set_priority -<SUBSECTION> -soup_message_get_site_for_cookies -soup_message_set_site_for_cookies -soup_message_get_is_top_level_navigation -soup_message_set_is_top_level_navigation -<SUBSECTION> -soup_message_get_metrics -<SUBSECTION Standard> -SOUP_MESSAGE -SOUP_IS_MESSAGE -SOUP_TYPE_MESSAGE -soup_message_get_type -SOUP_MESSAGE_CLASS -SOUP_IS_MESSAGE_CLASS -SOUP_MESSAGE_GET_CLASS -SoupMessageClass -<SUBSECTION Private> -soup_message_wrote_headers -soup_message_wrote_body_data -soup_message_wrote_body -soup_message_got_informational -soup_message_got_headers -soup_message_content_sniffed -soup_message_got_body -soup_message_finished -soup_message_restarted -soup_message_starting -</SECTION> - -<SECTION> -<FILE>soup-method</FILE> -<TITLE>SoupMethod</TITLE> -SOUP_METHOD_OPTIONS -SOUP_METHOD_GET -SOUP_METHOD_HEAD -SOUP_METHOD_PUT -SOUP_METHOD_POST -SOUP_METHOD_DELETE -SOUP_METHOD_TRACE -SOUP_METHOD_CONNECT -<SUBSECTION> -SOUP_METHOD_PROPFIND -SOUP_METHOD_PROPPATCH -SOUP_METHOD_MKCOL -SOUP_METHOD_COPY -SOUP_METHOD_MOVE -SOUP_METHOD_LOCK -SOUP_METHOD_UNLOCK -</SECTION> - -<SECTION> -<FILE>soup-message-headers</FILE> -<TITLE>SoupMessageHeaders</TITLE> -SoupMessageHeaders -SoupMessageHeadersType -soup_message_headers_new -soup_message_headers_ref -soup_message_headers_unref -<SUBSECTION> -soup_message_headers_append -soup_message_headers_replace -soup_message_headers_remove -soup_message_headers_clear -soup_message_headers_clean_connection_headers -soup_message_headers_get_one -soup_message_headers_get_list -soup_message_headers_get_headers_type -<SUBSECTION> -soup_message_headers_header_contains -soup_message_headers_header_equals -<SUBSECTION> -SoupMessageHeadersForeachFunc -soup_message_headers_foreach -<SUBSECTION> -SoupMessageHeadersIter -soup_message_headers_iter_init -soup_message_headers_iter_next -<SUBSECTION> -SoupEncoding -soup_message_headers_get_encoding -soup_message_headers_set_encoding -soup_message_headers_get_content_length -soup_message_headers_set_content_length -<SUBSECTION> -SoupExpectation -soup_message_headers_get_expectations -soup_message_headers_set_expectations -<SUBSECTION> -soup_message_headers_get_content_type -soup_message_headers_set_content_type -<SUBSECTION> -soup_message_headers_get_content_disposition -soup_message_headers_set_content_disposition -<SUBSECTION> -SoupRange -soup_message_headers_get_ranges -soup_message_headers_set_ranges -soup_message_headers_set_range -soup_message_headers_free_ranges -soup_message_headers_get_content_range -soup_message_headers_set_content_range -<SUBSECTION Standard> -SOUP_TYPE_MESSAGE_HEADERS -soup_message_headers_get_type -</SECTION> - -<SECTION> -<FILE>soup-headers</FILE> -soup_headers_parse_request -soup_headers_parse_response -soup_headers_parse_status_line -soup_headers_parse -<SUBSECTION> -soup_header_parse_list -soup_header_parse_quality_list -soup_header_free_list -soup_header_contains -soup_header_parse_param_list -soup_header_parse_semi_param_list -soup_header_parse_param_list_strict -soup_header_parse_semi_param_list_strict -soup_header_free_param_list -soup_header_g_string_append_param -soup_header_g_string_append_param_quoted -</SECTION> - -<SECTION> -<FILE>soup-message-body</FILE> -<TITLE>SoupMessageBody</TITLE> -SoupMemoryUse -<SUBSECTION> -SoupMessageBody -soup_message_body_new -soup_message_body_ref -soup_message_body_unref -<SUBSECTION> -soup_message_body_set_accumulate -soup_message_body_get_accumulate -<SUBSECTION> -soup_message_body_append -soup_message_body_append_bytes
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/docs/reference/migrating-from-libsoup-2.xml
Deleted
@@ -1,192 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<?xml-model href="http://docbook.org/xml/5.1/rng/docbook.rng" schematypens="http://relaxng.org/ns/structure/1.0"?> -<?xml-model href="http://docbook.org/xml/5.1/sch/docbook.sch" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?> -<chapter xmlns="http://docbook.org/ns/docbook" - xmlns:xlink="http://www.w3.org/1999/xlink" version="5.1"> - <title>Migrating from libsoup 2</title> - <sect2> - <title>Removed APIs</title> - <para>This is a list of APIs that have been removed:<itemizedlist> - <listitem> - <para>XML-RPC support</para> - </listitem> - <listitem> - <para>Handling of <literal>file://</literal> and <literal>data://</literal> - URIs</para> - <para>You should use <link -linkend="GFile"><type>GFile</type></link> for the former and <link -linkend="soup-uri-decode-data-uri"><function>soup_uri_decode_data_uri()</function></link> for the - latter.</para> - </listitem> - <listitem> - <para>Define aliases for property names</para> - <para>You must use the string name of properties directly which works in libsoup - 2 already.</para> - </listitem> - <listitem> - <para><literal>SoupSession:add-feature</literal> and <literal>SoupSession:add-feature-by-type</literal></para> - <para>You must call <link linkend="soup-session-add-feature"><function>soup_session_add_feature()</function></link> and - <link linkend="soup-session-add-feature-by-type"><function>soup_session_add_feature_by_type()</function></link> directly.</para> - </listitem> - <listitem> - <para><type>SoupRequest</type></para> - <para>You should use <link linkend="soup-session-send"><function>soup_session_send()</function></link> or - <link linkend="soup-session-send-async"><function>soup_session_send_async()</function></link> methods.</para> - </listitem> - <listitem> - <para><type>SoupAddress</type> has been replaced with <link linkend="GInetAddress"><type>GInetAddress</type></link> - and <link linkend="GNetworkAddress"><type>GNetworkAddress</type></link></para> - </listitem> - <listitem> - <para><type>SoupSocket</type> has been removed</para> - </listitem> - <listitem> - <para><type>SoupProxyResolverDefault</type> is replaced by - <link linkend="g-proxy-resolver-get-default"><function>g_proxy_resolver_get_default()</function></link></para> - </listitem> - <listitem> - <para><type>SoupBuffer</type> has been replaced by <link linkend="GBytes"><type>GBytes</type></link> and <link linkend="GByteArray"><type>GByteArray</type></link></para> - </listitem> - <listitem> - <para><type>SoupDate</type> has been replaced by <link linkend="GDateTime"><type>GDateTime</type></link></para> - </listitem> - <listitem> - <para><literal>SoupSession:ssl-strict</literal> has been removed in favor of using the <link linkend="SoupMessage-accept-certificate"><literal>SoupMessage:accept-certificate</literal></link> signal.</para> - </listitem> - <listitem> - <para><literal>soup_session_cancel_message()</literal> has been removed</para> - <para>Instead you pass a <link linkend="GCancellable"><type>GCancellable</type></link> to APIs and call <link linkend="g_cancellable_cancel"><function>g_cancellable_cancel()</function></link>.</para> - </listitem> - </itemizedlist></para> - </sect2> - <sect2> - <title>Moved authenticate signal</title> - <para>The <literal>SoupSession::authenticate</literal> signal has been replaced by - <link linkend="SoupMessage-authenticate"><literal>SoupMessage::authenticate</literal></link>. It now allows returning <literal>TRUE</literal> to signifiy - if you will handle authentication which allows for asynchronous handling.</para> - </sect2> - <sect2> - <title>Structs are private</title> - <para>You can no longer directly access various structs such as SoupMessage. These are now - accessed by getters and setters. See below for direct conversions:<informaltable> - <tgroup cols="2"> - <colspec colname="c1" colnum="1" colwidth="1*"/> - <colspec colname="c2" colnum="2" colwidth="1*"/> - <thead> - <row> - <entry>Struct field</entry> - <entry>Getter/Setter function</entry> - </row> - </thead> - <tbody> - <row> - <entry>SoupMessage.method</entry> - <entry><link linkend="soup-message-get-method"><function>soup_message_get_method()</function></link></entry> - </row> - <row> - <entry>SoupMessage.status_code</entry> - <entry><link linkend="soup-message-get-status"><function>soup_message_get_status()</function></link></entry> - </row> - <row> - <entry>SoupMessage.reason_phrase</entry> - <entry><link linkend="soup-message-get-reason-phrase"><function>soup_message_get_reason_phrase()</function></link></entry> - </row> - <row> - <entry>SoupMessage.uri</entry> - <entry><link linkend="soup-message-get-uri"><function>soup_message_get_uri()</function></link>, <link linkend="soup-message-set-uri"><function>soup_message_set_uri()</function></link></entry> - </row> - <row> - <entry>SoupMessage.request_headers</entry> - <entry><link linkend="soup-message-get-request-headers"><function>soup_message_get_request_headers()</function></link></entry> - </row> - <row> - <entry>SoupMessage.response_headers</entry> - <entry><link linkend="soup-message-get-response-headers"><function>soup_message_get_response_headers()</function></link></entry> - </row> - <row> - <entry>SoupMessage.request_body</entry> - <entry><link linkend="soup-message-set-request-body"><function>soup_message_set_request_body()</function></link>, - <link linkend="soup-message-set-request-body-from-bytes"><function>soup_message_set_request_body_from_bytes()</function></link></entry> - </row> - <row> - <entry>SoupMessage.response_body</entry> - <entry>See <link linkend="io-stream-based">section on IO</link> </entry> - </row> - </tbody> - </tgroup> - </informaltable></para> - <para>Similar struct changes exist for <link linkend="SoupCookie"><type>SoupCookie</type></link> but have very straightforward - replacements.</para> - </sect2> - <sect2> - <title>URI type changed</title> - <para>The <type>SoupURI</type> type has been replaced with the <link linkend="GUri"><type>GUri</type></link> type which has some - implications.</para> - <para>Creating a <link linkend="GUri"><type>GUri</type></link> is generally as simple as <code>g_uri_parse (uri, - SOUP_HTTP_URI_FLAGS, NULL)</code>. You may want to add - <literal>G_URI_FLAGS_PARSE_RELAXED</literal> to accept input that used to be - considered valid.</para> - <para>Note that unlike <type>SoupURI</type> <link linkend="GUri"><type>GUri</type></link> is an immutable type so you cannot change the contents - of one after it has been constructed. We provide <link linkend="soup_copy_uri"><function>soup_copy_uri()</function></link> to aid in modifying them.</para> - <para>The equivalent behavior to <code>soup_uri_to_string (uri, FALSE)</code> is - <code>g_uri_to_string_partial (uri, G_URI_HIDE_PASSWORD)</code>.</para> - <para>Since GUri does not provide any function to check for equality - <link linkend="soup_uri_equal"><function>soup_uri_equal()</function></link> still exists.</para> - <para>Sending a <literal>OPTIONS</literal> message with a path of <literal>*</literal> is no - longer a valid URI and has been replaced with SoupMessage:options-ping.</para> - </sect2> - <sect2> - <title>Status codes no longer used for internal errors</title> - <para>Previously <link linkend="SoupStatus"><type>SoupStatus</type></link> was used to hold libsoup errors - (<code>SOUP_STATUS_IS_TRANSPORT_ERROR()</code>). Now all of these errors are - propagated up through the normal <link linkend="GError"><type>GError</type></link> method on the various APIs to send messages. - Here is a mapping chart between the status codes and new errors:<informaltable> - <tgroup cols="2"> - <colspec colname="c1" colnum="1" colwidth="1*"/> - <colspec colname="newCol4" colnum="2" colwidth="1*"/> - <thead> - <row> - <entry>Old Status Codes</entry> - <entry>New GError</entry> - </row> - </thead> - <tbody> - <row> - <entry><code>SOUP_STATUS_CANCELLED</code></entry> - <entry><link linkend="G-IO-ERROR-CANCELLED:CAPS"><code>G_IO_ERROR_CANCELLED</code></link></entry> - </row> - <row> - <entry><code>SOUP_STATUS_MALFORMED</code></entry> - <entry><link linkend="SOUP-SESSION-ERROR-PARSING:CAPS"><code>SOUP_SESSION_ERROR_PARSING</code></link>, <link linkend="SOUP-SESSION-ERROR-ENCODING:CAPS"><code>SOUP_SESSION_ERROR_ENCODING</code></link></entry> - </row> - <row> - <entry><code>SOUP_STATUS_TOO_MANY_REDIRECTS</code></entry> - <entry><link linkend="SOUP-SESSION-ERROR-TOO-MANY-REDIRECTS:CAPS"><code>SOUP_SESSION_ERROR_TOO_MANY_REDIRECTS</code></link></entry> - </row> - </tbody> - </tgroup> - </informaltable></para> - </sect2> - <sect2 id="io-stream-based"> - <title>All IO is now GIOStream-based</title> - <para>Previously there were ways to allow libsoup to read data into buffers and for you to - read from those buffers such as <literal>SoupMessage:response-body</literal>, - <literal>SoupMessage:response-body-data</literal>, and <literal>SoupMessage::got-chunk</literal>.</para> - <para>libsoup no longer stores a buffer of data for you to read from and instead it returns - a <link linkend="GInputStream"><type>GInputStream</type></link> which you read from using normal GIO APIs.</para> - <para>If you want to simply request a buffer and nothing more you can use the - <link linkend="soup_session_send_and_read"><function>soup_session_send_and_read()</function></link> or - <link linkend="soup_session_send_and_read_async"><function>soup_session_send_and_read_async()</function></link> APIs.</para> - <para>This also applies to writing data where you can set a <link linkend="GInputStream"><type>GInputStream</type></link> using - <link linkend="soup_message_set_request_body"><function>soup_message_set_request_body()</function></link> or use the convenience API - <link linkend="soup_message_set_request_body_from_bytes"><function>soup_message_set_request_body_from_bytes()</function></link> to use a GBytes - buffer.</para> - </sect2> - <sect2 id="threading"> - <title>Clarification on thread-safety</title> - <para>In libsoup 2 there was an attempt at making various APIs of the library thread-safe. However this was never well tested, maintained, or documented.</para> - <para>In libsoup 3 it now behaves in line with other GObject libraries. Once you create a <link linkend="SoupSession"><type>SoupSession</type></link> all usage of that - session must happen on the same thread. You may create seperate sessions per thread but in most use-cases you should be using the async APIs which handle non-blocking IO for you.</para> - </sect2> -</chapter> -
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/docs/reference/server-howto.xml
Deleted
@@ -1,380 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" - "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd"> -<refentry id="libsoup-server-howto"> -<refmeta> -<refentrytitle>Server Basics</refentrytitle> -<manvolnum>3</manvolnum> -<refmiscinfo>LIBSOUP Library</refmiscinfo> -</refmeta> - -<refnamediv> -<refname>libsoup Server Basics</refname> -</refnamediv> - -<refsect2> -<title>Creating a SoupServer</title> - -<para> -As with the client API, there is a single object that will encapsulate -most of your interactions with libsoup. In this case, <link -linkend="SoupServer"><type>SoupServer</type></link>. -</para> - -<para> -You create the server with <link -linkend="soup-server-new"><function>soup_server_new</function></link>, -and as with the <type>SoupSession</type> constructor, you can specify -a few additional options: -</para> - -<variablelist> - <varlistentry> - <term><link linkend="SoupServer:tls-certificate"><literal>"tls-certificate"</literal></link></term> - <listitem><para> - A <link - linkend="GTlsCertificate"><type>GTlsCertificate</type></link> - (containing a private key) that will be used when handling - HTTPS requests on the server. - </para></listitem> - </varlistentry> - <varlistentry> - <term><link linkend="SoupServer:raw-paths"><literal>"raw-paths"</literal></link></term> - <listitem><para> - Set this to <literal>TRUE</literal> if you don't want - <application>libsoup</application> to decode %-encoding - in the Request-URI. (Eg, because you need to treat - <literal>"/foo/bar"</literal> and - <literal>"/foo%2Fbar"</literal> as different paths. - </para></listitem> - </varlistentry> - <varlistentry> - <term><link linkend="SoupServer:server-header"><literal>"server-header"</literal></link></term> - <listitem><para> - Allows you to set a Server header string that will be sent - on all responses. - </para></listitem> - </varlistentry> -</variablelist> - -</refsect2> - -<refsect2> -<title>Adding Listening Sockets</title> - -<para> - To tell the server where to listen, call <link - linkend="soup-server-listen"><function>soup_server_listen</function></link> - (to listen on a specific <link - linkend="GSocketAddress"><type>GSocketAddress</type></link>), <link - linkend="soup-server-listen-all"><function>soup_server_listen_all</function></link> - (to listen on a given port on all network interfaces), or <link - linkend="soup-server-listen-local"><function>soup_server_listen_local</function></link> - (to listen to a given port on the loopback interface only). You can - call any of these functions multiple times, to set up multiple - listening sockets. -</para> - -<para> - To set up an HTTPS server, you must first either set the <link - linkend="SoupServer:tls-certificate"><literal>SoupServer:tls-certificate</literal></link> - property, or else call <link - linkend="soup-server-set-ssl-cert-file"><function>soup_server_set_ssl_cert_file</function></link>. - After that you can pass the <link - linkend="SOUP-SERVER-LISTEN-HTTPS:CAPS"><literal>SOUP_SERVER_LISTEN_HTTPS</literal></link> - option to <link - linkend="soup-server-listen"><function>soup_server_listen</function></link>, - etc. -</para> - -<para> - By default, servers listen for both IPv4 and IPv6 connections; if - you don't want this, use the <link - linkend="SOUP-SERVER-LISTEN-IPV4-ONLY:CAPS"><literal>SOUP_SERVER_LISTEN_IPV4_ONLY</literal></link> - or <link - linkend="SOUP-SERVER-LISTEN-IPV6-ONLY:CAPS"><literal>SOUP_SERVER_LISTEN_IPV6_ONLY</literal></link> - options. -</para> - -<para> - The server runs asynchronously, in the thread-default - <link linkend="GMainContext"><type>GMainContext</type></link> of the - thread in which the "listen" calls were made. -</para> -</refsect2> - -<refsect2> -<title>Adding Handlers</title> - -<para> -By default, <link linkend="SoupServer"><type>SoupServer</type></link> -returns "404 Not Found" in response to all requests (except ones that -it can't parse, which get "400 Bad Request"). To override this -behavior, call <link -linkend="soup-server-add-handler"><function>soup_server_add_handler</function></link> -to set a callback to handle certain URI paths. -</para> - -<informalexample><programlisting> - soup_server_add_handler (server, "/foo", server_callback, - data, destroy_notify); -</programlisting></informalexample> - -<para> -The <literal>"/foo"</literal> indicates the base path for this -handler. When a request comes in, if there is a handler registered for -exactly the path in the request's <literal>Request-URI</literal>, then -that handler will be called. Otherwise -<application>libsoup</application> will strip path components one by -one until it finds a matching handler. So for example, a request of -the form -"<literal>GET /foo/bar/baz.html?a=1&b=2 HTTP/1.1</literal>" -would look for handlers for "<literal>/foo/bar/baz.html</literal>", -"<literal>/foo/bar</literal>", and "<literal>/foo</literal>". If a -handler has been registered with a <literal>NULL</literal> base path, -then it is used as the default handler for any request that doesn't -match any other handler. -</para> - -</refsect2> - -<refsect2> -<title>Responding to Requests</title> - -<para> -A handler callback looks something like this: -</para> - -<informalexample><programlisting> -static void -server_callback (SoupServer *server, - SoupServerMessage *msg, - const char *path, - GHashTable *query, - gpointer user_data) -{ - ... -} -</programlisting></informalexample> - -<para> -<literal>msg</literal> is the request that has been received and -<literal>user_data</literal> is the data that was passed to <link -linkend="soup-server-add-handler"><function>soup_server_add_handler</function></link>. -<literal>path</literal> is the path (from <literal>msg</literal>'s -URI), and <literal>query</literal> contains the result of parsing the -URI query field. (It is <literal>NULL</literal> if there was no -query.) -</para> - -<para> -By default, <application>libsoup</application> assumes that you have -completely finished processing the message when you return from the -callback, and that it can therefore begin sending the response. If you -are not ready to send a response immediately (eg, you have to contact -another server, or wait for data from a database), you must call <link -linkend="soup-server-pause-message"><function>soup_server_pause_message</function></link> -on the message before returning from the callback. This will delay -sending a response until you call <link -linkend="soup-server-unpause-message"><function>soup_server_unpause_message</function></link>. -(You must also connect to the <link -linkend="SoupServerMessage-finished">finished</link> signal on the message -in this case, so that you can break off processing if the client -unexpectedly disconnects before you start sending the data.) -</para> - -<para> -To set the response status, call <link -linkend="soup-server-message-set-status"><function>soup_server_message_set_status</function></link>. -If the response requires a body, you must decide whether to use -<literal>Content-Length</literal> encoding (the default), or -<literal>chunked</literal> encoding. -</para> - -<refsect3> -<title>Responding with <literal>Content-Length</literal> -Encoding</title> - -<para> -This is the simpler way to set a response body, if you have all of the
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/server/soup-server-io.c
Deleted
@@ -1,964 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ -/* - * soup-server-io.c: HTTP message I/O - * - * Copyright (C) 2000-2003, Ximian, Inc. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <glib/gi18n-lib.h> - -#include "soup.h" -#include "soup-body-input-stream.h" -#include "soup-body-output-stream.h" -#include "soup-filter-input-stream.h" -#include "soup-server-message-private.h" -#include "soup-message-headers-private.h" -#include "soup-misc.h" -#include "soup-socket.h" - -struct _SoupServerMessageIOData { - SoupMessageIOData base; - - GIOStream *iostream; - GInputStream *istream; - GOutputStream *ostream; - - GBytes *write_chunk; - goffset write_body_offset; - - GSource *unpause_source; - - GMainContext *async_context; -}; - -#define RESPONSE_BLOCK_SIZE 8192 -#define HEADER_SIZE_LIMIT (64 * 1024) - -void -soup_server_message_io_data_free (SoupServerMessageIOData *io) -{ - if (!io) - return; - - g_clear_object (&io->iostream); - - soup_message_io_data_cleanup (&io->base); - - if (io->unpause_source) { - g_source_destroy (io->unpause_source); - g_source_unref (io->unpause_source); - io->unpause_source = NULL; - } - - g_clear_pointer (&io->async_context, g_main_context_unref); - g_clear_pointer (&io->write_chunk, g_bytes_unref); - - g_slice_free (SoupServerMessageIOData, io); -} - -void -soup_server_message_io_finished (SoupServerMessage *msg) -{ - SoupServerMessageIOData *io; - SoupMessageIOCompletionFn completion_cb; - gpointer completion_data; - SoupMessageIOCompletion completion; - - io = soup_server_message_get_io_data (msg); - if (!io) - return; - - completion_cb = io->base.completion_cb; - completion_data = io->base.completion_data; - - if ((io->base.read_state >= SOUP_MESSAGE_IO_STATE_FINISHING && - io->base.write_state >= SOUP_MESSAGE_IO_STATE_FINISHING)) - completion = SOUP_MESSAGE_IO_COMPLETE; - else - completion = SOUP_MESSAGE_IO_INTERRUPTED; - - g_object_ref (msg); - soup_server_message_set_io_data (msg, NULL); - if (completion_cb) - completion_cb (G_OBJECT (msg), completion, completion_data); - g_object_unref (msg); -} - -GIOStream * -soup_server_message_io_steal (SoupServerMessage *msg) -{ - SoupServerMessageIOData *io; - SoupMessageIOCompletionFn completion_cb; - gpointer completion_data; - GIOStream *iostream; - - io = soup_server_message_get_io_data (msg); - if (!io || !io->iostream) - return NULL; - - iostream = g_object_ref (io->iostream); - completion_cb = io->base.completion_cb; - completion_data = io->base.completion_data; - - g_object_ref (msg); - soup_server_message_set_io_data (msg, NULL); - if (completion_cb) - completion_cb (G_OBJECT (msg), SOUP_MESSAGE_IO_STOLEN, completion_data); - g_object_unref (msg); - - return iostream; -} - -static void -closed_async (GObject *source, - GAsyncResult *result, - gpointer user_data) -{ - GOutputStream *body_ostream = G_OUTPUT_STREAM (source); - SoupServerMessage *msg = user_data; - SoupServerMessageIOData *io; - GCancellable *async_wait; - - io = soup_server_message_get_io_data (msg); - if (!io || !io->base.async_wait || io->base.body_ostream != body_ostream) { - g_object_unref (msg); - return; - } - - g_output_stream_close_finish (body_ostream, result, &io->base.async_error); - g_clear_object (&io->base.body_ostream); - - async_wait = io->base.async_wait; - io->base.async_wait = NULL; - g_cancellable_cancel (async_wait); - g_object_unref (async_wait); - - g_object_unref (msg); -} - -/* - * There are two request/response formats: the basic request/response, - * possibly with one or more unsolicited informational responses (such - * as the WebDAV "102 Processing" response): - * - * Client Server - * W:HEADERS / R:NOT_STARTED -> R:HEADERS / W:NOT_STARTED - * W:BODY / R:NOT_STARTED -> R:BODY / W:NOT_STARTED - * W:DONE / R:HEADERS (1xx) <- R:DONE / W:HEADERS (1xx) ... - * W:DONE / R:HEADERS <- R:DONE / W:HEADERS - * W:DONE / R:BODY <- R:DONE / W:BODY - * W:DONE / R:DONE R:DONE / W:DONE - * - * and the "Expect: 100-continue" request/response, with the client - * blocking halfway through its request, and then either continuing or - * aborting, depending on the server response: - * - * Client Server - * W:HEADERS / R:NOT_STARTED -> R:HEADERS / W:NOT_STARTED - * W:BLOCKING / R:HEADERS <- R:BLOCKING / W:HEADERS - * W:BODY / R:BLOCKING -> R:BODY / W:BLOCKING - * W:DONE / R:HEADERS <- R:DONE / W:HEADERS - * W:DONE / R:BODY <- R:DONE / W:BODY - * W:DONE / R:DONE R:DONE / W:DONE - */ - -static void -handle_partial_get (SoupServerMessage *msg) -{ - SoupRange *ranges; - int nranges; - GBytes *full_response; - guint status; - SoupMessageHeaders *request_headers; - SoupMessageHeaders *response_headers; - SoupMessageBody *response_body; - - request_headers = soup_server_message_get_request_headers (msg); - response_headers = soup_server_message_get_response_headers (msg); - response_body = soup_server_message_get_response_body (msg); - - /* Make sure the message is set up right for us to return a - * partial response; it has to be a GET, the status must be - * 200 OK (and in particular, NOT already 206 Partial - * Content), and the SoupServer must have already filled in - * the response body - */ - if (soup_server_message_get_method (msg) != SOUP_METHOD_GET || - soup_server_message_get_status (msg) != SOUP_STATUS_OK || - soup_message_headers_get_encoding (response_headers) != - SOUP_ENCODING_CONTENT_LENGTH || - response_body->length == 0 || - !soup_message_body_get_accumulate (response_body)) - return; - - /* Oh, and there has to have been a valid Range header on the - * request, of course.
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/server/soup-socket.c
Deleted
@@ -1,806 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ -/* - * soup-socket.c: Socket networking code. - * - * Copyright (C) 2000-2003, Ximian, Inc. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> - -#include <glib/gi18n-lib.h> -#include <gio/gnetworking.h> - -#include "soup-socket.h" -#include "soup.h" -#include "soup-io-stream.h" - -/*<private> - * SECTION:soup-socket - * @short_description: A network socket - * - * #SoupSocket is libsoup's TCP socket type. While it is primarily - * intended for internal use, #SoupSocket<!-- -->s are exposed in the - * API in various places, and some of their methods (eg, - * soup_socket_get_remote_address()) may be useful to applications. - **/ - -enum { - DISCONNECTED, - NEW_CONNECTION, - ACCEPT_CERTIFICATE, - LAST_SIGNAL -}; - -static guint signalsLAST_SIGNAL = { 0 }; - -enum { - PROP_0, - - PROP_GSOCKET, - PROP_IOSTREAM, - PROP_LOCAL_ADDRESS, - PROP_REMOTE_ADDRESS, - PROP_REMOTE_CONNECTABLE, - PROP_IPV6_ONLY, - PROP_TLS_CERTIFICATE, - PROP_TLS_DATABASE, - PROP_TLS_AUTH_MODE, - - LAST_PROPERTY -}; - -static GParamSpec *propertiesLAST_PROPERTY = { NULL, }; - -struct _SoupSocket { - GObject parent_instance; -}; - -typedef struct { - GInetSocketAddress *local_addr, *remote_addr; - GSocketConnectable *remote_connectable; - GIOStream *conn, *iostream; - GSocket *gsock; - GInputStream *istream; - GOutputStream *ostream; - - guint ipv6_only:1; - guint ssl:1; - GTlsCertificate *tls_certificate; - GTlsDatabase *tls_database; - GTlsAuthenticationMode tls_auth_mode; - - GMainContext *async_context; - GSource *watch_src; -} SoupSocketPrivate; - -static void soup_socket_initable_interface_init (GInitableIface *initable_interface); - -G_DEFINE_FINAL_TYPE_WITH_CODE (SoupSocket, soup_socket, G_TYPE_OBJECT, - G_ADD_PRIVATE (SoupSocket) - G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, - soup_socket_initable_interface_init)) - -static void finish_socket_setup (SoupSocket *sock); -static void finish_listener_setup (SoupSocket *sock); - -static void -soup_socket_init (SoupSocket *sock) -{ - SoupSocketPrivate *priv = soup_socket_get_instance_private (sock); - - priv->async_context = g_main_context_ref_thread_default (); -} - -static gboolean -soup_socket_initable_init (GInitable *initable, - GCancellable *cancellable, - GError **error) -{ - SoupSocket *sock = SOUP_SOCKET (initable); - SoupSocketPrivate *priv = soup_socket_get_instance_private (sock); - - if (priv->conn) { - g_warn_if_fail (priv->gsock == NULL); - - finish_socket_setup (sock); - } - - if (priv->gsock != NULL) { - int listening; - - g_warn_if_fail (priv->local_addr == NULL); - g_warn_if_fail (priv->remote_addr == NULL); - - if (!g_socket_get_option (priv->gsock, - SOL_SOCKET, SO_ACCEPTCONN, - &listening, error)) { - g_prefix_error (error, _("Could not import existing socket: ")); - return FALSE; - } - - finish_socket_setup (sock); - if (listening) - finish_listener_setup (sock); - else if (!g_socket_is_connected (priv->gsock)) { - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, - _("Can’t import unconnected socket")); - return FALSE; - } - } - - return TRUE; -} - -static void -disconnect_internal (SoupSocket *sock) -{ - SoupSocketPrivate *priv = soup_socket_get_instance_private (sock); - - g_clear_object (&priv->gsock); - if (priv->conn) { - g_io_stream_close (priv->conn, NULL, NULL); - g_signal_handlers_disconnect_by_data (priv->conn, sock); - g_clear_object (&priv->conn); - } -} - -static void -soup_socket_finalize (GObject *object) -{ - SoupSocket *sock = SOUP_SOCKET (object); - SoupSocketPrivate *priv = soup_socket_get_instance_private (sock); - - if (priv->conn) - disconnect_internal (SOUP_SOCKET (object)); - - g_clear_object (&priv->conn); - g_clear_object (&priv->iostream); - g_clear_object (&priv->istream); - g_clear_object (&priv->ostream); - - g_clear_object (&priv->local_addr); - g_clear_object (&priv->remote_addr); - g_clear_object (&priv->remote_connectable); - - g_clear_object (&priv->tls_certificate); - g_clear_object (&priv->tls_database); - - if (priv->watch_src) { - g_source_destroy (priv->watch_src); - g_source_unref (priv->watch_src); - } - g_clear_pointer (&priv->async_context, g_main_context_unref); - - G_OBJECT_CLASS (soup_socket_parent_class)->finalize (object); -} - -static void -finish_socket_setup (SoupSocket *sock) -{ - SoupSocketPrivate *priv = soup_socket_get_instance_private (sock); - - if (priv->gsock) { - if (!priv->conn) - priv->conn = (GIOStream *)g_socket_connection_factory_create_connection (priv->gsock); - - g_socket_set_option (priv->gsock, IPPROTO_TCP, TCP_NODELAY, TRUE, NULL); - } - - if (!priv->conn) - return; - - if (!priv->iostream) - priv->iostream = soup_io_stream_new (priv->conn, FALSE); - if (!priv->istream) - priv->istream = g_object_ref (g_io_stream_get_input_stream (priv->iostream));
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/server/soup-socket.h
Deleted
@@ -1,33 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ -/* - * Copyright (C) 2000-2003, Ximian, Inc. - */ - -#pragma once - -#include "soup-types.h" - -G_BEGIN_DECLS - -#define SOUP_TYPE_SOCKET (soup_socket_get_type ()) -G_DECLARE_FINAL_TYPE (SoupSocket, soup_socket, SOUP, SOCKET, GObject) - -SoupSocket *soup_socket_new (const char *optname1, - ...) G_GNUC_NULL_TERMINATED; - -gboolean soup_socket_listen (SoupSocket *sock, - GError **error); - -gboolean soup_socket_is_ssl (SoupSocket *sock); - -void soup_socket_disconnect (SoupSocket *sock); -gboolean soup_socket_is_connected (SoupSocket *sock); -GIOStream *soup_socket_get_connection (SoupSocket *sock); -GSocket *soup_socket_get_gsocket (SoupSocket *sock); -GSocket *soup_socket_steal_gsocket (SoupSocket *sock); -GIOStream *soup_socket_get_iostream (SoupSocket *sock); - -GInetSocketAddress *soup_socket_get_local_address (SoupSocket *sock); -GInetSocketAddress *soup_socket_get_remote_address (SoupSocket *sock); - -G_END_DECLS
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/tests/http2-server.py
Deleted
@@ -1,126 +0,0 @@ -#!/usr/bin/env python3 - -import asyncio -from functools import wraps -import os -from secrets import compare_digest -import sys -from urllib.parse import urlparse - -from quart import ( - request, - make_response, - Quart, -) - -app = Quart(__name__) - -timer_handle = None -loop = None - -def set_timeout(): - global timer_handle - - # ASAN is very slow, just don't have a timer. - if 'ASAN_OPTIONS' in os.environ: - return - - if timer_handle: - timer_handle.cancel() - - # This timeout just prevents a zombie process from - # running even if a test crashes. - timer_handle = loop.call_later(20, lambda: sys.exit(0)) - - -@app.route('/') -async def index(): - set_timeout() - return 'Hello world' - -@app.route('/slow') -async def slow(): - set_timeout() - await asyncio.sleep(1) - return 'Hello world' - -@app.route('/timeout') -async def timeout(): - set_timeout() - await asyncio.sleep(4) - return 'Hello world' - -@app.route('/no-content') -async def no_content(): - set_timeout() - return await make_response('', 204) - -@app.route('/large') -async def large(): - set_timeout() - - async def generate_data(): - # Send increasing letters just to aid debugging - letter = ord('A') - bytes_pending = 1024 * 24 - while bytes_pending: - await asyncio.sleep(0.1) - bytes_pending -= 1024 - string = chr(letter) * 1024 - letter += 1 - yield bytes(string, 'UTF-8') - yield b'\0' - - return generate_data() - -@app.route('/echo_query') -async def echo_query(): - set_timeout() - url = urlparse(request.url) - return url.query - -@app.route('/echo_post', methods='POST') -async def echo_post(): - set_timeout() - data = await request.get_data() - return data - -@app.route('/auth') -async def auth(): - set_timeout() - auth = request.authorization - - if ( - auth is not None and - auth.type == "basic" and - auth.username == 'username' and - compare_digest(auth.password, 'password') - ): - return 'Authenticated' - - response = await make_response('Authentication Required') - response.status_code = 401 - response.headers'WWW-Authenticate' = 'Basic' - return response - -has_been_misdirected = False - -@app.route('/misdirected_request') -async def misdirected_request(): - set_timeout() - global has_been_misdirected - - if not has_been_misdirected: - has_been_misdirected = True - response = await make_response('', 421) - return response - - return 'Success!' - -if __name__ == '__main__': - loop = asyncio.get_event_loop() - set_timeout() - - app.run(use_reloader=False, loop=loop, - certfile='test-cert.pem', - keyfile='test-key.pem')
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/tests/socket-test.c
Deleted
@@ -1,274 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ -/* - * Copyright 2007-2012 Red Hat, Inc. - * Copyright 2012 Nokia Corporation - */ - -#include "test-utils.h" -#include "libsoup/server/soup-socket.h" - -#include <fcntl.h> -#include <gio/gnetworking.h> - -#ifdef G_OS_WIN32 -#include <io.h> -#endif - -static void -assert_host_equals (GInetSocketAddress *addr, const char *host) -{ - char *addr_host = g_inet_address_to_string (g_inet_socket_address_get_address (addr)); - g_assert_cmpstr (addr_host, ==, host); - g_free (addr_host); -} - -static void -do_unconnected_socket_test (void) -{ - GInetSocketAddress *addr; - GSocketAddress *localhost; - SoupSocket *sock; - GSocketClient *client; - GSocketConnectable *remote_connectable; - GSocketConnection *conn; - GSocket *client_socket; - guint res; - - g_test_bug ("673083"); - - localhost = g_inet_socket_address_new_from_string ("127.0.0.1", 0); - - sock = soup_socket_new ("local-address", localhost, - NULL); - g_assert_true (sock != NULL); - - addr = soup_socket_get_local_address (sock); - g_assert_true (addr != NULL); - assert_host_equals (addr, "127.0.0.1"); - g_assert_cmpuint (g_inet_socket_address_get_port (addr), ==, 0); - - /* fails with ENOTCONN */ - g_test_expect_message ("libsoup", G_LOG_LEVEL_WARNING, - "*socket not connected*"); - addr = soup_socket_get_remote_address (sock); - g_test_assert_expected_messages (); - g_assert_null (addr); - - res = soup_socket_listen (sock, NULL); - g_assert_true (res); - - addr = soup_socket_get_local_address (sock); - g_assert_true (addr != NULL); - assert_host_equals (addr, "127.0.0.1"); - g_assert_cmpuint (g_inet_socket_address_get_port (addr), >, 0); - - client = g_socket_client_new (); - remote_connectable = G_SOCKET_CONNECTABLE (soup_socket_get_local_address (sock)); - conn = g_socket_client_connect (client, remote_connectable, NULL, NULL); - g_assert_true (conn != NULL); - client_socket = g_socket_connection_get_socket (conn); - g_assert_true (client_socket != NULL); - addr = G_INET_SOCKET_ADDRESS (g_socket_get_local_address (client_socket, NULL)); - g_assert_true (addr != NULL); - g_object_unref (addr); - addr = G_INET_SOCKET_ADDRESS (g_socket_get_remote_address (client_socket, NULL)); - g_assert_true (addr != NULL); - assert_host_equals (addr, "127.0.0.1"); - g_assert_cmpuint (g_inet_socket_address_get_port (addr), >, 0); - g_object_unref (addr); - g_object_unref (conn); - g_object_unref (client); - - client = g_socket_client_new (); - remote_connectable = G_SOCKET_CONNECTABLE (soup_socket_get_local_address (sock)); - /* save it for later */ - - /* listening socket fails with ENOTCONN */ - g_test_expect_message ("libsoup", G_LOG_LEVEL_WARNING, - /* We can't check the error message since it comes from - * libc and is locale-dependent. - */ - "*"); - addr = soup_socket_get_remote_address (sock); - g_test_assert_expected_messages (); - g_assert_null (addr); - - soup_socket_disconnect (sock); - - g_test_expect_message ("libsoup", G_LOG_LEVEL_WARNING, - /* This error message comes from soup-socket.c though */ - "*socket not connected*"); - addr = soup_socket_get_remote_address (sock); - g_test_assert_expected_messages (); - g_assert_null (addr); - - conn = g_socket_client_connect (client, remote_connectable, NULL, NULL); - g_assert_false (conn != NULL); - - g_object_unref (localhost); - g_object_unref (client); - g_object_unref (sock); -} - -static int -socket_get_fd (SoupSocket *socket) -{ - return g_socket_get_fd (soup_socket_get_gsocket (socket)); -} - -static void -do_socket_from_fd_server_test (void) -{ - GSocket *gsock; - SoupSocket *sock; - GInetSocketAddress *local; - GSocketAddress *gaddr; - GError *error = NULL; - - gsock = g_socket_new (G_SOCKET_FAMILY_IPV4, - G_SOCKET_TYPE_STREAM, - G_SOCKET_PROTOCOL_DEFAULT, - &error); - g_assert_no_error (error); - - gaddr = g_inet_socket_address_new_from_string ("127.0.0.1", 0); - g_socket_bind (gsock, gaddr, TRUE, &error); - g_object_unref (gaddr); - g_assert_no_error (error); - g_socket_listen (gsock, &error); - g_assert_no_error (error); - g_assert_false (g_socket_is_connected (gsock)); - - gaddr = g_socket_get_local_address (gsock, &error); - g_assert_no_error (error); - - sock = g_initable_new (SOUP_TYPE_SOCKET, NULL, &error, - "gsocket", gsock, - NULL); - g_assert_no_error (error); - g_assert_nonnull (sock); - - g_object_get (G_OBJECT (sock), - "local-address", &local, - NULL); - g_assert_cmpint (socket_get_fd (sock), ==, g_socket_get_fd (gsock)); - g_assert_true (soup_socket_is_connected (sock)); - - assert_host_equals (local, "127.0.0.1"); - g_assert_cmpint (g_inet_socket_address_get_port (local), ==, g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (gaddr))); - g_object_unref (local); - g_object_unref (gaddr); - - g_object_unref (sock); - - /* Closing the SoupSocket should have closed the GSocket */ - g_assert_true (g_socket_is_closed (gsock)); - - g_object_unref (gsock); -} - -static void -do_socket_from_fd_bad_test (void) -{ - GSocket *gsock, *gsock2, *gsockcli; - SoupSocket *sock, *sock2; - GInetSocketAddress *local, *remote; - GSocketAddress *gaddr; - GError *error = NULL; - - /* Importing an unconnected socket gives an error */ - gsock = g_socket_new (G_SOCKET_FAMILY_IPV4, - G_SOCKET_TYPE_STREAM, - G_SOCKET_PROTOCOL_DEFAULT, - &error); - g_assert_no_error (error); - g_assert_false (g_socket_is_connected (gsock)); - - sock = g_initable_new (SOUP_TYPE_SOCKET, NULL, &error, - "gsocket", gsock, - NULL); - g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED); - g_clear_error (&error); - g_assert_null (sock); - g_object_unref (gsock); - - gsock = g_socket_new (G_SOCKET_FAMILY_IPV4, - G_SOCKET_TYPE_STREAM, - G_SOCKET_PROTOCOL_DEFAULT, - &error); - g_assert_no_error (error);
View file
_service:tar_scm:libsoup-3.2.2.tar.xz/.gitignore
Added
@@ -0,0 +1,3 @@ +/po/libsoup.pot +/*build/ +/html/
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/.gitlab-ci.yml -> _service:tar_scm:libsoup-3.2.2.tar.xz/.gitlab-ci.yml
Changed
@@ -1,4 +1,4 @@ -image: registry.gitlab.gnome.org/gnome/libsoup/master:v16 +image: registry.gitlab.gnome.org/gnome/libsoup/master:v17 stages: - build @@ -17,7 +17,7 @@ extends: .build script: - cp .gitlab-ci/lcovrc ~/.lcovrc - - meson _build -Db_coverage=true -Dauto_features=enabled + - meson _build -Db_coverage=true --auto-features=enabled - meson compile -C _build - meson test --no-suite autobahn-quick --no-suite autobahn -C _build --verbose - ninja -C _build coverage-html @@ -36,7 +36,7 @@ fedora-autobahn-quick: extends: .build script: - - meson _build -Dauto-features=enabled -Dautobahn=enabled + - meson _build --auto-features=enabled -Dautobahn=enabled - meson test -C _build --suite autobahn-quick --verbose artifacts: paths: @@ -46,7 +46,7 @@ fedora-scan: extends: .build script: - - meson _build -Dauto_features=enabled + - meson _build --auto-features=enabled - ninja -C _build scan-build - bash -c 'if -n "$(ls -A _build/meson-logs/scanbuild/)" ; then echo "Scan build log found, assuming defects exist"; exit 1; fi' artifacts: @@ -63,7 +63,7 @@ SOUP_TEST_NO_IPV6: 1 script: # Introspection doesn't work when linking to libasan, the NTLM tests fail most likely due to unsafe usage of setenv() - - meson _build -Dauto-features=enabled -Db_sanitize=address -Dintrospection=disabled -Dvapi=disabled -Dntlm=disabled + - meson _build --auto-features=enabled -Db_sanitize=address -Dintrospection=disabled -Dvapi=disabled -Dntlm=disabled -Ddocs=disabled - meson test --no-suite autobahn-quick --no-suite autobahn -C _build --verbose --timeout-multiplier=10 artifacts: when: on_failure @@ -76,7 +76,7 @@ # variables: # CC: clang # script: -# - meson _build -Dauto-features=enabled -Dfuzzing=enabled -Dintrospection=disabled -Dvapi=disabled +# - meson _build --auto-features=enabled -Dfuzzing=enabled -Dintrospection=disabled -Dvapi=disabled # - meson test -C _build --suite=fuzzing --timeout-multiplier=10 # artifacts: # when: on_failure @@ -86,29 +86,30 @@ reference: stage: docs variables: - DESTDIR: _install - needs: + MESON_ARGS: >- + -Ddocs=enabled + -Ddoc_tests=true + -Dvapi=disabled script: - - meson _build --prefix=/usr -Dgtk_doc=true - - ninja -C _build libsoup-3.0-doc - - .gitlab-ci/check-docs.py - mkdir -p _reference/libsoup-3.0 - - cp -R _build/docs/reference/html/* _reference/libsoup-3.0/ - - cp -R /usr/share/gtk-doc/html/{glib,gio,gobject,libsoup-2.4} _reference - - cp .gitlab-ci/index.html _reference - - gtkdoc-rebase --relative --html-dir=./_reference/ --verbose + - meson ${MESON_ARGS} _build + - meson compile -C _build libsoup-doc --verbose + - meson test -C _build docs --verbose + - mv _build/docs/reference/libsoup-3.0/* _reference/libsoup-3.0 + # Add libsoup-2.4 docs. + - cp -R /usr/share/gtk-doc/html/{glib,gio,gobject,libsoup-2.4} _reference/ + - cp .gitlab-ci/index.html _reference/ artifacts: paths: - - _build/docs/reference/libsoup-3.0-*.txt - _reference - coverage: '/^(\d+\%) symbol docs coverage\.\s+/' pages: stage: deploy needs: 'reference' script: - - mv _reference/ public/ + - mv _reference public artifacts: + when: on_success paths: - public only:
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/.gitlab-ci/Dockerfile -> _service:tar_scm:libsoup-3.2.2.tar.xz/.gitlab-ci/Dockerfile
Changed
@@ -29,11 +29,11 @@ vala \ valgrind \ which \ - && dnf builddep -y glib2 vala \ + && dnf builddep -y glib2 nghttp2 vala \ && dnf clean all \ && python2.7 -m ensurepip \ && pip2.7 install virtualenv autobahntestsuite \ - && pip3 install quart gi-docgen + && pip3 install gi-docgen # We need glib 2.70 RUN git clone https://gitlab.gnome.org/GNOME/glib.git \ @@ -71,6 +71,16 @@ && popd \ && rm -rf libsoup +# Update libnghttp2 for do_invalid_header_rfc9113_received_test() +RUN git clone https://github.com/nghttp2/nghttp2.git \ + && pushd nghttp2 \ + && git checkout v1.50.0 \ + && autoreconf --install --symlink \ + && ./configure --prefix=/usr --disable-static --disable-examples \ + && make -j $(nproc) install \ + && popd \ + && rm -rf nghttp2 + ARG HOST_USER_ID=5555 ENV HOST_USER_ID ${HOST_USER_ID} RUN useradd -u $HOST_USER_ID -ms /bin/bash user
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/.gitlab-ci/run-docker.sh -> _service:tar_scm:libsoup-3.2.2.tar.xz/.gitlab-ci/run-docker.sh
Changed
@@ -2,7 +2,7 @@ set -e -TAG="registry.gitlab.gnome.org/gnome/libsoup/master:v16" +TAG="registry.gitlab.gnome.org/gnome/libsoup/master:v17" SUDO_CMD="sudo" if docker -v |& grep -q podman; then
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/NEWS -> _service:tar_scm:libsoup-3.2.2.tar.xz/NEWS
Changed
@@ -1,3 +1,53 @@ +Changes in libsoup from 3.2.1 to 3.2.2: + +* Various HTTP/2 Fixes: Carlos Garcia Campos + * Fix `content-sniffed` not being emitted for resources without content + * Fix leak of SoupServerConnection when stolen + +Changes in libsoup from 3.2.0 to 3.2.1: + +* When built against nghttp2 1.50.0+ be relaxed about header whitespace Carlos Garcia Campos +* Fix possible crash when cancelling an HTTP/2 message Carlos Garcia Campos +* Fix regresion where soup_server_message_get_socket() could return NULL Carlos Garcia Campos +* Fix minor memory leak Milan Crha + +Changes in libsoup from 3.1.4 to 3.2.0: + +Changes in libsoup from 3.1.3 to 3.1.4: + +* Numerous improvements to HTTP/2 reliablity Carlos Garcia Campos +* Fix `http` proxy authentication with default proxy resolver Carlos Garcia Campos +* Fix undefined ``ssize_t`` with MSVC Patrick Griffis + +Changes in libsoup from 3.1.2 to 3.1.3: + +* Fix compile error when `SOUP_VERSION_MAX_ALLOWED` is defined Patrick Griffis + +Changes in libsoup from 3.1.1 to 3.1.2: + +* Replace HTTP/2 tests using Quart with internal HTTP/2 server tests Carlos Garcia Campos +* Improve version macros including adding ability to define `SOUP_DISABLE_DEPRECATION_WARNINGS` Emmanuele Bassi + +Changes in libsoup from 3.0.7 to 3.1.1: + +* Reintroduce some thread-safety to SoupSession (see https://libsoup.org/libsoup-3.0/client-thread-safety.html) Carlos Garcia Campos +* Add SoupServerMessage:tls-peer-certificate and SoupServerMessage:tls-peer-certificate-errors Ignacio Casal Quinteiro +* Port docs to gi-docgen Maximiliano Sandoval R +* Update documentation Patrick Griffis + +Changes in libsoup from 3.0.6 to 3.0.7: + +* Fix leak in SoupAuthNTLM Milan Crha +* Fix constructing SoupAuthNTLM objects Milan Crha +* Disable mutual negotiation in SoupAuthNegotiate Michael Catanzaro +* http2: Do not advertise the `h2` protocool for proxy connections Carlos Garcia Campos +* http2: Remove left-over headers when HTTP/1 redirects to HTTP/2 Carlos Garcia Campos +* http2: Handle HTTP_1_1_REQUIRED error Carlos Garcia Campos +* http2: Read request bodies synchronously for sync requests Carlos Garcia Campos +* http2: Properly handle server sending shut down GOAWAY Carlos Garcia Campos +* tests: Remove dependency on Apache's PHP module Carlos Garcia Campos +* tests: Depend upon Apache's http2 module Carlos Garcia Campos + Changes in libsoup from 3.0.5 to 3.0.6: * Misc HTTP/2 fixes Carlos Garcia Campos
View file
_service:tar_scm:libsoup-3.2.2.tar.xz/docs/reference/build-howto.md
Added
@@ -0,0 +1,68 @@ +Title: Building with libsoup +Slug: build-howto + +# Building with libsoup + +## Buildsystem Integration + +Like other GNOME libraries, libsoup uses +`pkg-config` to provide compiler options. The package +name is `libsoup-3.0`. For example if you use Autotools: + +``` +PKG_CHECK_MODULES(LIBSOUP, libsoup-3.0) +AC_SUBST(LIBSOUP_CFLAGS) +AC_SUBST(LIBSOUP_LIBS) +``` + +If you use Meson: + +``` +libsoup_dep = dependency('libsoup-3.0') +``` + +## API Availability and Deprecation Warnings + +If you want to restrict your program to a particular libsoup version or range of +versions, you can define const@VERSION_MIN_REQUIRED and/or +`SOUP_VERSION_MAX_ALLOWED`. For example with Autotools: + +``` +LIBSOUP_CFLAGS="$LIBSOUP_CFLAGS -DSOUP_VERSION_MIN_REQUIRED=SOUP_VERSION_3_0" +LIBSOUP_CFLAGS="$LIBSOUP_CFLAGS -DSOUP_VERSION_MAX_ALLOWED=SOUP_VERSION_3_2" +``` + +Or with Meson: + +```meson +add_project_arguments( + '-DSOUP_VERSION_MIN_REQUIRED=SOUP_VERSION_2_99', + '-DSOUP_VERSION_MAX_ALLOWED=SOUP_VERSION_3_0', + language: 'c' +) +``` + +The const@VERSION_MIN_REQUIRED declaration states that the code is not +expected to compile on versions of libsoup older than the indicated version, and +so the compiler should print warnings if the code uses functions that were +deprecated as of that release. + +The `SOUP_VERSION_MAX_ALLOWED` declaration states that the code *is* expected +to compile on versions of libsoup up to the indicated version, and so, when +compiling the program against a newer version than that, the compiler should +print warnings if the code uses functions that did not yet exist in the +max-allowed release. + +You can use func@CHECK_VERSION to check the version of libsoup at compile +time, to compile different code for different libsoup versions. (If you are +setting const@VERSION_MIN_REQUIRED and `SOUP_VERSION_MAX_ALLOWED` to +different versions, as in the example above, then you almost certainly need to +be doing this.) + +## Headers + +Code using libsoup should include the header like so: + +```c +#include <libsoup/soup.h> +```
View file
_service:tar_scm:libsoup-3.2.2.tar.xz/docs/reference/client-advanced.md
Added
@@ -0,0 +1,156 @@ +Title: Advances Usage +Slug: client-advanced + +# Advanced Usage + +## Customizing Session Options + +When you create the session with ctor@Session.new_with_options, you can +specify various additional options. See the class@Session documentation for +more details but these may be interesting: property@Session:max-conns and +property@Session:max-conns-per-host, property@Session:user-agent, +property@Session:timeout, property@Session:accept-language and +property@Session:accept-language-auto. + +## Adding Session Features + +Additional session functionality is provided as iface@SessionFeatures, which +can be added to or removed from a session. + +One such feature is class@ContentDecoder which is added by default. This +advertises to servers that the client supports compression, and automatically +decompresses compressed responses. + +Some other available features that you can add include: + +<table> + <tr> + <td>class@Logger</td> + <td> + A debugging aid, which logs all of libsoup's HTTP traffic + to <code>stdout</code> (or another place you specify). + </td> + </tr> + <tr> + <td> + class@CookieJar, class@CookieJarText, + and class@CookieJarDB. + </td> + <td> + Support for HTTP cookies. class@CookieJar + provides non-persistent cookie storage, while + class@CookieJarText uses a text file to keep + track of cookies between sessions, and + class@CookieJarDB uses a + <tt>SQLite</tt> database. + </td> + </tr> + <tr> + <td>class@ContentSniffer</td> + <td> + Uses the HTML5 sniffing rules to attempt to + determine the Content-Type of a response when the + server does not identify the Content-Type, or appears to + have provided an incorrect one. + </td> + </tr> +</table> + +Use the method@Session.add_feature_by_type function to add features that don't +require any configuration (such as class@ContentSniffer), and the +method@Session.add_featurefunction to add features that must be constructed +first (such as class@Logger). For example, an application might do something +like the following: + +```c +session = soup_session_new (); +soup_session_add_feature_by_type (session, SOUP_TYPE_CONTENT_SNIFFER); + +if (debug_level) { + SoupLogger *logger = soup_logger_new (debug_level); + soup_session_add_feature (session, SOUP_SESSION_FEATURE (logger)); + g_object_unref (logger); +} +``` + +You can also remove features by calling method@Session.remove_feature or +method@Session.remove_feature_by_type. + +## Using a proxy + +By default libsoup tries to respect the default proxy (as best as +func@Gio.ProxyResolver.get_default knows), however you can set a custom one or +disable it outright using the property@Session:proxy-resolver property. For +example: + +```c +{ + GProxyResolver *resolver = g_simple_proxy_resolver_new ("https://my-proxy-example.org", NULL); + SoupSession *session = soup_session_new_with_options ("proxy-resolver", resolver, NULL); + g_object_unref (resolver); +} +``` + +## Using the SoupMessage API + +The class@Message type contains all the state for a request and response pair +that you send and receive to a server. For many more complex tasks you will have +to create one of these and send it with the method@Session.send function. For +example this sends a request with the `HEAD` method: + +```c +{ + SoupSession *session = soup_session_new (); + SoupMessage *msg = soup_message_new (SOUP_METHOD_HEAD, "https://example.org"); + + // This allows you to also customize the request headers: + SoupMessageHeaders *request_headers = soup_message_get_request_headers (msg); + soup_message_headers_replace (request_headers, "Foo", "Bar"); + + GInputStream *in_stream = soup_session_send (session, msg, NULL, NULL); + if (in_stream) { + g_print ("Message was sent and recived a response of %u (%s)\n", + soup_message_get_status (msg), soup_message_get_reason_phrase (msg)); + // You can also inspect the response headers via soup_message_get_response_headers(); + g_object_unref (in_stream); + } + + g_object_unref (msg); + g_object_unref (session); +} +``` + +## Handling authentication + +```c +static gboolean +authenticate_callback (SoupMessage *msg, SoupAuth *auth, gboolean retrying, gpointer user_data) +{ + if (retrying) { + // Maybe don't try again if our password failed + return FALSE; + } + + soup_auth_authenticate (auth, "username", "password"); + + // Returning TRUE means we have or *will* handle it. + // soup_auth_authenticate() or soup_auth_cancel() can be called later + // for example after showing a prompt to the user or loading the password + // from a keyring. + return TRUE; +} + +int main (int argc, char **argv) +{ + SoupSession *session = soup_session_new (); + SoupMessage *msg = soup_message_new (SOUP_METHOD_GET, "https://example.org"); + g_signal_connect (msg, "authenticate", G_CALLBACK (authenticate_callback), NULL); + GInputStream *in_stream = soup_session_send (session, msg, NULL, NULL); + + if (in_stream) { + g_object_unref (in_stream); + } + + return 0; +} +```
View file
_service:tar_scm:libsoup-3.2.2.tar.xz/docs/reference/client-basic.md
Added
@@ -0,0 +1,183 @@ +Title: Creating a Basic Client +Slug: client-basic + +# Creating a Basic Client + +libsoup provides a feature rich and complete HTTP client feature-set however in this guide we will just be touching the basics. + +## Creating a SoupSession +The core of libsoup is class@Session; It contains all of the state of a client +including managing connections, queuing messages, handling authentication and +redirects, and much more. For now lets assume the default set of options and +features it provides are acceptable for most usage in which case you simply need +to create one with ctor@Session.new. + +## Downloading Into Memory + +A common use case is that you simply want to request an HTTP resource and store +it for later use. There are a few methods of doing this but libsoup provides a high +level API to accomplish this: + +```c +#include <libsoup/soup.h> + +int main (int argc, char **argv) +{ + SoupSession *session = soup_session_new (); + SoupMessageHeaders *response_headers; + const char *content_type; + SoupMessage *msg = soup_message_new (SOUP_METHOD_GET, "https://upload.wikimedia.org/wikipedia/commons/5/5f/BBB-Bunny.png"); + GError *error = NULL; + GBytes *bytes = soup_session_send_and_read ( + session, + msg, + NULL, // Pass a GCancellable here if you want to cancel a download + &error); + + if (error) { + g_printerr ("Failed to download: %s\n", error->message); + g_error_free (error); + g_object_unref (msg); + g_object_unref (session); + return 1; + } + + response_headers = soup_message_get_response_headers (msg); + content_type = soup_message_headers_get_content_type (response_headers); + + // content_type = "image/png" + // bytes contains the raw data that can be used elsewhere + g_print ("Downloaded %zu bytes of type %s\n", + g_bytes_get_size (bytes), content_type); + + g_bytes_unref (bytes); + g_object_unref (msg); + g_object_unref (session); + return 0; +} +``` + +## Efficiently Streaming Data + +While sometimes you want to store an entire download in memory it is often more +efficient to stream the data in chunks. In this example we will write the output +to a file. + +```c +#include <libsoup/soup.h> + +int main (int argc, char **argv) +{ + SoupSession *session = soup_session_new (); + SoupMessageHeaders *response_headers; + const char *content_type; + goffset content_length; + SoupMessage *msg = soup_message_new (SOUP_METHOD_GET, "https://upload.wikimedia.org/wikipedia/commons/5/5f/BBB-Bunny.png"); + GError *error = NULL; + GInputStream *in_stream = soup_session_send ( + session, + msg, + NULL, + &error); + + if (error) { + g_printerr ("Failed to download: %s\n", error->message); + g_error_free (error); + g_object_unref (msg); + g_object_unref (session); + return 1; + } + + GFile *output_file = g_file_new_tmp ("BBB-Bunny-XXXXXX.png"); + GOutputStream *out_stream = g_file_create (output_file, + G_FILE_CREATE_NONE, NULL, &error); + + if (error) { + g_printerr ("Failed to create file \"%s\": %s\n", + g_file_peek_path (output_file), error->message); + g_error_free (error); + g_object_unref (output_file); + g_object_unref (in_stream); + g_object_unref (msg); + g_object_unref (session); + return 1; + } + + response_headers = soup_message_get_response_headers (msg); + content_type = soup_message_headers_get_content_type (response_headers); + content_length = soup_message_headers_get_content_length (response_headers); + + // content_type = "image/png" + g_print ("Downloading %zu bytes of type %s to %s\n", + content_length, content_type, + g_file_peek_path (output_file)); + + g_output_stream_splice (out_stream, in_stream, + G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, + NULL, &error); + + if (error) { + g_print ("Download failed: %s\n", error->message); + g_error_free (error); + } else { + g_print ("Download completed\n"); + } + + g_object_unref (output_file); + g_object_unref (in_stream); + g_object_unref (out_stream); + g_object_unref (msg); + g_object_unref (session); + return error ? 1 : 0; +} +``` + +## Using Asynchronously + +If you are using libsoup in an application with a struct@GLib.MainLoop such as +a GTK application you do not want to block the mainloop by doing IO. To +accomplish this libsoup provides an asynchronous version of each of the APIs: +method@Session.send_and_read_async and method@Session.send_async. These +behave the same as all async GLib APIs, for example: + +```c +#include <libsoup/soup.h> + +static void on_load_callback (GObject *source, GAsyncResult *result, gpointer user_data) +{ + GMainLoop *loop = user_data; + GError *error = NULL; + GBytes *bytes = soup_session_send_and_read_finish (SOUP_SESSION (source), result, &error); + + // Usage here is the same as before + if (error) { + g_error_free (error); + } else { + g_bytes_unref (bytes); + } + + g_main_loop_quit (loop); +} + +int main (int argc, char **argv) +{ + SoupSession *session = soup_session_new (); + GMainLoop *loop = g_main_loop_new (NULL, FALSE); + SoupMessage *msg = soup_message_new (SOUP_METHOD_GET, "https://upload.wikimedia.org/wikipedia/commons/5/5f/BBB-Bunny.png"); + + soup_session_send_and_read_async ( + session, + msg, + G_PRIORITY_DEFAULT, + NULL, + on_load_callback, + loop); + + g_main_loop_run (loop); + + g_main_loop_unref (loop); + g_object_unref (msg); + g_object_unref (session); + return 0; +} +```
View file
_service:tar_scm:libsoup-3.2.2.tar.xz/docs/reference/client-thread-safety.md
Added
@@ -0,0 +1,39 @@ +Title: Client thread safety +Slug: client-thread-safety + +# Client thread safety + +libsoup is not fully thread safe, but since version 3.2 it's possible +to send messages from any thread. The recommended and most efficient +way to use libsoup is using only the async API from a single thread, +even when it feels natural to use the sync API from a worker +thread. While there's not much difference in HTTP/1, in the case of +HTTP/2, two messages for the same host sent from different threads +will not use the same connection, so the advantage of HTTP/2 +multiplexing is lost. + +There are a few important things to consider when using multiple +threads: + + - Only the API to send messages can be called concurrently from + multiple threads. So, in case of using multiple threads, you must + configure the session (setting network properties, features, etc.) + from the thread it was created and before any request is made. + + - All signals associated to a message + (signal@Session::request-queued, + signal@Session::request-unqueued, and all Message signals) are + emitted from the thread that started the request, and all the IO will + happen there too. + + - The session can be created in any thread, but all session APIs + except the methods to send messages must be called from the thread + where the session was created. + + - To use the async API from a thread different than the one where the + session was created, the thread must have a thread default main + context where the async callbacks are dispatched. + + - The sync API doesn't need any main context at all. + +
View file
_service:tar_scm:libsoup-3.2.2.tar.xz/docs/reference/client-tls.md
Added
@@ -0,0 +1,101 @@ +Title: Everything TLS Related +Slug: client-tls + +# Everything TLS Related + +libsoup comes with TLS support provided by glib-networking. This has multiple backends +including gnutls (default on all platforms), SChannel on Windows, or OpenSSL. + +## Accepting Invalid or Pinned Certificates + +This makes use of the signal@Message::accept-certificate signal. + +```c +static gboolean +accept_certificate_callback (SoupMessage *msg, GTlsCertificate *certificate, + GTlsCertificateFlags tls_errors, gpointer user_data) +{ + // Here you can inspect @certificate or compare it against a trusted one + // and you can see what is considered invalid by @tls_errors. + // Returning TRUE trusts it anyway. + return TRUE; +} + +int main (int argc, char **argv) +{ + SoupSession *session = soup_session_new (); + SoupMessage *msg = soup_message_new (SOUP_METHOD_GET, "https://example.org"); + g_signal_connect (msg, "accept-certificate", G_CALLBACK (accept_certificate_callback), NULL); + GInputStream *in_stream = soup_session_send (session, msg, NULL, NULL); + + if (in_stream) { + g_object_unref (in_stream); + } + + return 0; +} +``` + +## Setting a Custom CA + +```c +{ + GError *error = NULL; + // NOTE: This is blocking IO + GTlsDatabase *tls_db = g_tls_file_database_new ("/foo/ca.pem", &error); + + if (error) { + g_printerr ("Failed to load certificates: %s\n", error->message); + g_error_free (error); + return; + } + + SoupSession *session = soup_session_new_with_options ("tls-database", tls_db, NULL); + g_object_unref (tls_db); +} +``` + +## Using Client Certificates + +```c +static gboolean +on_request_certificate (SoupMessage *msg, GTlsClientConnection *conn, gpointer user_data) +{ + GTlsCertificate *client_cert = user_data; + + /* We immediately set this however you can set this later in an async function. */ + soup_message_set_tls_client_certificate (msg, client_cert); + + return TRUE; /* We handled the request */ +} + +int main (int argc, char **argv) +{ + GError *error = NULL; + GTlsCertificate *client_cert = g_tls_certificate_new_from_file ("/foo/cert.pem", &error); + + if (error) { + g_printerr ("Failed to load certificate: %s\n", error->message); + g_error_free (error); + return 1; + } + + SoupSession *session = soup_session_new (); + SoupMessage *msg = soup_message_new ("GET", "https://example.org"); + + /* We can set the certificate ahead of time if we already have one */ + // soup_message_set_tls_client_certificate (msg, client_cert) + + /* However we can also dynamically request one which is useful in + * applications that show a graphical prompt for example. */ + g_signal_connect (msg, "request-certificate", + G_CALLBACK (on_request_certificate), client_cert); + + // Send the message... + + g_object_unref (msg); + g_object_unref (session); + g_object_unref (client_cert); + return 0; +} +```
View file
_service:tar_scm:libsoup-3.2.2.tar.xz/docs/reference/libsoup.toml.in
Added
@@ -0,0 +1,52 @@ +library +namespace = "Soup" +version = "@VERSION@" +browse_url = "https://gitlab.gnome.org/GNOME/libsoup" +repository_url = "https://gitlab.gnome.org/GNOME/libsoup.git" +docs_url = "https://libsoup.org/libsoup-3.0/" +website_url = "https://libsoup.org/" +authors = "Dan Winship, Claudio Saavedra, Patrick Griffis, and Carlos Garcia Campos" +license = "LGPL-2.0-or-later" +description = "HTTP client/server library for GNOME" +dependencies = "GObject-2.0", "GLib-1.0", "Gio-2.0" +devhelp = true +search_index = true + +dependencies."GObject-2.0" +name = "GObject" +description = "The base type system library" +docs_url = "https://docs.gtk.org/gobject/" + +dependencies."GLib-2.0" +name = "GLib" +description = "The base type system library" +docs_url = "https://docs.gtk.org/glib/" + +dependencies."Gio-2.0" +name = "GIO" +description = "GObject Interfaces and Objects, Networking, IPC, and I/O" +docs_url = "https://docs.gtk.org/gio/" + +theme +name = "basic" +show_index_summary = true +show_class_hierarchy = true + +source-location +base_url = "https://gitlab.gnome.org/GNOME/libsoup/-/blob/master/" + +extra +# The same order will be used when generating the index +content_files = + "build-howto.md", + 'client-basic.md', + 'client-advanced.md', + 'client-thread-safety.md', + 'client-tls.md', + 'server-howto.md', + "migrating-from-libsoup-2.md", + + +content_images = + +urlmap_file = "urlmap.js"
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/docs/reference/meson.build -> _service:tar_scm:libsoup-3.2.2.tar.xz/docs/reference/meson.build
Changed
@@ -1,87 +1,69 @@ -ignore_headers = - 'gconstructor.h', - 'soup.h', - 'soup-enum-types.h', - 'soup-message-private.h', - 'soup-session-private.h', - 'soup-auth-digest-private.h', - 'soup-brotli-decompressor.h', - 'soup-connection.h', - 'soup-connection-auth.h', - 'soup-message-queue-item.h', - 'soup-path-map.h', - 'soup-http-input-stream.h', - 'soup-converter-wrapper.h', - 'soup-body-input-stream.h', - 'soup-body-output-stream.h', - 'soup-client-input-stream.h', - 'soup-content-processor.h', - 'soup-content-sniffer-stream.h', - 'soup-io-stream.h', - 'soup-cache-input-stream.h', - 'soup-filter-input-stream.h', - 'soup-cookie-jar-sqlite.h', - 'soup-cache-private.h', - 'soup-cache-client-input-stream.h', - 'soup-logger-input-stream.h', - 'soup-logger-private.h', - 'soup-socket.h', - 'soup-socket-properties.h', - 'soup-websocket-extension-manager-private.h', - 'soup-misc.h', - 'soup-date-utils-private.h', - 'soup-resources.h', - 'soup-private-enum-types.h', - 'soup-server-message-private.h', - 'soup-message-io-data.h', - 'soup-message-io-source.h', - 'soup-uri-utils-private.h', - 'soup-session-feature-private.h', - 'soup-message-metrics-private.h', - 'soup-client-message-io.h', - 'soup-message-io-completion.h', - 'soup-client-message-io-http1.h', - 'soup-client-message-io-http2.h', - 'soup-body-input-stream-http2.h', - 'soup-tls-interaction.h', - 'soup-header-names.h', - 'soup-message-headers-private.h', +expand_content_md_files = + 'build-howto.md', + 'client-basic.md', + 'client-advanced.md', + 'client-thread-safety.md', + 'client-tls.md', + 'server-howto.md', + 'migrating-from-libsoup-2.md', -mkdb_args = - '--output-format=xml' - +toml_data = configuration_data() +toml_data.set('VERSION', meson.project_version()) -scan_args = - '--deprecated-guards=SOUP_DISABLE_DEPRECATED', - '--rebuild-types', - '--ignore-decorators="SOUP_DEPRECATED\w*\s*()|SOUP_DEPRECATED\w*|SOUP_AVAILABLE\w_*"' - +gidocgen_dep = dependency('gi-docgen', version: '>= 2021.1', + fallback: 'gi-docgen', 'dummy_dep', + native: true, + required: get_option('docs') +) -glib_prefix = glib_dep.get_pkgconfig_variable('prefix') -glib_docpath = glib_prefix / 'share' / 'gtk-doc' / 'html' +have_docs = gidocgen_dep.found() +if not enable_introspection and get_option('docs').auto() + have_docs = false + warning('Documentation will not be built as introspection was disabled') +elif not enable_introspection and get_option('docs').enabled() + error('Documentation cannot be built without introspection being enabled') +endif -gnome.gtkdoc('libsoup-3.0', - main_xml : 'libsoup-3.0-docs.xml', - src_dir : srcdir, - ignore_headers : ignore_headers, - namespace : 'soup', - mkdb_args : mkdb_args, - scan_args : scan_args, - fixxref_args : - '--html-dir=@0@'.format(get_option('datadir') / 'gtk-doc', 'html'), - '--extra-dir=@0@'.format(glib_docpath / 'glib'), - '--extra-dir=@0@'.format(glib_docpath /'gobject'), - '--extra-dir=@0@'.format(glib_docpath /'gio'), - , - dependencies : libsoup_dep, - install : true, - content_files: - 'build-howto.xml', - 'client-basic.xml', - 'client-advanced.xml', - 'client-tls.xml', - 'server-howto.xml', - 'migrating-from-libsoup-2.xml', - , -) +if have_docs + libsoup_toml = configure_file( + input: 'libsoup.toml.in', + output: 'libsoup.toml', + configuration: toml_data + ) + + gidocgen = find_program('gi-docgen') + + docs_dir = get_option('datadir') / 'doc' + + custom_target('libsoup-doc', + input: libsoup_toml, soup_gir_gen_sources0 , + output: 'libsoup-@0@'.format(apiversion), + command: + gidocgen, + 'generate', + '--quiet', + '--add-include-path=@0@'.format(meson.current_build_dir() / '../../libsoup'), + '--config=@INPUT0@', + '--output-dir=@OUTPUT@', + '--no-namespace-dir', + '--content-dir=@0@'.format(meson.current_source_dir()), + '@INPUT1@', + , + depend_files: expand_content_md_files , + build_by_default: true, + install: true, + install_dir: docs_dir, + ) + + if get_option('doc_tests') + test('docs', gidocgen, + args: + 'check', + '--add-include-path=@0@'.format(meson.current_build_dir() / '../../libsoup'), + '--config=@0@'.format(libsoup_toml), + soup_gir_gen_sources0, + + ) + endif +endif \ No newline at end of file
View file
_service:tar_scm:libsoup-3.2.2.tar.xz/docs/reference/migrating-from-libsoup-2.md
Added
@@ -0,0 +1,163 @@ +Title: Migrating from libsoup 2 +Slug: migrating-from-libsoup-2 + +# Migrating from libsoup 2 + +## Removed APIs + +This is a list of APIs that have been removed: + + - XML-RPC support. + - Handling of `file://` and `data://` URIs You should use iface@Gio.File for + the former and func@uri_decode_data_uri for the latter. + - Define aliases for property names You must use the string name of properties + directly which works in libsoup 2 already. + - `SoupSession:add-feature` and `SoupSession:add-feature-by-type` You must call + method@Session.add_feature and method@Session.add_feature_by_type + directly. + - `SoupRequest`: You should use method@Session.send or + method@Session.send_async methods. + - `SoupAddress` has been replaced with class@Gio.InetAddress and + class@Gio.NetworkAddress. + - `SoupSocket` has been removed. + - `SoupProxyResolverDefault` is replaced by + func@Gio.ProxyResolver.get_default. + - `SoupBuffer` has been replaced by struct@GLib.Bytes and + struct@GLib.ByteArray. + - `SoupDate` has been replaced by `GDateTime`. + - `SoupSession:ssl-strict` has been removed in favor of using the + signal@Message::accept-certificate signal. + - `soup_session_cancel_message()` has been removed instead you + pass a class@Gio.Cancellable to APIs and call method@Gio.Cancellable.cancel. + +## Moved authenticate signal + +The `SoupSession::authenticate` signal has been replaced by +signal@Message::authenticate. It now allows returning `TRUE` to signify if +you will handle authentication which allows for asynchronous handling. + +## Structs are private + +You can no longer directly access various structs such as class@Message. These are +now accessed by getters and setters. See below for direct +conversions: + +<!-- TODO add links --> +<table> + <tr> + <th>Struct field</th> + <th>Getter/Setter function</th> + </tr> + <tr> + <td>SoupMessage.method</td> + <td>soup_message_get_method()</td> + </tr> + <tr> + <td>SoupMessage.status_code</td> + <td>soup_message_get_status()</td> + </tr> + <tr> + <td>SoupMessage.reason_phrase</td> + <td>soup_message_get_reason_phrase()</td> + </tr> + <tr> + <td>SoupMessage.uri</td> + <td>soup_message_get_uri(), soup_message_set_uri()</td> + </tr> + <tr> + <td>SoupMessage.request_headers</td> + <td>soup_message_get_request_headers()</td> + </tr> + <tr> + <td>SoupMessage.response_headers</td> + <td>soup_message_get_response_headers()</td> + </tr> + <tr> + <td>SoupMessage.request_body</td> + <td>soup_message_set_request_body(), soup_message_set_request_body_from_bytes()</td> + </tr> + <tr> + <td>SoupMessage.response_body</td> + <td>See section on IO</td> + </tr> +</table> + +Similar struct changes exist for struct@Cookie but have very straightforward +replacements. + +## URI type changed + +The `SoupURI` type has been replaced with the struct@GLib.Uri type which has +some implications. + +Creating a struct@GLib.Uri is generally as simple as `g_uri_parse (uri, + SOUP_HTTP_URI_FLAGS, NULL)`. You may want to add + +`G_URI_FLAGS_PARSE_RELAXED` to accept input that used to be considered valid. + +Note that unlike `SoupURI`, `GUri` is an immutable type so you cannot change the +contents of one after it has been constructed. We provide func@uri_copy to aid +in modifying them. + +The equivalent behavior to `soup_uri_to_string (uri, FALSE)` +is `g_uri_to_string_partial (uri, G_URI_HIDE_PASSWORD)`. + +Since `GUri` does not provide any function to check for equality +func@uri_equal still exists. + +Sending a `OPTIONS` message with a path of `*` is no longer a valid URI and has +been replaced with property@Message:is-options-ping. + +## Status codes no longer used for internal errors + +Previously enum@Status was used to hold libsoup errors +(`SOUP_STATUS_IS_TRANSPORT_ERROR()`). Now all of these errors are propagated up +through the normal struct@GLib.Error method on the various APIs to send +messages. Here is a mapping chart between the status codes and new errors: + +<table> + <tr> + <th>Old Status Codes</th> + <th>New <code>GError</code></th> + </tr> + <tr> + <td><code>SOUP_STATUS_CANCELLED</code></td> + <td><code>G_IO_ERROR_CANCELLED</code></td> + </tr> + <tr> + <td><code>SOUP_STATUS_MALFORMED</code></td> + <td><code>SOUP_SESSION_ERROR_PARSING</code>, <code>SOUP_SESSION_ERROR_ENCODING</code></td> + </tr> + <tr> + <td><code>SOUP_STATUS_TOO_MANY_REDIRECTS</code></td> + <td><code>SOUP_SESSION_ERROR_TOO_MANY_REDIRECTS</code></td> + </tr> +</table> + +## All IO is now GIOStream-based + +Previously there were ways to allow libsoup to read data into buffers and for +you to read from those buffers such as `SoupMessage:response-body` +`SoupMessage:response-body-data`, and `SoupServerMessage::got-chunk`. + +libsoup no longer stores a buffer of data for you to read from and instead it +returns a class@Gio.InputStream which you read from using normal GIO APIs. + +If you want to simply request a buffer and nothing more you can use the +method@Session.send_and_read or method@Session.send_and_read_async APIs. + +This also applies to writing data where you can set a class@Gio.InputStream +using method@Message.set_request_body or use the convenience API +method@Message.set_request_body_from_bytes to use a struct@GLib.Bytes +buffer. + +## Clarification on thread-safety + +In libsoup 2 there was an attempt at making various APIs of the library +thread-safe. However this was never well tested, maintained, or documented. + + +libsoup 3 was initially designed to behave in line with other GObject libraries. Once you +create a class@Session all usage of that session must happen on the same +thread. However, in version 3.2 thread safety support was introduced +again, with the same approach as libsoup2.
View file
_service:tar_scm:libsoup-3.2.2.tar.xz/docs/reference/server-howto.md
Added
@@ -0,0 +1,247 @@ +Title: Server Basics +Slug: server-howto + +# Server Basics + +## Creating a SoupServer + +As with the client API, there is a single object that will encapsulate +most of your interactions with libsoup. In this case, class@Server. + +You create the server with ctor@Server.new, and as with the class@Session +constructor, you can specify a few additional options: + +<table> + <tr> + <td>property@Server:tls-certificate</td> + <td> + A class@Gio.TlsCertificate + (containing a private key) that will be used when handling + HTTPS requests on the server. + </td> + </tr> + <tr> + <td>property@Server:raw-paths</literal></td> + <td> + Set this to <tt>TRUE</tt> if you don't want + libsoup to decode %-encoding + in the Request-URI. (e.g. because you need to treat + <tt>"/foo/bar"</tt> and + <tt>"/foo%2Fbar"</tt> as different paths. + </td> + </tr> + <tr> + <td>property@Server:server-header</td> + <td> + Allows you to set a Server header string that will be sent + on all responses. + </td> + </tr> +</table> + +## Adding Listening Sockets + +To tell the server where to listen, call method@Server.listen (to listen on a +specific class@Gio.SocketAddress), method@Server.listen_all (to listen on a +given port on all network interfaces), or method@Server.listen_local (to +listen to a given port on the `loopback` interface only). You can call any of +these functions multiple times, to set up multiple listening sockets. + +To set up an HTTPS server, you must first either set the +property@Server:tls-certificate property, or else call +method@Server.set_tls_certificate. After that you can pass the +`SOUP_SERVER_LISTEN_HTTPS` option to method@Server.listen, etc. + +By default, servers listen for both IPv4 and IPv6 connections; if you don't want +this, use the `SOUP_SERVER_LISTEN_IPV4_ONLY` or `SOUP_SERVER_LISTEN_IPV6_ONLY` +options. + +The server runs asynchronously, in the thread-default struct@GLib.MainContext +of the thread in which the `listen` calls were made. + +## Adding Handlers + +By default, class@Server returns "404 Not Found" in response to all requests +(except ones that it can't parse, which get "400 Bad Request"). To override this +behavior, call class@Server.add_handler to set a callback to handle certain +URI paths. + +```c +soup_server_add_handler (server, "/foo", server_callback, + data, destroy_notify); +``` + +The `"/foo"` indicates the base path for this handler. When a request comes in, +if there is a handler registered for exactly the path in the request's +`Request-URI`, then that handler will be called. Otherwise libsoup will strip +path components one by one until it finds a matching handler. So for example, a +request of the form `GET /foo/bar/baz.html?a=1&b=2 HTTP/1.1` would look for +handlers for `/foo/bar/baz.html`, `/foo/bar`, and `/foo`. If a handler has been +registered with a `NULL` base path, then it is used as the default handler for +any request that doesn't match any other handler. + +## Responding to Requests + +A handler callback looks something like this: + +```c +static void +server_callback (SoupServer *server, + SoupServerMessage *msg, + const char *path, + GHashTable *query, + gpointer user_data) +{ + // ... +} +``` + +`msg` is the request that has been received and `user_data` is the data that was +passed to method@Server.add_handler. `path` is the path (from `msg`'s URI), +and `query` contains the result of parsing the URI query field. (It is `NULL` if +there was no query.) + +By default, libsoup assumes that you have completely finished processing the +message when you return from the callback, and that it can therefore begin +sending the response. If you are not ready to send a response immediately (e.g. +you have to contact another server, or wait for data from a database), you must +call method@Server.pause_message on the message before returning from the +callback. This will delay sending a response until you call +method@Server.unpause_message. (You must also connect to the +signal@ServerMessage::finished signal on the message in this case, so that you +can break off processing if the client unexpectedly disconnects before you start +sending the data.) + +To set the response status, call method@ServerMessage.set_status. If the +response requires a body, you must decide whether to use `Content-Length` +encoding (the default), or `chunked` encoding. + +## Responding with `Content-Length` Encoding + +This is the simpler way to set a response body, if you have all of the data +available at once. + +```c +static void +server_callback (SoupServer *server, + SoupServerMessage *msg, + const char *path, + GHashTable *query, + gpointer user_data) +{ + MyServerData *server_data = user_data; + const char *mime_type; + GByteArray *body; + + if (soup_server_message_get_method (msg) != SOUP_METHOD_GET) { + soup_server_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED, NULL); + return; + } + + /* This is somewhat silly. Presumably your server will do + * something more interesting. + */ + body = g_hash_table_lookup (server_data->bodies, path); + mime_type = g_hash_table_lookup (server_data->mime_types, path); + if (!body || !mime_type) { + soup_server_message_set_status (msg, SOUP_STATUS_NOT_FOUND, NULL); + return; + } + + soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL); + soup_server_message_set_response (msg, mime_type, SOUP_MEMORY_COPY, + body->data, body->len); +} +``` + +# Responding with `chunked` Encoding + +If you want to supply the response body in chunks as it becomes available, use +`chunked` encoding instead. In this case, first call +`soup_message_headers_set_encoding (msg->response_headers, +SOUP_ENCODING_CHUNKED)` to tell libsoup that you'll be using `chunked` encoding. +Then call method@MessageBody.append (or method@MessageBody.append_bytes) on +`msg->response_body` with each chunk of the response body as it becomes +available, and call method@MessageBody.complete when the response is complete. +After each of these calls, you must also call class@Server.unpause_message to +cause the chunk to be sent. (You do not normally need to call +method@Server.pause_message, because I/O is automatically paused when doing a +`chunked` transfer if no chunks are available.) + +When using chunked encoding, you must also connect to the +signal@ServerMessage::finished signal on the message, so that you will be +notified if the client disconnects between two chunks; class@Server will unref +the message if that happens, so you must stop adding new chunks to the response +at that point. (An alternate possibility is to write each new chunk only when +the signal@ServerMessage::wrote_chunk signal is emitted indicating that the +previous one was written successfully.) + +The **`simple-proxy`** example in the `examples/` directory gives an example of +using `chunked` encoding. + +## Handling Authentication + +To have class@Server handle HTTP authentication for you, create a +class@AuthDomainBasic or class@AuthDomainDigest, and pass it to +method@Server.add_auth_domain: + +```c +SoupAuthDomain *domain; + +domain = soup_auth_domain_basic_new ( + "realm", "My Realm", + "auth-callback", auth_callback, + "auth-data", auth_data, + "add-path", "/foo", + "add-path", "/bar/private", + NULL); +soup_server_add_auth_domain (server, domain); +g_object_unref (domain);
View file
_service:tar_scm:libsoup-3.2.2.tar.xz/docs/reference/urlmap.js
Added
@@ -0,0 +1,6 @@ +// A map between namespaces and base URLs for their online documentation +baseURLs = + 'GLib', 'https://docs.gtk.org/glib/' , + 'GObject', 'https://docs.gtk.org/gobject/' , + 'Gio', 'https://docs.gtk.org/gio/' , +
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/examples/simple-proxy.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/examples/simple-proxy.c
Changed
@@ -190,7 +190,7 @@ SOUP_MEMORY_COPY, error->message, strlen (error->message)); g_error_free (error); - soup_server_unpause_message (tunnel->self, tunnel->msg); + soup_server_message_unpause (tunnel->msg); tunnel_close (tunnel); return; } @@ -199,7 +199,7 @@ tunnel->server.ostream = g_io_stream_get_output_stream (tunnel->server.iostream); soup_server_message_set_status (tunnel->msg, SOUP_STATUS_OK, NULL); - soup_server_unpause_message (tunnel->self, tunnel->msg); + soup_server_message_unpause (tunnel->msg); g_signal_connect (tunnel->msg, "finished", G_CALLBACK (start_tunnel), tunnel); } @@ -211,7 +211,7 @@ GUri *dest_uri; GSocketClient *sclient; - soup_server_pause_message (server, msg); + soup_server_message_pause (msg); tunnel = g_new0 (Tunnel, 1); tunnel->self = g_object_ref (server); @@ -241,7 +241,7 @@ soup_message_headers_foreach (soup_message_get_response_headers (from), copy_header, soup_server_message_get_response_headers (to)); soup_message_headers_remove (soup_server_message_get_response_headers (to), "Content-Length"); - soup_server_unpause_message (server, to); + soup_server_message_unpause (to); } static void @@ -262,7 +262,7 @@ if (error) { g_print ("%p failed to read body: %s\n\n", server_msg, error->message); soup_server_message_set_status (server_msg, SOUP_STATUS_INTERNAL_SERVER_ERROR, NULL); - soup_server_unpause_message (server, server_msg); + soup_server_message_unpause (server_msg); g_error_free (error); return; } @@ -274,7 +274,7 @@ g_signal_handlers_disconnect_by_func (server_msg, client_msg_failed, client_cancellable); soup_message_body_complete (soup_server_message_get_response_body (server_msg)); - soup_server_unpause_message (server, server_msg); + soup_server_message_unpause (server_msg); g_object_unref (server_msg); return; } @@ -284,7 +284,7 @@ SoupMessageBody *body = soup_server_message_get_response_body (server_msg); soup_message_body_append_bytes (body, bytes); - soup_server_unpause_message (server, server_msg); + soup_server_message_unpause (server_msg); g_bytes_unref (bytes); @@ -303,7 +303,7 @@ if (error) { g_print ("%p failed to read body: %s\n\n", server_msg, error->message); soup_server_message_set_status (server_msg, SOUP_STATUS_INTERNAL_SERVER_ERROR, NULL); - soup_server_unpause_message (server, server_msg); + soup_server_message_unpause (server_msg); g_error_free (error); return; } @@ -365,7 +365,7 @@ // Keep the server message alive until the client one is finished g_object_ref (msg); - soup_server_pause_message (server, msg); + soup_server_message_pause (msg); } static gboolean
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/get_apache_modules_dirs.py -> _service:tar_scm:libsoup-3.2.2.tar.xz/get_apache_modules_dirs.py
Changed
@@ -27,13 +27,6 @@ import os import glob -def check_php_module(modules_path): - php_modules = glob.glob(os.path.join(modules_path, 'libphp7*.so')); - if len(php_modules): - # The last one in the sorted output will be the desired php module. - return sorted(php_modules)-1; - - def check_module(modules_path, module): module_path = os.path.join(modules_path, module) return os.path.isfile(module_path) @@ -52,7 +45,7 @@ 'mod_authz_user', 'mod_dir', 'mod_mime', - 'mod_mpm_prefork', + 'mod_mpm_event', 'mod_proxy', 'mod_proxy_http', 'mod_proxy_connect' @@ -105,8 +98,8 @@ apache_modules_dir = '' apache_ssl_module_dir = '' - apache_php_module_file = '' apache_mod_unixd_module_file = '' + apache_http2_module_dir = '' for lib_dir in 'lib', 'lib64': for httpd_dir in 'apache', 'apache2', 'http', 'http2', 'httpd': @@ -117,11 +110,10 @@ apache_modules_dir = modules_path if check_module(modules_path, 'mod_ssl.so'): apache_ssl_module_dir = modules_path - php_module = check_php_module(modules_path) - if (php_module): - apache_php_module_file = php_module if check_module(modules_path, 'mod_unixd.so'): apache_mod_unixd_module_file = modules_path + if check_module(modules_path, 'mod_http2.so'): + apache_http2_module_dir = modules_path # These two are mandatory for having properly configured Apache if apache_modules_dir == '' or apache_ssl_module_dir == '': @@ -129,8 +121,8 @@ print(apache_modules_dir + ":" + apache_ssl_module_dir + ":" + - apache_php_module_file + ":" + - apache_mod_unixd_module_file, end='') + apache_mod_unixd_module_file + ":" + + apache_http2_module_dir, end='') if __name__ == "__main__": main()
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup.doap -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup.doap
Changed
@@ -17,16 +17,9 @@ <maintainer> <foaf:Person> - <foaf:name>Dan Winship</foaf:name> - <foaf:mbox rdf:resource="mailto:danw@gnome.org" /> - <gnome:userid>danw</gnome:userid> - </foaf:Person> - </maintainer> - <maintainer> - <foaf:Person> - <foaf:name>Claudio Saavedra</foaf:name> - <foaf:mbox rdf:resource="mailto:csaavedra@igalia.com" /> - <gnome:userid>csaavedra</gnome:userid> + <foaf:name>Carlos Garcia Campos</foaf:name> + <foaf:mbox rdf:resource="mailto:cgarcia@igalia.com" /> + <gnome:userid>carlosgc</gnome:userid> </foaf:Person> </maintainer> <maintainer>
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/auth/soup-auth-basic.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/auth/soup-auth-basic.c
Changed
@@ -23,11 +23,12 @@ } SoupAuthBasicPrivate; /** - * SOUP_TYPE_AUTH_BASIC: + * SoupAuthBasic: * - * A #GType corresponding to HTTP "Basic" authentication. - * #SoupSessions support this by default; if you want to disable - * support for it, call soup_session_remove_feature_by_type(), + * HTTP "Basic" authentication. + * + * class@Sessions support this by default; if you want to disable + * support for it, call method@Session.remove_feature_by_type, * passing %SOUP_TYPE_AUTH_BASIC. * */
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/auth/soup-auth-digest.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/auth/soup-auth-digest.c
Changed
@@ -46,11 +46,12 @@ static void recompute_hex_a1 (SoupAuthDigestPrivate *priv); /** - * SOUP_TYPE_AUTH_DIGEST: + * SoupAuthDigest: * - * A #GType corresponding to HTTP "Digest" authentication. - * #SoupSessions support this by default; if you want to disable - * support for it, call soup_session_remove_feature_by_type(), + * HTTP "Digest" authentication. + * + * class@Sessions support this by default; if you want to disable + * support for it, call method@Session.remove_feature_by_type * passing %SOUP_TYPE_AUTH_DIGEST. * */
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/auth/soup-auth-manager.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/auth/soup-auth-manager.c
Changed
@@ -22,49 +22,28 @@ #include "soup-uri-utils-private.h" /** - * SECTION:soup-auth-manager - * @short_description: HTTP client-side authentication handler - * @see_also: #SoupSession, #SoupAuth + * SoupAuthManager: + * + * HTTP client-side authentication handler. * - * #SoupAuthManager is the #SoupSessionFeature that handles HTTP - * authentication for a #SoupSession. + * #SoupAuthManager is the iface@SessionFeature that handles HTTP + * authentication for a class@Session. * * A #SoupAuthManager is added to the session by default, and normally * you don't need to worry about it at all. However, if you want to * disable HTTP authentication, you can remove the feature from the - * session with soup_session_remove_feature_by_type(), or disable it on - * individual requests with soup_message_disable_feature(). - * - **/ - -/** - * SoupAuthManager: - * - * Class for managing client-side HTTP authentication. - */ - -/** - * SOUP_TYPE_AUTH_MANAGER: - * - * The #GType of #SoupAuthManager; you can use this with - * soup_session_remove_feature_by_type() or - * soup_message_disable_feature(). + * session with method@Session.remove_feature_by_type or disable it on + * individual requests with method@Message.disable_feature. * - * (Although this type has only been publicly visible since libsoup - * 2.42, it has always existed in the background, and you can use - * <literal><code>g_type_from_name ("SoupAuthManager")</code></literal> - * to get its #GType in earlier releases.) + * You can use this with method@Session.remove_feature_by_type or + * method@Message.disable_feature. * - */ + * (Although this type has only been publicly visible since libsoup 2.42, it has + * always existed in the background, and you can use `g_type_from_name + * ("SoupAuthManager")` to get its alias@GLib.Type in earlier releases.) + **/ static void soup_auth_manager_session_feature_init (SoupSessionFeatureInterface *feature_interface, gpointer interface_data); -enum { - AUTHENTICATE, - LAST_SIGNAL -}; - -static guint signalsLAST_SIGNAL = { 0 }; - struct _SoupAuthManager { GObject parent_instance; }; @@ -75,6 +54,7 @@ gboolean auto_ntlm; SoupAuth *proxy_auth; + GMutex mutex; GHashTable *auth_hosts; } SoupAuthManagerPrivate; @@ -104,6 +84,7 @@ soup_uri_host_equal, NULL, (GDestroyNotify)soup_auth_host_free); + g_mutex_init (&priv->mutex); } static void @@ -117,6 +98,8 @@ g_clear_object (&priv->proxy_auth); + g_mutex_clear (&priv->mutex); + G_OBJECT_CLASS (soup_auth_manager_parent_class)->finalize (object); } @@ -126,33 +109,6 @@ GObjectClass *object_class = G_OBJECT_CLASS (auth_manager_class); object_class->finalize = soup_auth_manager_finalize; - - /** - * SoupAuthManager::authenticate: - * @manager: the #SoupAuthManager - * @msg: the #SoupMessage being sent - * @auth: the #SoupAuth to authenticate - * @retrying: %TRUE if this is the second (or later) attempt - * - * Emitted when the manager requires the application to - * provide authentication credentials. - * - * #SoupMessage connects to this signal and emits its own - * #SoupMessage::authenticate signal when it is emitted, so - * you shouldn't need to use this signal directly. - */ - signalsAUTHENTICATE = - g_signal_new ("authenticate", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, - NULL, NULL, - NULL, - G_TYPE_NONE, 3, - SOUP_TYPE_MESSAGE, - SOUP_TYPE_AUTH, - G_TYPE_BOOLEAN); - } static int @@ -454,15 +410,18 @@ make_auto_ntlm_auth (SoupAuthManagerPrivate *priv, SoupAuthHost *host) { SoupAuth *auth; + char *authority; if (!priv->auto_ntlm) return FALSE; + authority = g_strdup_printf ("%s:%d", g_uri_get_host (host->uri), g_uri_get_port (host->uri)); auth = g_object_new (SOUP_TYPE_AUTH_NTLM, - "host", g_uri_get_host (host->uri), + "authority", authority, NULL); record_auth_for_uri (priv, host->uri, auth, FALSE); g_object_unref (auth); + g_free (authority); return TRUE; } @@ -661,6 +620,8 @@ SoupAuth *auth, *prior_auth; gboolean prior_auth_failed = FALSE; + g_mutex_lock (&priv->mutex); + /* See if we used auth last time */ prior_auth = soup_message_get_auth (msg); if (prior_auth && check_auth (msg, prior_auth)) { @@ -669,8 +630,10 @@ prior_auth_failed = TRUE; } else { auth = create_auth (priv, msg); - if (!auth) + if (!auth) { + g_mutex_unlock (&priv->mutex); return; + } } if (!soup_message_query_flags (msg, SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE)) { @@ -682,6 +645,8 @@ auth = g_object_ref (new_auth); } + g_mutex_unlock (&priv->mutex); + /* If we need to authenticate, try to do it. */ authenticate_auth (manager, auth, msg, prior_auth_failed, FALSE, TRUE); @@ -695,6 +660,8 @@ SoupAuthManagerPrivate *priv = soup_auth_manager_get_instance_private (manager); SoupAuth *auth; + g_mutex_lock (&priv->mutex); + auth = lookup_auth (priv, msg); if (auth && soup_auth_is_ready (auth, msg)) { if (SOUP_IS_CONNECTION_AUTH (auth)) @@ -708,6 +675,8 @@ soup_session_requeue_message (priv->session, msg); } + + g_mutex_unlock (&priv->mutex); } static void @@ -717,6 +686,8 @@ SoupAuth *auth = NULL, *prior_auth; gboolean prior_auth_failed = FALSE; + g_mutex_lock (&priv->mutex); + /* See if we used auth last time */ prior_auth = soup_message_get_proxy_auth (msg); if (prior_auth && check_auth (msg, prior_auth)) { @@ -729,13 +700,17 @@
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/auth/soup-auth-negotiate.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/auth/soup-auth-negotiate.c
Changed
@@ -27,11 +27,13 @@ /** * soup_auth_negotiate_supported: * - * Indicates whether libsoup was built with GSSAPI support. If this is - * %FALSE, %SOUP_TYPE_AUTH_NEGOTIATE will still be defined and can - * still be added to a #SoupSession, but libsoup will never attempt to + * Indicates whether libsoup was built with GSSAPI support. + * + * If this is %FALSE, %SOUP_TYPE_AUTH_NEGOTIATE will still be defined and can + * still be added to a class@Session, but libsoup will never attempt to * actually use this auth type. * + * Returns: %TRUE if supported otherwise %FALSE */ gboolean soup_auth_negotiate_supported (void) @@ -76,17 +78,18 @@ } SoupAuthNegotiatePrivate; /** - * SOUP_TYPE_AUTH_NEGOTIATE: + * SoupAuthNegotiate: + * + * HTTP-based GSS-Negotiate authentication, as defined by + * RFC 4559(https://datatracker.ietf.org/doc/html/rfc4559). * - * A #GType corresponding to HTTP-based GSS-Negotiate authentication. - * #SoupSessions do not support this type by default; if you want to - * enable support for it, call soup_session_add_feature_by_type(), + * class@Sessions do not support this type by default; if you want to + * enable support for it, call method@Session.add_feature_by_type, * passing %SOUP_TYPE_AUTH_NEGOTIATE. * * This auth type will only work if libsoup was compiled with GSSAPI - * support; you can check soup_auth_negotiate_supported() to see if it + * support; you can check func@AuthNegotiate.supported to see if it * was. - * */ G_DEFINE_FINAL_TYPE_WITH_PRIVATE (SoupAuthNegotiate, soup_auth_negotiate, SOUP_TYPE_CONNECTION_AUTH) @@ -361,9 +364,20 @@ auth_headers = soup_message_headers_get_one_common (soup_message_get_response_headers (msg), SOUP_HEADER_WWW_AUTHENTICATE); if (!auth_headers || g_ascii_strncasecmp (auth_headers, "Negotiate ", 10) != 0) { - g_warning ("Failed to parse auth header"); + if (soup_message_get_status (msg) == SOUP_STATUS_OK) { + /* The server *may* supply final authentication data to + * the client, but doesn't have to. We are not + * authenticating the server, so just ignore missing + * auth data. In practice, this is required for web + * compat. + */ + priv->is_authenticated = TRUE; + return; + } + + g_warning ("Server bug: missing or invalid WWW-Authenticate header: %s", auth_headers); conn->state = SOUP_NEGOTIATE_FAILED; - goto out; + return; } ret = soup_gss_client_step (conn, auth_headers + 10, &error_message); @@ -393,7 +407,7 @@ default: conn->state = SOUP_NEGOTIATE_FAILED; } - out: + g_clear_pointer (&error_message, g_free); } @@ -584,7 +598,7 @@ &conn->context, conn->server_name, (gss_OID) &gss_mech_spnego, - GSS_C_MUTUAL_FLAG, + 0, GSS_C_INDEFINITE, GSS_C_NO_CHANNEL_BINDINGS, &in,
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/auth/soup-auth-ntlm.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/auth/soup-auth-ntlm.c
Changed
@@ -99,13 +99,13 @@ #endif /** - * SOUP_TYPE_AUTH_NTLM: + * SoupAuthNTLM: * - * A #GType corresponding to HTTP-based NTLM authentication. - * #SoupSessions do not support this type by default; if you want to - * enable support for it, call soup_session_add_feature_by_type(), - * passing %SOUP_TYPE_AUTH_NTLM. + * HTTP-based NTLM authentication. * + * class@Sessions do not support this type by default; if you want to + * enable support for it, call method@Session.add_feature_by_type, + * passing %SOUP_TYPE_AUTH_NTLM. */ G_DEFINE_FINAL_TYPE_WITH_PRIVATE (SoupAuthNTLM, soup_auth_ntlm, SOUP_TYPE_CONNECTION_AUTH) @@ -758,12 +758,14 @@ return FALSE; } + g_free (*default_domain); *default_domain = g_convert ((char *)chall + domain.offset, domain.length, "UTF-8", "UCS-2LE", NULL, NULL, NULL); } if (nonce) { + g_free (*nonce); *nonce = g_memdup2 (chall + NTLM_CHALLENGE_NONCE_OFFSET, NTLM_CHALLENGE_NONCE_LENGTH); } @@ -777,6 +779,7 @@ g_free (chall); return FALSE; } + g_free (*target_info); *target_info = g_memdup2 (chall + target.offset, target.length); *target_info_sz = target.length; }
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/auth/soup-auth.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/auth/soup-auth.c
Changed
@@ -18,22 +18,16 @@ #include "soup-uri-utils-private.h" /** - * SECTION:soup-auth - * @short_description: HTTP client-side authentication support - * @see_also: #SoupSession - * - * #SoupAuth objects store the authentication data associated with a - * given bit of web space. They are created automatically by - * #SoupSession. - **/ - -/** * SoupAuth: * - * The abstract base class for handling authentication. Specific HTTP - * Authentication mechanisms are implemented by its subclasses, but - * applications never need to be aware of the specific subclasses - * being used. + * The abstract base class for handling authentication. + * + * Specific HTTP Authentication mechanisms are implemented by its subclasses, + * but applications never need to be aware of the specific subclasses being + * used. + * + * #SoupAuth objects store the authentication data associated with a given bit + * of web space. They are created automatically by class@Session. **/ typedef struct { @@ -166,7 +160,7 @@ /* properties */ /** - * SoupAuth:scheme-name: + * SoupAuth:scheme-name: (attributes org.gtk.Property.get=soup_auth_get_scheme_name) * * The authentication scheme name. **/ @@ -178,7 +172,7 @@ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); /** - * SoupAuth:realm: + * SoupAuth:realm: (attributes org.gtk.Property.get=soup_auth_get_realm) * * The authentication realm. **/ @@ -190,7 +184,7 @@ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** - * SoupAuth:authority: + * SoupAuth:authority: (attributes org.gtk.Property.get=soup_auth_get_authority) * * The authority (host:port) being authenticated to. **/ @@ -202,7 +196,7 @@ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** - * SoupAuth:is-for-proxy: + * SoupAuth:is-for-proxy: (attributes org.gtk.Property.get=soup_auth_is_for_proxy) * * Whether or not the auth is for a proxy server. **/ @@ -214,7 +208,7 @@ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** - * SoupAuth:is-authenticated: + * SoupAuth:is-authenticated: (attributes org.gtk.Property.get=soup_auth_is_authenticated) * * Whether or not the auth has been authenticated. **/ @@ -226,10 +220,9 @@ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); /** - * SoupAuth:is-cancelled: + * SoupAuth:is-cancelled: (attributes org.gtk.Property.get=soup_auth_is_cancelled) * - * An alias for the #SoupAuth:is-cancelled property. - * (Whether or not the auth has been cancelled.) + * Whether or not the auth has been cancelled. **/ propertiesPROP_IS_CANCELLED = g_param_spec_boolean ("is-cancelled", @@ -251,11 +244,11 @@ * Creates a new #SoupAuth of type @type with the information from * @msg and @auth_header. * - * This is called by #SoupSession; you will normally not create auths + * This is called by class@Session; you will normally not create auths * yourself. * * Returns: (nullable): the new #SoupAuth, or %NULL if it could - * not be created + * not be created **/ SoupAuth * soup_auth_new (GType type, SoupMessage *msg, const char *auth_header) @@ -310,12 +303,13 @@ * @auth_header: the WWW-Authenticate/Proxy-Authenticate header * * Updates @auth with the information from @msg and @auth_header, - * possibly un-authenticating it. As with soup_auth_new(), this is - * normally only used by #SoupSession. + * possibly un-authenticating it. + * + * As with ctor@Auth.new, this is normally only used by class@Session. * * Returns: %TRUE if @auth is still a valid (but potentially - * unauthenticated) #SoupAuth. %FALSE if something about @auth_params - * could not be parsed or incorporated into @auth at all. + * unauthenticated) #SoupAuth. %FALSE if something about @auth_params + * could not be parsed or incorporated into @auth at all. **/ gboolean soup_auth_update (SoupAuth *auth, SoupMessage *msg, const char *auth_header) @@ -360,8 +354,10 @@ * @username: the username provided by the user or client * @password: the password provided by the user or client * - * Call this on an auth to authenticate it; normally this will cause - * the auth's message to be requeued with the new authentication info. + * Call this on an auth to authenticate it. + * + * Normally this will cause the auth's message to be requeued with the new + * authentication info. **/ void soup_auth_authenticate (SoupAuth *auth, const char *username, const char *password) @@ -387,9 +383,10 @@ * soup_auth_cancel: * @auth: a #SoupAuth * - * Call this on an auth to cancel it. You need to cancel an auth to complete - * an asynchronous authenticate operation when no credentials are provided - * (soup_auth_authenticate() is not called). + * Call this on an auth to cancel it. + * + * You need to cancel an auth to complete an asynchronous authenticate operation + * when no credentials are provided (method@Auth.authenticate is not called). * The #SoupAuth will be cancelled on dispose if it hans't been authenticated. */ void @@ -408,7 +405,7 @@ } /** - * soup_auth_is_for_proxy: + * soup_auth_is_for_proxy: (attributes org.gtk.Method.get_property=is-for-proxy) * @auth: a #SoupAuth * * Tests whether or not @auth is associated with a proxy server rather @@ -428,6 +425,7 @@ /** * soup_auth_get_scheme_name: + * soup_auth_get_scheme_name: (attributes org.gtk.Method.get_property=scheme-name) * @auth: a #SoupAuth * * Returns @auth's scheme name. (Eg, "Basic", "Digest", or "NTLM") @@ -443,7 +441,7 @@ } /** - * soup_auth_get_authority: + * soup_auth_get_authority: (attributes org.gtk.Method.get_property=authority) * @auth: a #SoupAuth * * Returns the authority (host:port) that @auth is associated with. @@ -461,13 +459,14 @@ } /** - * soup_auth_get_realm: + * soup_auth_get_realm: (attributes org.gtk.Method.get_property=realm) * @auth: a #SoupAuth * - * Returns @auth's realm. This is an identifier that distinguishes - * separate authentication spaces on a given server, and may be some - * string that is meaningful to the user. (Although it is probably not - * localized.) + * Returns @auth's realm. + * + * This is an identifier that distinguishes separate authentication spaces on a + * given server, and may be some string that is meaningful to the user. + * (Although it is probably not localized.) * * Returns: the realm name **/ @@ -485,10 +484,12 @@ * soup_auth_get_info: * @auth: a #SoupAuth * - * Gets an opaque identifier for @auth, for use as a hash key or the - * like. #SoupAuth objects from the same server with the same
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/auth/soup-connection-auth.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/auth/soup-connection-auth.c
Changed
@@ -100,16 +100,17 @@ conn = soup_message_get_connection (msg); state = g_hash_table_lookup (priv->conns, conn); - if (state) - return state; + if (!state) { + state = SOUP_CONNECTION_AUTH_GET_CLASS (auth)->create_connection_state (auth); + if (conn) { + g_signal_connect (conn, "disconnected", + G_CALLBACK (connection_disconnected), auth); + } - state = SOUP_CONNECTION_AUTH_GET_CLASS (auth)->create_connection_state (auth); - if (conn) { - g_signal_connect (conn, "disconnected", - G_CALLBACK (connection_disconnected), auth); - } + g_hash_table_insert (priv->conns, conn, state); + } + g_clear_object (&conn); - g_hash_table_insert (priv->conns, conn, state); return state; }
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/auth/soup-tls-interaction.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/auth/soup-tls-interaction.c
Changed
@@ -16,7 +16,7 @@ }; typedef struct { - SoupConnection *conn; + GWeakRef conn; } SoupTlsInteractionPrivate; G_DEFINE_FINAL_TYPE_WITH_PRIVATE (SoupTlsInteraction, soup_tls_interaction, G_TYPE_TLS_INTERACTION) @@ -31,12 +31,15 @@ { SoupTlsInteractionPrivate *priv = soup_tls_interaction_get_instance_private (SOUP_TLS_INTERACTION (tls_interaction)); GTask *task; + SoupConnection *conn = g_weak_ref_get (&priv->conn); task = g_task_new (tls_interaction, cancellable, callback, user_data); - if (priv->conn) - soup_connection_request_tls_certificate (priv->conn, connection, task); - else + if (conn) { + soup_connection_request_tls_certificate (conn, connection, task); + g_object_unref (conn); + } else { g_task_return_int (task, G_TLS_INTERACTION_FAILED); + } g_object_unref (task); } @@ -60,12 +63,15 @@ { SoupTlsInteractionPrivate *priv = soup_tls_interaction_get_instance_private (SOUP_TLS_INTERACTION (tls_interaction)); GTask *task; + SoupConnection *conn = g_weak_ref_get (&priv->conn); task = g_task_new (tls_interaction, cancellable, callback, user_data); - if (priv->conn) - soup_connection_request_tls_certificate_password (priv->conn, password, task); - else + if (conn) { + soup_connection_request_tls_certificate_password (conn, password, task); + g_object_unref (conn); + } else { g_task_return_int (task, G_TLS_INTERACTION_FAILED); + } g_object_unref (task); } @@ -85,10 +91,7 @@ { SoupTlsInteractionPrivate *priv = soup_tls_interaction_get_instance_private (SOUP_TLS_INTERACTION (object)); - if (priv->conn) { - g_object_remove_weak_pointer (G_OBJECT (priv->conn), (gpointer*)&priv->conn); - priv->conn = NULL; - } + g_weak_ref_clear (&priv->conn); G_OBJECT_CLASS (soup_tls_interaction_parent_class)->finalize (object); } @@ -96,6 +99,9 @@ static void soup_tls_interaction_init (SoupTlsInteraction *interaction) { + SoupTlsInteractionPrivate *priv = soup_tls_interaction_get_instance_private (interaction); + + g_weak_ref_init (&priv->conn, NULL); } static void @@ -120,8 +126,7 @@ interaction = g_object_new (SOUP_TYPE_TLS_INTERACTION, NULL); priv = soup_tls_interaction_get_instance_private (SOUP_TLS_INTERACTION (interaction)); - priv->conn = conn; - g_object_add_weak_pointer (G_OBJECT (priv->conn), (gpointer*)&priv->conn); + g_weak_ref_set (&priv->conn, conn); return interaction; }
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/cache/soup-cache-private.h -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/cache/soup-cache-private.h
Changed
@@ -27,6 +27,12 @@ G_BEGIN_DECLS +typedef enum { + SOUP_CACHE_RESPONSE_FRESH, + SOUP_CACHE_RESPONSE_NEEDS_VALIDATION, + SOUP_CACHE_RESPONSE_STALE +} SoupCacheResponse; + SoupCacheResponse soup_cache_has_response (SoupCache *cache, SoupMessage *msg); GInputStream *soup_cache_send_response (SoupCache *cache,
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/cache/soup-cache.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/cache/soup-cache.c
Changed
@@ -47,16 +47,19 @@ #include "soup-session-feature-private.h" /** - * SECTION:soup-cache - * @short_description: Caching support + * SoupCache: * - * #SoupCache implements a file-based cache for HTTP resources. + * File-based cache for HTTP resources. */ /** - * SoupCache: + * SoupCacheability: + * @SOUP_CACHE_CACHEABLE: The message should be cached + * @SOUP_CACHE_UNCACHEABLE: The message shouldn't be cached + * @SOUP_CACHE_INVALIDATES: The messages cache should be invalidated + * @SOUP_CACHE_VALIDATES: The messages cache should be updated * - * Class implementing caching for HTTP resources. + * Indicates if a message should or shouldn't be cached. */ static void soup_cache_session_feature_init (SoupSessionFeatureInterface *feature_interface, gpointer interface_data); @@ -120,6 +123,7 @@ typedef struct { char *cache_dir; + GMutex mutex; GHashTable *cache; guint n_pending; SoupSession *session; @@ -540,8 +544,10 @@ g_assert (!entry->dirty); g_assert (g_list_length (priv->lru_start) == g_hash_table_size (priv->cache)); - if (!g_hash_table_remove (priv->cache, GUINT_TO_POINTER (entry->key))) + if (!g_hash_table_remove (priv->cache, GUINT_TO_POINTER (entry->key))) { + g_mutex_unlock (&priv->mutex); return FALSE; + } /* Remove from LRU */ lru_item = g_list_find (priv->lru_start, entry); @@ -709,7 +715,9 @@ soup_message_set_metrics_timestamp (msg, SOUP_MESSAGE_METRICS_REQUEST_START); + g_mutex_lock (&priv->mutex); entry = soup_cache_entry_lookup (cache, msg); + g_mutex_unlock (&priv->mutex); g_return_val_if_fail (entry, NULL); file = get_file_from_entry (cache, entry); @@ -812,6 +820,8 @@ SoupCachePrivate *priv = soup_cache_get_instance_private (cache); SoupCacheEntry *entry = helper->entry; + g_mutex_lock (&priv->mutex); + --priv->n_pending; entry->dirty = FALSE; @@ -840,6 +850,7 @@ } cleanup: + g_mutex_unlock (&priv->mutex); g_object_unref (helper->cache); g_slice_free (StreamHelper, helper); } @@ -859,6 +870,8 @@ StreamHelper *helper; time_t request_time, response_time; + g_mutex_lock (&priv->mutex); + /* First of all, check if we should cache the resource. */ cacheability = soup_cache_get_cacheability (cache, msg); entry = soup_cache_entry_lookup (cache, msg); @@ -866,6 +879,7 @@ if (cacheability & SOUP_CACHE_INVALIDATES) { if (entry) soup_cache_entry_remove (cache, entry, TRUE); + g_mutex_unlock (&priv->mutex); return NULL; } @@ -877,15 +891,20 @@ */ if (entry) soup_cache_update_from_conditional_request (cache, msg); + g_mutex_unlock (&priv->mutex); return NULL; } - if (!(cacheability & SOUP_CACHE_CACHEABLE)) + if (!(cacheability & SOUP_CACHE_CACHEABLE)) { + g_mutex_unlock (&priv->mutex); return NULL; + } /* Check if we are already caching this resource */ - if (entry && (entry->dirty || entry->being_validated)) + if (entry && (entry->dirty || entry->being_validated)) { + g_mutex_unlock (&priv->mutex); return NULL; + } /* Create a new entry, deleting any old one if present */ if (entry) @@ -900,12 +919,15 @@ /* Do not continue if it can not be stored */ if (!soup_cache_entry_insert (cache, entry, TRUE)) { soup_cache_entry_free (entry); + g_mutex_unlock (&priv->mutex); return NULL; } entry->cancellable = g_cancellable_new (); ++priv->n_pending; + g_mutex_unlock (&priv->mutex); + helper = g_slice_new (StreamHelper); helper->cache = g_object_ref (cache); helper->entry = entry; @@ -946,6 +968,8 @@ priv->max_size = DEFAULT_MAX_SIZE; priv->max_entry_data_size = priv->max_size / MAX_ENTRY_DATA_PERCENTAGE; priv->size = 0; + + g_mutex_init (&priv->mutex); } static void @@ -971,6 +995,8 @@ g_list_free (priv->lru_start); + g_mutex_clear (&priv->mutex); + G_OBJECT_CLASS (soup_cache_parent_class)->finalize (object); } @@ -1036,6 +1062,10 @@ cache_class->get_cacheability = get_cacheability; + /** + * SoupCache:cache-dir: + * The directory to store the cache files. + */ propertiesPROP_CACHE_DIR = g_param_spec_string ("cache-dir", "Cache directory", @@ -1044,6 +1074,10 @@ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + /** + * SoupCache:cache-type: + * Whether the cache is private or shared. + */ propertiesPROP_CACHE_TYPE = g_param_spec_enum ("cache-type", "Cache type", @@ -1110,13 +1144,17 @@ int max_age, max_stale, min_fresh; GList *lru_item, *item; + g_mutex_lock (&priv->mutex); + entry = soup_cache_entry_lookup (cache, msg); /* 1. The presented Request-URI and that of stored response * match */ - if (!entry) + if (!entry) { + g_mutex_unlock (&priv->mutex); return SOUP_CACHE_RESPONSE_STALE; + } /* Increase hit count. Take sorting into account */ entry->hits++; @@ -1132,6 +1170,8 @@ g_list_free (lru_item); } + g_mutex_unlock (&priv->mutex); + if (entry->dirty || entry->being_validated) return SOUP_CACHE_RESPONSE_STALE; @@ -1255,8 +1295,8 @@ * * Calculates whether the @msg can be cached or not. *
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/cache/soup-cache.h -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/cache/soup-cache.h
Changed
@@ -38,12 +38,6 @@ } SoupCacheability; typedef enum { - SOUP_CACHE_RESPONSE_FRESH, - SOUP_CACHE_RESPONSE_NEEDS_VALIDATION, - SOUP_CACHE_RESPONSE_STALE -} SoupCacheResponse; - -typedef enum { SOUP_CACHE_SINGLE_USER, SOUP_CACHE_SHARED } SoupCacheType;
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/content-decoder/soup-content-decoder.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/content-decoder/soup-content-decoder.c
Changed
@@ -21,8 +21,9 @@ #endif /** - * SECTION:soup-content-decoder - * @short_description: Content-Encoding handler + * SoupContentDecoder: + * + * Handles decoding of HTTP messages. * * #SoupContentDecoder handles adding the "Accept-Encoding" header on * outgoing messages, and processing the "Content-Encoding" header on @@ -31,7 +32,7 @@ * * A #SoupContentDecoder will automatically be * added to the session by default. (You can use - * soup_session_remove_feature_by_type() if you don't + * method@Session.remove_feature_by_type if you don't * want this.) * * If #SoupContentDecoder successfully decodes the Content-Encoding, @@ -46,15 +47,8 @@ * (Note that currently there is no way to (automatically) use * Content-Encoding when sending a request body, or to pick specific * encoding types to support.) - * **/ -/** - * SoupContentDecoder: - * - * Class handling decoding of HTTP messages. - */ - struct _SoupContentDecoder { GObject parent; };
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/content-sniffer/soup-content-sniffer.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/content-sniffer/soup-content-sniffer.c
Changed
@@ -24,24 +24,18 @@ #include "soup-session-feature-private.h" /** - * SECTION:soup-content-sniffer - * @short_description: Content sniffing for SoupSession + * SoupContentSniffer: + * + * Sniffs the mime type of messages. * * A #SoupContentSniffer tries to detect the actual content type of * the files that are being downloaded by looking at some of the data - * before the #SoupMessage emits its #SoupMessage::got-headers signal. - * #SoupContentSniffer implements #SoupSessionFeature, so you can add - * content sniffing to a session with soup_session_add_feature() or - * soup_session_add_feature_by_type(). - * + * before the class@Message emits its signal@Message::got-headers signal. + * #SoupContentSniffer implements iface@SessionFeature, so you can add + * content sniffing to a session with method@Session.add_feature or + * method@Session.add_feature_by_type. **/ -/** - * SoupContentSniffer: - * - * Class that attempts to sniff the mime type of messages. - */ - static void soup_content_sniffer_session_feature_init (SoupSessionFeatureInterface *feature_interface, gpointer interface_data); static SoupContentProcessorInterface *soup_content_sniffer_default_content_processor_interface; @@ -787,13 +781,13 @@ * @params: (element-type utf8 utf8) (out) (transfer full) (nullable): return * location for Content-Type parameters (eg, "charset"), or %NULL * - * Sniffs @buffer to determine its Content-Type. The result may also - * be influenced by the Content-Type declared in @msg's response - * headers. + * Sniffs @buffer to determine its Content-Type. * - * Returns: the sniffed Content-Type of @buffer; this will never be %NULL, - * but may be "application/octet-stream". + * The result may also be influenced by the Content-Type declared in @msg's + * response headers. * + * Returns: the sniffed Content-Type of @buffer; this will never be %NULL, + * but may be `application/octet-stream`. */ char * soup_content_sniffer_sniff (SoupContentSniffer *sniffer, SoupMessage *msg, @@ -901,7 +895,6 @@ * Creates a new #SoupContentSniffer. * * Returns: a new #SoupContentSniffer - * **/ SoupContentSniffer * soup_content_sniffer_new (void)
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/cookies/soup-cookie-jar-db.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/cookies/soup-cookie-jar-db.c
Changed
@@ -19,23 +19,18 @@ #include "soup.h" /** - * SECTION:soup-cookie-jar-db - * @short_description: Database-based Cookie Jar + * SoupCookieJarDB: + * + * Database-based Cookie Jar. * - * #SoupCookieJarDB is a #SoupCookieJar that reads cookies from and - * writes them to a sqlite database in the new Mozilla format. + * #SoupCookieJarDB is a class@CookieJar that reads cookies from and writes + * them to a sqlite database in the new Mozilla format. * - * (This is identical to <literal>SoupCookieJarSqlite</literal> in + * (This is identical to `SoupCookieJarSqlite` in * libsoup-gnome; it has just been moved into libsoup proper, and * renamed to avoid conflicting.) **/ -/** - * SoupCookieJarDB: - * - * Subclass of #SoupCookieJar that stores cookies in a sqlite database. - */ - enum { PROP_0, @@ -119,15 +114,13 @@ * * Creates a #SoupCookieJarDB. * - * @filename will be read in at startup to create an initial set of - * cookies. If @read_only is %FALSE, then the non-session cookies will - * be written to @filename when the 'changed' signal is emitted from - * the jar. (If @read_only is %TRUE, then the cookie jar will only be - * used for this session, and changes made to it will be lost when the - * jar is destroyed.) + * @filename will be read in at startup to create an initial set of cookies. If + * @read_only is %FALSE, then the non-session cookies will be written to + * @filename when the signal@CookieJar::changed signal is emitted from the + * jar. (If @read_only is %TRUE, then the cookie jar will only be used for this + * session, and changes made to it will be lost when the jar is destroyed.) * * Returns: the new #SoupCookieJar - * **/ SoupCookieJar * soup_cookie_jar_db_new (const char *filename, gboolean read_only) @@ -339,6 +332,11 @@ object_class->set_property = soup_cookie_jar_db_set_property; object_class->get_property = soup_cookie_jar_db_get_property; + /** + * SoupCookieJarDB:filename: + * + * Cookie-storage filename. + */ propertiesPROP_FILENAME = g_param_spec_string ("filename", "Filename",
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/cookies/soup-cookie-jar-text.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/cookies/soup-cookie-jar-text.c
Changed
@@ -17,18 +17,13 @@ #include "soup.h" /** - * SECTION:soup-cookie-jar-text - * @short_description: Text-file-based ("cookies.txt") Cookie Jar - * - * #SoupCookieJarText is a #SoupCookieJar that reads cookies from and - * writes them to a text file in format similar to Mozilla's "cookies.txt". - **/ - -/** * SoupCookieJarText: * - * Subclass of #SoupCookieJar that stores cookies in a text file. - */ + * Text-file-based ("cookies.txt") Cookie Jar + * + * #SoupCookieJarText is a class@CookieJar that reads cookies from and writes + * them to a text file in format similar to Mozilla's "cookies.txt". + **/ enum { PROP_0, @@ -113,15 +108,13 @@ * * Creates a #SoupCookieJarText. * - * @filename will be read in at startup to create an initial set of - * cookies. If @read_only is %FALSE, then the non-session cookies will - * be written to @filename when the 'changed' signal is emitted from - * the jar. (If @read_only is %TRUE, then the cookie jar will only be - * used for this session, and changes made to it will be lost when the - * jar is destroyed.) + * @filename will be read in at startup to create an initial set of cookies. If + * @read_only is %FALSE, then the non-session cookies will be written to + * @filename when the signal@CookieJar::changed signal is emitted from the + * jar. (If @read_only is %TRUE, then the cookie jar will only be used for this + * session, and changes made to it will be lost when the jar is destroyed.) * * Returns: the new #SoupCookieJar - * **/ SoupCookieJar * soup_cookie_jar_text_new (const char *filename, gboolean read_only) @@ -394,6 +387,11 @@ object_class->set_property = soup_cookie_jar_text_set_property; object_class->get_property = soup_cookie_jar_text_get_property; + /** + * SoupCookieJarText:filename: + * + * Cookie-storage filename. + */ propertiesPROP_FILENAME = g_param_spec_string ("filename", "Filename",
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/cookies/soup-cookie-jar.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/cookies/soup-cookie-jar.c
Changed
@@ -21,25 +21,19 @@ #include "soup-uri-utils-private.h" /** - * SECTION:soup-cookie-jar - * @short_description: Automatic cookie handling for SoupSession + * SoupCookieJar: + * + * Automatic cookie handling for SoupSession. * - * A #SoupCookieJar stores #SoupCookie<!-- -->s and arrange for them - * to be sent with the appropriate #SoupMessage<!-- -->s. - * #SoupCookieJar implements #SoupSessionFeature, so you can add a - * cookie jar to a session with soup_session_add_feature() or - * soup_session_add_feature_by_type(). + * A #SoupCookieJar stores struct@Cookies and arrange for them to be sent with + * the appropriate class@Messages. #SoupCookieJar implements + * iface@SessionFeature, so you can add a cookie jar to a session with + * method@Session.add_feature or method@Session.add_feature_by_type. * * Note that the base #SoupCookieJar class does not support any form * of long-term cookie persistence. **/ -/** - * SoupCookieJar: - * - * Class that stores cookies in memory. - */ - enum { CHANGED, LAST_SIGNAL @@ -59,6 +53,7 @@ static GParamSpec *propertiesLAST_PROPERTY = { NULL, }; typedef struct { + GMutex mutex; gboolean constructed, read_only; GHashTable *domains, *serials; guint serial; @@ -82,6 +77,7 @@ g_free, NULL); priv->serials = g_hash_table_new (NULL, NULL); priv->accept_policy = SOUP_COOKIE_JAR_ACCEPT_ALWAYS; + g_mutex_init (&priv->mutex); } static void @@ -106,6 +102,7 @@ soup_cookies_free (value); g_hash_table_destroy (priv->domains); g_hash_table_destroy (priv->serials); + g_mutex_clear (&priv->mutex); G_OBJECT_CLASS (soup_cookie_jar_parent_class)->finalize (object); } @@ -174,7 +171,9 @@ * @old_cookie: the old #SoupCookie value * @new_cookie: the new #SoupCookie value * - * Emitted when @jar changes. If a cookie has been added, + * Emitted when @jar changes. + * + * If a cookie has been added, * @new_cookie will contain the newly-added cookie and * @old_cookie will be %NULL. If a cookie has been deleted, * @old_cookie will contain the to-be-deleted cookie and @@ -193,6 +192,11 @@ SOUP_TYPE_COOKIE | G_SIGNAL_TYPE_STATIC_SCOPE, SOUP_TYPE_COOKIE | G_SIGNAL_TYPE_STATIC_SCOPE); + /** + * SoupCookieJar:read-only: + * + * Whether or not the cookie jar is read-only. + */ propertiesPROP_READ_ONLY = g_param_spec_boolean ("read-only", "Read-only", @@ -202,10 +206,9 @@ G_PARAM_STATIC_STRINGS); /** - * SoupCookieJar:accept-policy: - * - * The policy the jar should follow to accept or reject cookies + * SoupCookieJar:accept-policy: (attributes org.gtk.Property.get=soup_cookie_jar_get_accept_policy org.gtk.Property.set=soup_cookie_jar_set_accept_policy) * + * The policy the jar should follow to accept or reject cookies. */ propertiesPROP_ACCEPT_POLICY = g_param_spec_enum ("accept-policy", @@ -222,11 +225,12 @@ /** * soup_cookie_jar_new: * - * Creates a new #SoupCookieJar. The base #SoupCookieJar class does - * not support persistent storage of cookies; use a subclass for that. + * Creates a new #SoupCookieJar. * - * Returns: a new #SoupCookieJar + * The base #SoupCookieJar class does not support persistent storage of cookies; + * use a subclass for that. * + * Returns: a new #SoupCookieJar **/ SoupCookieJar * soup_cookie_jar_new (void) @@ -341,6 +345,8 @@ next_domain = NULL; } + g_mutex_lock (&priv->mutex); + do { new_head = domain_cookies = g_hash_table_lookup (priv->domains, cur); while (domain_cookies) { @@ -377,6 +383,8 @@ } g_slist_free (cookies_to_remove); + g_mutex_unlock (&priv->mutex); + return g_slist_sort_with_data (cookies, compare_cookies, jar); } @@ -385,7 +393,7 @@ * @jar: a #SoupCookieJar * @uri: a #GUri * @for_http: whether or not the return value is being passed directly - * to an HTTP operation + * to an HTTP operation * * Retrieves (in Cookie-header form) the list of cookies that would * be sent with a request to @uri. @@ -399,8 +407,7 @@ * this. * * Returns: (nullable): the cookies, in string form, or %NULL if - * there are no cookies for @uri. - * + * there are no cookies for @uri. **/ char * soup_cookie_jar_get_cookies (SoupCookieJar *jar, GUri *uri, @@ -431,10 +438,10 @@ * @jar: a #SoupCookieJar * @uri: a #GUri * @for_http: whether or not the return value is being passed directly - * to an HTTP operation + * to an HTTP operation * * Retrieves the list of cookies that would be sent with a request to @uri - * as a #GSList of #SoupCookie objects. + * as a struct@GLib.List of #SoupCookie objects. * * If @for_http is %TRUE, the return value will include cookies marked * "HttpOnly" (that is, cookies that the server wishes to keep hidden @@ -445,8 +452,7 @@ * this. * * Returns: (transfer full) (element-type Soup.Cookie): a #GSList - * with the cookies in the @jar that would be sent with a request to @uri. - * + * with the cookies in the @jar that would be sent with a request to @uri. **/ GSList * soup_cookie_jar_get_cookie_list (SoupCookieJar *jar, GUri *uri, gboolean for_http) @@ -464,19 +470,20 @@ * @top_level: (nullable): a #GUri for the top level document * @site_for_cookies: (nullable): a #GUri indicating the origin to get cookies for * @for_http: whether or not the return value is being passed directly - * to an HTTP operation + * to an HTTP operation * @is_safe_method: if the HTTP method is safe, as defined by RFC 7231, ignored when @for_http is %FALSE * @is_top_level_navigation: whether or not the HTTP request is part of - * top level navigation + * top level navigation * - * This is an extended version of soup_cookie_jar_get_cookie_list() that - * provides more information required to use SameSite cookies. See the - * SameSite cookies spec(https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site-00) - * for more detailed information. + * This is an extended version of method@CookieJar.get_cookie_list that + * provides more information required to use SameSite cookies. * - * Returns: (transfer full) (element-type Soup.Cookie): a #GSList - * with the cookies in the @jar that would be sent with a request to @uri. + * See the SameSite cookies + * spec(https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site-00) for + * more detailed information. * + * Returns: (transfer full) (element-type Soup.Cookie): a #GSList + * with the cookies in the @jar that would be sent with a request to @uri. */ GSList * soup_cookie_jar_get_cookie_list_with_same_site_info (SoupCookieJar *jar, @@ -515,6 +522,7 @@ const char *cookie_base_domain;
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/cookies/soup-cookie.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/cookies/soup-cookie.c
Changed
@@ -20,21 +20,13 @@ #include "soup.h" /** - * SECTION:soup-cookie - * @short_description: HTTP Cookies - * @see_also: #SoupMessage, #SoupCookieJar - * - * #SoupCookie implements HTTP cookies, as described by <ulink - * url="http://tools.ietf.org/html/rfc6265.txt">RFC 6265</ulink>. - * - * To have a #SoupSession handle cookies for your appliction - * automatically, use a #SoupCookieJar. - **/ - -/** * SoupCookie: * - * An HTTP cookie. + * Implements HTTP cookies, as described by + * RFC 6265(http://tools.ietf.org/html/rfc6265.txt). + * + * To have a class@Session handle cookies for your appliction + * automatically, use a class@CookieJar. * * @name and @value will be set for all cookies. If the cookie is * generated from a string that appears to have no name, then @name @@ -54,7 +46,6 @@ * If @http_only is set, the cookie should not be exposed to untrusted * code (eg, javascript), so as to minimize the danger posed by * cross-site scripting attacks. - * **/ struct _SoupCookie { @@ -76,7 +67,6 @@ * Copies @cookie. * * Returns: a copy of @cookie - * **/ SoupCookie * soup_cookie_copy (SoupCookie *cookie) @@ -101,12 +91,12 @@ * @cookie: a #SoupCookie * @host: a URI * - * Checks if the @cookie's domain and @host match in the sense that - * @cookie should be sent when making a request to @host, or that - * @cookie should be accepted when receiving a response from @host. + * Checks if the @cookie's domain and @host match. + * + * The domains match if @cookie should be sent when making a request to @host, + * or that @cookie should be accepted when receiving a response from @host. * * Returns: %TRUE if the domains match, %FALSE otherwise - * **/ gboolean soup_cookie_domain_matches (SoupCookie *cookie, const char *host) @@ -349,9 +339,10 @@ * @path: cookie path, or %NULL * @max_age: max age of the cookie, or -1 for a session cookie * - * Creates a new #SoupCookie with the given attributes. (Use - * soup_cookie_set_secure() and soup_cookie_set_http_only() if you - * need to set those attributes on the returned cookie.) + * Creates a new #SoupCookie with the given attributes. + * + * Use method@Cookie.set_secure and method@Cookie.set_http_only if you + * need to set those attributes on the returned cookie. * * If @domain starts with ".", that indicates a domain (which matches * the string after the ".", or any hostname that has @domain as a @@ -365,10 +356,9 @@ * %SOUP_COOKIE_MAX_AGE_ONE_WEEK and %SOUP_COOKIE_MAX_AGE_ONE_YEAR (or * multiples thereof) to calculate this value. (If you really care * about setting the exact time that the cookie will expire, use - * soup_cookie_set_expires().) + * method@Cookie.set_expires.) * * Returns: a new #SoupCookie. - * **/ SoupCookie * soup_cookie_new (const char *name, const char *value, @@ -393,10 +383,11 @@ /** * soup_cookie_parse: * @header: a cookie string (eg, the value of a Set-Cookie header) - * @origin: (nullable): origin of the cookie, or %NULL + * @origin: (nullable): origin of the cookie + * + * Parses @header and returns a #SoupCookie. * - * Parses @header and returns a #SoupCookie. (If @header contains - * multiple cookies, only the first one will be parsed.) + * If @header contains multiple cookies, only the first one will be parsed. * * If @header does not have "path" or "domain" attributes, they will * be defaulted from @origin. If @origin is %NULL, path will default @@ -406,9 +397,8 @@ * of the cookie. * * Returns: (nullable): a new #SoupCookie, or %NULL if it could - * not be parsed, or contained an illegal "domain" attribute for a - * cookie originating from @origin. - * + * not be parsed, or contained an illegal "domain" attribute for a + * cookie originating from @origin. **/ SoupCookie * soup_cookie_parse (const char *cookie, GUri *origin) @@ -423,10 +413,9 @@ * soup_cookie_get_name: * @cookie: a #SoupCookie * - * Gets @cookie's name + * Gets @cookie's name. * * Returns: @cookie's name - * **/ const char * soup_cookie_get_name (SoupCookie *cookie) @@ -439,8 +428,7 @@ * @cookie: a #SoupCookie * @name: the new name * - * Sets @cookie's name to @name - * + * Sets @cookie's name to @name. **/ void soup_cookie_set_name (SoupCookie *cookie, const char *name) @@ -453,10 +441,9 @@ * soup_cookie_get_value: * @cookie: a #SoupCookie * - * Gets @cookie's value + * Gets @cookie's value. * * Returns: @cookie's value - * **/ const char * soup_cookie_get_value (SoupCookie *cookie) @@ -469,8 +456,7 @@ * @cookie: a #SoupCookie * @value: the new value * - * Sets @cookie's value to @value - * + * Sets @cookie's value to @value. **/ void soup_cookie_set_value (SoupCookie *cookie, const char *value) @@ -483,10 +469,9 @@ * soup_cookie_get_domain: * @cookie: a #SoupCookie * - * Gets @cookie's domain + * Gets @cookie's domain. * * Returns: @cookie's domain - * **/ const char * soup_cookie_get_domain (SoupCookie *cookie) @@ -499,8 +484,7 @@ * @cookie: a #SoupCookie * @domain: the new domain * - * Sets @cookie's domain to @domain - * + * Sets @cookie's domain to @domain. **/ void soup_cookie_set_domain (SoupCookie *cookie, const char *domain) @@ -513,10 +497,9 @@ * soup_cookie_get_path: * @cookie: a #SoupCookie * - * Gets @cookie's path + * Gets @cookie's path. * * Returns: @cookie's path - * **/ const char * soup_cookie_get_path (SoupCookie *cookie) @@ -529,8 +512,7 @@ * @cookie: a #SoupCookie * @path: the new path * - * Sets @cookie's path to @path - * + * Sets @cookie's path to @path. **/ void
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/generate-version-header.py -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/generate-version-header.py
Changed
@@ -19,8 +19,8 @@ # Specific to 3.x dev releases versions.append((3, 0)) else: - minor_max = minor if minor != 0 and is_stable(minor) else minor + 1 - for i in range(0, minor_max): + minor_max = minor if is_stable(minor) else minor + 1 + for i in range(0, minor_max + 1): if is_stable(i): versions.append((3, i)) @@ -37,19 +37,32 @@ * Since: {major_version}.{minor_version} */ #define SOUP_VERSION_{major_version}_{minor_version} (G_ENCODE_VERSION ({major_version}, {minor_version})) - '''.format(major_version=version0, minor_version=version1) - version_attributes += '''#if SOUP_VERSION_MIN_REQUIRED >= SOUP_VERSION_{major_version}_{minor_version} -# define SOUP_DEPRECATED_IN_{major_version}_{minor_version} G_DEPRECATED -# define SOUP_DEPRECATED_IN_{major_version}_{minor_version}_FOR(f) G_DEPRECATED_FOR(f) + version_attributes += '''/** + * SOUP_DEPRECATED_IN_{major_version}_{minor_version}: + * A macro used to indicate a symbol was deprecated in this version. + */ +/** + * SOUP_DEPRECATED_IN_{major_version}_{minor_version}_FOR: + * @f: The recommended replacement function. + * + * A macro used to indicate a symbol was deprecated in this version with a replacement. + */ +#if SOUP_VERSION_MIN_REQUIRED >= SOUP_VERSION_{major_version}_{minor_version} +# define SOUP_DEPRECATED_IN_{major_version}_{minor_version} SOUP_DEPRECATED +# define SOUP_DEPRECATED_IN_{major_version}_{minor_version}_FOR(f) SOUP_DEPRECATED_FOR(f) #else -# define SOUP_DEPRECATED_IN_{major_version}_{minor_version} -# define SOUP_DEPRECATED_IN_{major_version}_{minor_version}_FOR(f) +# define SOUP_DEPRECATED_IN_{major_version}_{minor_version} _SOUP_EXTERN +# define SOUP_DEPRECATED_IN_{major_version}_{minor_version}_FOR(f) _SOUP_EXTERN #endif +/** + * SOUP_AVAILABLE_IN_{major_version}_{minor_version}: + * A macro used to indicate a symbol is available in this version or later. + */ #if SOUP_VERSION_MAX_ALLOWED < SOUP_VERSION_{major_version}_{minor_version} -# define SOUP_AVAILABLE_IN_{major_version}_{minor_version} G_UNAVAILABLE({major_version}, {minor_version}) _SOUP_EXTERN +# define SOUP_AVAILABLE_IN_{major_version}_{minor_version} SOUP_UNAVAILABLE({major_version}, {minor_version}) #else # define SOUP_AVAILABLE_IN_{major_version}_{minor_version} _SOUP_EXTERN #endif
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/hsts/soup-hsts-enforcer-db.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/hsts/soup-hsts-enforcer-db.c
Changed
@@ -19,19 +19,14 @@ #include "soup.h" /** - * SECTION:soup-hsts-enforcer-db - * @short_description: Persistent HTTP Strict Transport Security enforcer + * SoupHSTSEnforcerDB: + * + * Persistent HTTP Strict Transport Security enforcer. * - * #SoupHSTSEnforcerDB is a #SoupHSTSEnforcer that uses a SQLite + * #SoupHSTSEnforcerDB is a class@HSTSEnforcer that uses a SQLite * database as a backend for persistency. **/ -/** - * SoupHSTSEnforcerDB: - * - * Subclass of #SoupHSTSEnforcer using an sqlite database. - */ - enum { PROP_0, @@ -116,10 +111,9 @@ * policies. If the file doesn't exist, a new database will be created * and initialized. Changes to the policies during the lifetime of a * #SoupHSTSEnforcerDB will be written to @filename when - * #SoupHSTSEnforcer::changed is emitted. + * signal@HSTSEnforcer::changed is emitted. * * Returns: the new #SoupHSTSEnforcer - * **/ SoupHSTSEnforcer * soup_hsts_enforcer_db_new (const char *filename)
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/hsts/soup-hsts-enforcer.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/hsts/soup-hsts-enforcer.c
Changed
@@ -19,39 +19,32 @@ #include "soup-uri-utils-private.h" /** - * SECTION:soup-hsts-enforcer - * @short_description: Automatic HTTP Strict Transport Security enforcing - * for #SoupSession + * SoupHSTSEnforcer: + * + * Automatic HTTP Strict Transport Security enforcing for class@Session. * * A #SoupHSTSEnforcer stores HSTS policies and enforces them when - * required. #SoupHSTSEnforcer implements #SoupSessionFeature, so you + * required. #SoupHSTSEnforcer implements iface@SessionFeature, so you * can add an HSTS enforcer to a session with - * soup_session_add_feature() or soup_session_add_feature_by_type(). + * method@Session.add_feature or method@Session.add_feature_by_type. * * #SoupHSTSEnforcer keeps track of all the HTTPS destinations that, * when connected to, return the Strict-Transport-Security header with * valid values. #SoupHSTSEnforcer will forget those destinations * upon expiry or when the server requests it. * - * When the #SoupSession the #SoupHSTSEnforcer is attached to queues - * or restarts a message, the #SoupHSTSEnforcer will rewrite the URI - * to HTTPS if the destination is a known HSTS host and is contacted - * over an insecure transport protocol (HTTP). Users of - * #SoupHSTSEnforcer are advised to listen to changes in - * SoupMessage:uri in order to be aware of changes in the message URI. + * When the class@Session the #SoupHSTSEnforcer is attached to queues or + * restarts a message, the #SoupHSTSEnforcer will rewrite the URI to HTTPS if + * the destination is a known HSTS host and is contacted over an insecure + * transport protocol (HTTP). Users of #SoupHSTSEnforcer are advised to listen + * to changes in the property@Message:uri property in order to be aware of + * changes in the message URI. * * Note that #SoupHSTSEnforcer does not support any form of long-term - * HSTS policy persistence. See #SoupHSTSEnforcerDB for a persistent + * HSTS policy persistence. See class@HSTSEnforcerDB for a persistent * enforcer. - * **/ -/** - * SoupHSTSEnforcer: - * - * Class for storing and enforcing a #SoupHSTSPolicy. - */ - static void soup_hsts_enforcer_session_feature_init (SoupSessionFeatureInterface *feature_interface, gpointer interface_data); enum { @@ -63,6 +56,7 @@ typedef struct { SoupSession *session; + GMutex mutex; GHashTable *host_policies; GHashTable *session_policies; } SoupHSTSEnforcerPrivate; @@ -84,6 +78,7 @@ priv->session_policies = g_hash_table_new_full (soup_str_case_hash, soup_str_case_equal, g_free, NULL); + g_mutex_init (&priv->mutex); } static void @@ -103,6 +98,8 @@ soup_hsts_policy_free (value); g_hash_table_destroy (priv->session_policies); + g_mutex_clear (&priv->mutex); + G_OBJECT_CLASS (soup_hsts_enforcer_parent_class)->finalize (object); } @@ -160,7 +157,9 @@ * @old_policy: the old #SoupHSTSPolicy value * @new_policy: the new #SoupHSTSPolicy value * - * Emitted when @hsts_enforcer changes. If a policy has been added, + * Emitted when @hsts_enforcer changes. + * + * If a policy has been added, * @new_policy will contain the newly-added policy and * @old_policy will be %NULL. If a policy has been deleted, * @old_policy will contain the to-be-deleted policy and @@ -186,12 +185,12 @@ /** * soup_hsts_enforcer_new: * - * Creates a new #SoupHSTSEnforcer. The base #SoupHSTSEnforcer class - * does not support persistent storage of HSTS policies, see - * #SoupHSTSEnforcerDB for that. + * Creates a new #SoupHSTSEnforcer. * - * Returns: a new #SoupHSTSEnforcer + * The base #SoupHSTSEnforcer class does not support persistent storage of HSTS + * policies, see class@HSTSEnforcerDB for that. * + * Returns: a new #SoupHSTSEnforcer **/ SoupHSTSEnforcer * soup_hsts_enforcer_new (void) @@ -317,14 +316,14 @@ * @hsts_enforcer: a #SoupHSTSEnforcer * @policy: (transfer none): the policy of the HSTS host * - * Sets @policy to @hsts_enforcer. If @policy is expired, any - * existing HSTS policy for its host will be removed instead. If a - * policy existed for this host, it will be replaced. Otherwise, the - * new policy will be inserted. If the policy is a session policy, that - * is, one created with soup_hsts_policy_new_session_policy(), the policy - * will not expire and will be enforced during the lifetime of - * @hsts_enforcer's #SoupSession. + * Sets @policy to @hsts_enforcer. * + * If @policy is expired, any existing HSTS policy for its host will be removed + * instead. If a policy existed for this host, it will be replaced. Otherwise, + * the new policy will be inserted. If the policy is a session policy, that is, + * one created with ctor@HSTSPolicy.new_session_policy, the policy will not + * expire and will be enforced during the lifetime of @hsts_enforcer's + * class@Session. **/ void soup_hsts_enforcer_set_policy (SoupHSTSEnforcer *hsts_enforcer, @@ -342,21 +341,24 @@ domain = soup_hsts_policy_get_domain (policy); g_return_if_fail (domain != NULL); - is_session_policy = soup_hsts_policy_is_session_policy (policy); - policies = is_session_policy ? priv->session_policies : - priv->host_policies; + g_mutex_lock (&priv->mutex); + is_session_policy = soup_hsts_policy_is_session_policy (policy); if (!is_session_policy && soup_hsts_policy_is_expired (policy)) { soup_hsts_enforcer_remove_host_policy (hsts_enforcer, domain); + g_mutex_unlock (&priv->mutex); return; } + policies = is_session_policy ? priv->session_policies : priv->host_policies; current_policy = g_hash_table_lookup (policies, domain); if (current_policy) soup_hsts_enforcer_replace_policy (hsts_enforcer, policy); else soup_hsts_enforcer_insert_policy (hsts_enforcer, policy); + + g_mutex_unlock (&priv->mutex); } /** @@ -365,10 +367,10 @@ * @domain: policy domain or hostname * @include_subdomains: %TRUE if the policy applies on sub domains * - * Sets a session policy for @domain. A session policy is a policy - * that is permanent to the lifetime of @hsts_enforcer's #SoupSession - * and doesn't expire. + * Sets a session policy for @domain. * + * A session policy is a policy that is permanent to the lifetime of + * @hsts_enforcer's class@Session and doesn't expire. **/ void soup_hsts_enforcer_set_session_policy (SoupHSTSEnforcer *hsts_enforcer, @@ -426,19 +428,28 @@ soup_hsts_enforcer_must_enforce_secure_transport (SoupHSTSEnforcer *hsts_enforcer, const char *domain) { + SoupHSTSEnforcerPrivate *priv = soup_hsts_enforcer_get_instance_private (hsts_enforcer); const char *super_domain = domain; g_return_val_if_fail (domain != NULL, FALSE); - if (soup_hsts_enforcer_has_valid_policy (hsts_enforcer, domain)) + g_mutex_lock (&priv->mutex); + + if (soup_hsts_enforcer_has_valid_policy (hsts_enforcer, domain)) { + g_mutex_unlock (&priv->mutex); return TRUE; + } while ((super_domain = super_domain_of (super_domain)) != NULL) { if (soup_hsts_enforcer_host_includes_subdomains (hsts_enforcer, super_domain) && - soup_hsts_enforcer_has_valid_policy (hsts_enforcer, super_domain)) + soup_hsts_enforcer_has_valid_policy (hsts_enforcer, super_domain)) { + g_mutex_unlock (&priv->mutex); return TRUE; + } } + g_mutex_unlock (&priv->mutex); + return FALSE; }
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/hsts/soup-hsts-enforcer.h -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/hsts/soup-hsts-enforcer.h
Changed
@@ -18,7 +18,7 @@ * SoupHSTSEnforcerClass: * @parent_class: The parent class. * @is_persistent: The @is_persistent function advertises whether the enforcer is persistent or - * whether changes made to it will be lost when the underlying #SoupSession is finished. + * whether changes made to it will be lost when the underlying class@Session is finished. * @has_valid_policy: The @has_valid_policy function is called to check whether there is a valid * policy for the given domain. This method should return %TRUE for #SoupHSTSEnforcer to * change the scheme of the #GUri in the #SoupMessage to HTTPS. Implementations might want to
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/hsts/soup-hsts-policy.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/hsts/soup-hsts-policy.c
Changed
@@ -19,22 +19,13 @@ #include "soup.h" /** - * SECTION:soup-hsts-policy - * @title: SoupHSTSPolicy - * @short_description: HSTS policies - * - * Policies to be used with #SoupHSTSEnforcer. - * - */ - -/** * SoupHSTSPolicy: * * #SoupHSTSPolicy implements HTTP policies, as described by * RFC 6797(http://tools.ietf.org/html/rfc6797). * * @domain represents the host that this policy applies to. The domain - * must be IDNA-canonicalized. soup_hsts_policy_new() and related methods + * must be IDNA-canonicalized. ctor@HSTSPolicy.new and related methods * will do this for you. * * @max_age contains the 'max-age' value from the Strict Transport @@ -47,7 +38,6 @@ * * If @include_subdomains is %TRUE, the Strict Transport Security policy * must also be enforced on subdomains of @domain. - * **/ struct _SoupHSTSPolicy { @@ -66,7 +56,6 @@ * Copies @policy. * * Returns: (transfer full): a copy of @policy - * **/ SoupHSTSPolicy * soup_hsts_policy_copy (SoupHSTSPolicy *policy) @@ -90,7 +79,6 @@ * Tests if @policy1 and @policy2 are equal. * * Returns: whether the policies are equal. - * */ gboolean soup_hsts_policy_equal (SoupHSTSPolicy *policy1, SoupHSTSPolicy *policy2) @@ -141,14 +129,13 @@ * represented by this object must be enforced. * * @max_age is used to set the "expires" attribute on the policy; pass - * SOUP_HSTS_POLICY_MAX_AGE_PAST for an already-expired policy, or a + * %SOUP_HSTS_POLICY_MAX_AGE_PAST for an already-expired policy, or a * lifetime in seconds. * * If @include_subdomains is %TRUE, the strict transport security policy * must also be enforced on all subdomains of @domain. * * Returns: a new #SoupHSTSPolicy. - * **/ SoupHSTSPolicy * soup_hsts_policy_new (const char *domain, @@ -178,11 +165,12 @@ * @expires: the date of expiration of the policy or %NULL for a permanent policy * @include_subdomains: %TRUE if the policy applies on subdomains * - * Full version of #soup_hsts_policy_new(), to use with an existing - * expiration date. See #soup_hsts_policy_new() for details. + * Full version of ctor@HSTSPolicy.new, to use with an existing + * expiration date. * - * Returns: a new #SoupHSTSPolicy. + * See ctor@HSTSPolicy.new for details. * + * Returns: a new #SoupHSTSPolicy. **/ SoupHSTSPolicy * soup_hsts_policy_new_full (const char *domain, @@ -219,8 +207,9 @@ * @include_subdomains: %TRUE if the policy applies on sub domains * * Creates a new session #SoupHSTSPolicy with the given attributes. + * * A session policy is a policy that is valid during the lifetime of - * the #SoupHSTSEnforcer it is added to. Contrary to regular policies, + * the class@HSTSEnforcer it is added to. Contrary to regular policies, * it has no expiration date and is not stored in persistent * enforcers. These policies are useful for user-agent to load their * own or user-defined rules. @@ -232,7 +221,6 @@ * must also be enforced on all subdomains of @domain. * * Returns: a new #SoupHSTSPolicy. - * **/ SoupHSTSPolicy * soup_hsts_policy_new_session_policy (const char *domain, @@ -253,8 +241,7 @@ * returns a #SoupHSTSPolicy. * * Returns: (nullable): a new #SoupHSTSPolicy, or %NULL if no valid - * "Strict-Transport-Security" response header was found. - * + * "Strict-Transport-Security" response header was found. **/ SoupHSTSPolicy * soup_hsts_policy_new_from_response (SoupMessage *msg) @@ -315,7 +302,6 @@ * Gets @policy's domain. * * Returns: (transfer none): @policy's domain. - * **/ const char * soup_hsts_policy_get_domain (SoupHSTSPolicy *policy) @@ -329,11 +315,11 @@ * soup_hsts_policy_is_expired: * @policy: a #SoupHSTSPolicy * - * Gets whether @policy is expired. Permanent policies never - * expire. + * Gets whether @policy is expired. * - * Returns: %TRUE if @policy is expired, %FALSE otherwise. + * Permanent policies never expire. * + * Returns: %TRUE if @policy is expired, %FALSE otherwise. **/ gboolean soup_hsts_policy_is_expired (SoupHSTSPolicy *policy) @@ -350,7 +336,6 @@ * Gets whether @policy include its subdomains. * * Returns: %TRUE if @policy includes subdomains, %FALSE otherwise. - * **/ gboolean soup_hsts_policy_includes_subdomains (SoupHSTSPolicy *policy) @@ -365,10 +350,10 @@ * @policy: a #SoupHSTSPolicy * * Gets whether @policy is a non-permanent, non-expirable session policy. - * see soup_hsts_policy_new_session_policy() for details. * - * Returns: %TRUE if @policy is permanent, %FALSE otherwise + * See ctor@HSTSPolicy.new_session_policy for details. * + * Returns: %TRUE if @policy is permanent, %FALSE otherwise **/ gboolean soup_hsts_policy_is_session_policy (SoupHSTSPolicy *policy) @@ -415,7 +400,6 @@ * @policy: (transfer full): a #SoupHSTSPolicy * * Frees @policy. - * **/ void soup_hsts_policy_free (SoupHSTSPolicy *policy)
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/http1/soup-client-message-io-http1.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/http1/soup-client-message-io-http1.c
Changed
@@ -38,6 +38,9 @@ SoupMessageMetrics *metrics; + /* Request body logger */ + SoupLogger *logger; + #ifdef HAVE_SYSPROF gint64 begin_time_nsec; #endif @@ -146,8 +149,11 @@ client_io->msg_io->metrics->request_body_size += count; } - if (!is_metadata) + if (!is_metadata) { + if (client_io->msg_io->logger) + soup_logger_log_request_data (client_io->msg_io->logger, msg, (const char *)buffer, count); soup_message_wrote_body_data (msg, count); + } } static void @@ -252,7 +258,10 @@ uri_string = g_strdup_printf ("%s:%d", uri_host, g_uri_get_port (uri)); g_free (uri_host); } else { - gboolean proxy = soup_connection_is_via_proxy (soup_message_get_connection (msg)); + SoupConnection *conn = soup_message_get_connection (msg); + gboolean proxy = soup_connection_is_via_proxy (conn); + + g_object_unref (conn); /* Proxy expects full URI to destination. Otherwise * just the path. @@ -354,10 +363,7 @@ io->write_state = SOUP_MESSAGE_IO_STATE_BODY; logger = soup_session_get_feature_for_message (client_io->msg_io->item->session, SOUP_TYPE_LOGGER, msg); - if (logger) { - soup_logger_request_body_setup (SOUP_LOGGER (logger), msg, - SOUP_BODY_OUTPUT_STREAM (io->body_ostream)); - } + client_io->msg_io->logger = logger ? SOUP_LOGGER (logger) : NULL; break; case SOUP_MESSAGE_IO_STATE_BODY: @@ -854,9 +860,12 @@ soup_client_message_io_http1_get_priority (client_io)); g_source_attach (io->io_source, g_main_context_get_thread_default ()); } else { - if ((SoupClientMessageIOHTTP1 *)soup_message_get_io_data (msg) == client_io) - soup_message_io_finish (msg, error); - g_error_free (error); + if ((SoupClientMessageIOHTTP1 *)soup_message_get_io_data (msg) == client_io) { + g_assert (!client_io->msg_io->item->error); + client_io->msg_io->item->error = g_steal_pointer (&error); + soup_message_io_finish (msg, client_io->msg_io->item->error); + } + g_clear_error (&error); }
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/http2/soup-body-input-stream-http2.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/http2/soup-body-input-stream-http2.c
Changed
@@ -180,7 +180,7 @@ if (count == 0 && blocking && !priv->completed) { GError *read_error = NULL; g_signal_emit (memory_stream, signalsNEED_MORE_DATA, 0, - cancellable, &read_error); + blocking, cancellable, &read_error); if (read_error) { g_propagate_error (error, read_error); @@ -429,5 +429,6 @@ NULL, NULL, NULL, G_TYPE_ERROR, - 1, G_TYPE_CANCELLABLE); + 2, G_TYPE_BOOLEAN, + G_TYPE_CANCELLABLE); }
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/http2/soup-client-message-io-http2.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/http2/soup-client-message-io-http2.c
Changed
@@ -40,29 +40,19 @@ #include "soup-client-input-stream.h" #include "soup-logger-private.h" #include "soup-uri-utils-private.h" +#include "soup-http2-utils.h" #include "content-decoder/soup-content-decoder.h" #include "soup-body-input-stream-http2.h" -#include <nghttp2/nghttp2.h> - #define FRAME_HEADER_SIZE 9 -typedef enum { - STATE_NONE, - STATE_WRITE_HEADERS, - STATE_WRITE_DATA, - STATE_WRITE_DONE, - STATE_READ_HEADERS, - STATE_READ_DATA_START, - STATE_READ_DATA, - STATE_READ_DONE, -} SoupHTTP2IOState; - typedef struct { SoupClientMessageIO iface; - SoupConnection *conn; + GThread *owner; + gboolean async; + GWeakRef conn; GIOStream *stream; GInputStream *istream; GOutputStream *ostream; @@ -87,6 +77,7 @@ GTask *close_task; gboolean session_terminated; gboolean goaway_sent; + gboolean ever_used; guint in_callback; } SoupClientMessageIOHTTP2; @@ -116,6 +107,7 @@ gpointer completion_data; SoupHTTP2IOState state; GError *error; + uint32_t http2_error; gboolean paused; guint32 stream_id; gboolean can_be_restarted; @@ -125,93 +117,6 @@ static void soup_client_message_io_http2_finished (SoupClientMessageIO *iface, SoupMessage *msg); static ssize_t on_data_source_read_callback (nghttp2_session *session, int32_t stream_id, uint8_t *buf, size_t length, uint32_t *data_flags, nghttp2_data_source *source, void *user_data); -static void -NGCHECK (int return_code) -{ - if (return_code == NGHTTP2_ERR_NOMEM) - g_abort (); - else if (return_code < 0) - g_debug ("Unhandled NGHTTP2 Error: %s", nghttp2_strerror (return_code)); -} - -static const char * -frame_type_to_string (nghttp2_frame_type type) -{ - switch (type) { - case NGHTTP2_DATA: - return "DATA"; - case NGHTTP2_HEADERS: - return "HEADERS"; - case NGHTTP2_PRIORITY: - return "PRIORITY"; - case NGHTTP2_RST_STREAM: - return "RST_STREAM"; - case NGHTTP2_SETTINGS: - return "SETTINGS"; - case NGHTTP2_PING: - return "PING"; - case NGHTTP2_GOAWAY: - return "GOAWAY"; - case NGHTTP2_WINDOW_UPDATE: - return "WINDOW_UPDATE"; - /* LCOV_EXCL_START */ - case NGHTTP2_PUSH_PROMISE: - return "PUSH_PROMISE"; - case NGHTTP2_CONTINUATION: - return "CONTINUATION"; - case NGHTTP2_ALTSVC: - return "ALTSVC"; - case NGHTTP2_ORIGIN: - return "ORIGIN"; - default: - g_warn_if_reached (); - return "UNKNOWN"; - /* LCOV_EXCL_STOP */ - } -} - -static const char * -headers_category_to_string (nghttp2_headers_category catergory) -{ - switch (catergory) { - case NGHTTP2_HCAT_REQUEST: - return "REQUEST"; - case NGHTTP2_HCAT_RESPONSE: - return "RESPONSE"; - case NGHTTP2_HCAT_PUSH_RESPONSE: - return "PUSH_RESPONSE"; - case NGHTTP2_HCAT_HEADERS: - return "HEADERS"; - } - g_assert_not_reached (); -} - -static const char * -state_to_string (SoupHTTP2IOState state) -{ - switch (state) { - case STATE_NONE: - return "NONE"; - case STATE_WRITE_HEADERS: - return "WRITE_HEADERS"; - case STATE_WRITE_DATA: - return "WRITE_DATA"; - case STATE_WRITE_DONE: - return "WRITE_DONE"; - case STATE_READ_HEADERS: - return "READ_HEADERS"; - case STATE_READ_DATA_START: - return "READ_DATA_START"; - case STATE_READ_DATA: - return "READ_DATA"; - case STATE_READ_DONE: - return "READ_DONE"; - default: - g_assert_not_reached (); - return ""; - } -} - G_GNUC_PRINTF(3, 0) static void h2_debug (SoupClientMessageIOHTTP2 *io, @@ -234,7 +139,7 @@ stream_id = data->stream_id; g_assert (io); - g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "C%" G_GUINT64_FORMAT "-S%u %s %s", io->connection_id, stream_id, data ? state_to_string (data->state) : "-", message); + g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "CLIENT C%" G_GUINT64_FORMAT "-S%u %s %s", io->connection_id, stream_id, data ? soup_http2_io_state_to_string (data->state) : "-", message); g_free (message); } @@ -268,6 +173,20 @@ } static void +set_http2_error_for_data (SoupHTTP2MessageData *data, + uint32_t error_code) +{ + h2_debug (data->io, data, "SESSION Error: %s", nghttp2_http2_strerror (error_code)); + + if (data->error) + return; + + data->http2_error = error_code; + data->error = g_error_new (G_IO_ERROR, G_IO_ERROR_FAILED, + "HTTP/2 Error: %s", nghttp2_http2_strerror (error_code)); +} + +static void set_io_error (SoupClientMessageIOHTTP2 *io, GError *error) { @@ -277,6 +196,11 @@ io->error = error; else g_error_free (error); + + if (io->close_task && !io->goaway_sent) { + g_task_return_boolean (io->close_task, TRUE); + g_clear_object (&io->close_task); + } } static void @@ -286,23 +210,40 @@ { if (data->state != from) { g_warning ("Unexpected state changed %s -> %s, expected to be from %s", - state_to_string (data->state), state_to_string (to), - state_to_string (from)); + soup_http2_io_state_to_string (data->state), soup_http2_io_state_to_string (to), + soup_http2_io_state_to_string (from)); } /* State never goes backwards */ if (to < data->state) { g_warning ("Unexpected state changed %s -> %s, expected %s -> %s\n", - state_to_string (data->state), state_to_string (to),
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/meson.build -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/meson.build
Changed
@@ -42,15 +42,18 @@ 'http2/soup-client-message-io-http2.c', 'http2/soup-body-input-stream-http2.c', + 'server/http1/soup-server-message-io-http1.c', + 'server/http2/soup-server-message-io-http2.c', 'server/soup-auth-domain.c', 'server/soup-auth-domain-basic.c', 'server/soup-auth-domain-digest.c', + 'server/soup-listener.c', 'server/soup-message-body.c', 'server/soup-path-map.c', 'server/soup-server.c', - 'server/soup-server-io.c', + 'server/soup-server-connection.c', 'server/soup-server-message.c', - 'server/soup-socket.c', + 'server/soup-server-message-io.c', 'websocket/soup-websocket.c', 'websocket/soup-websocket-connection.c', @@ -61,11 +64,13 @@ 'soup-client-input-stream.c', 'soup-client-message-io.c', 'soup-connection.c', + 'soup-connection-manager.c', 'soup-date-utils.c', 'soup-filter-input-stream.c', 'soup-form.c', 'soup-headers.c', 'soup-header-names.c', + 'soup-http2-utils.c', 'soup-init.c', 'soup-io-stream.c', 'soup-logger.c', @@ -199,6 +204,8 @@ 'http1', 'http2', 'server', + 'server/http1', + 'server/http2', 'websocket', '.' ), @@ -211,7 +218,6 @@ soup_enums, , version : libversion, - soversion : soversion, darwin_versions: darwin_versions, c_args : libsoup_c_args, include_directories : libsoup_includes,
View file
_service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/server/http1
Added
+(directory)
View file
_service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/server/http1/soup-server-message-io-http1.c
Added
@@ -0,0 +1,1062 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ +/* + * soup-server-message-io-http1.c: HTTP message I/O + * + * Copyright (C) 2000-2003, Ximian, Inc. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <glib/gi18n-lib.h> + +#include "soup-server-message-io-http1.h" +#include "soup.h" +#include "soup-body-input-stream.h" +#include "soup-body-output-stream.h" +#include "soup-filter-input-stream.h" +#include "soup-message-io-data.h" +#include "soup-message-headers-private.h" +#include "soup-server-message-private.h" +#include "soup-misc.h" + +typedef struct { + SoupMessageIOData base; + + SoupServerMessage *msg; + + GBytes *write_chunk; + goffset write_body_offset; + + GSource *unpause_source; + + GMainContext *async_context; +} SoupMessageIOHTTP1; + +typedef struct { + SoupServerMessageIO iface; + + GIOStream *iostream; + GInputStream *istream; + GOutputStream *ostream; + + SoupMessageIOStartedFn started_cb; + gpointer started_user_data; + + gboolean in_io_run; + + SoupMessageIOHTTP1 *msg_io; +} SoupServerMessageIOHTTP1; + +#define RESPONSE_BLOCK_SIZE 8192 +#define HEADER_SIZE_LIMIT (64 * 1024) + +static gboolean io_run_ready (SoupServerMessage *msg, + gpointer user_data); +static void io_run (SoupServerMessageIOHTTP1 *server_io); + +static SoupMessageIOHTTP1 * +soup_message_io_http1_new (SoupServerMessage *msg) +{ + SoupMessageIOHTTP1 *msg_io; + + msg_io = g_new0 (SoupMessageIOHTTP1, 1); + msg_io->msg = msg; + msg_io->base.read_header_buf = g_byte_array_new (); + msg_io->base.write_buf = g_string_new (NULL); + msg_io->base.read_state = SOUP_MESSAGE_IO_STATE_HEADERS; + msg_io->base.write_state = SOUP_MESSAGE_IO_STATE_NOT_STARTED; + msg_io->async_context = g_main_context_ref_thread_default (); + + return msg_io; +} + +static void +soup_message_io_http1_free (SoupMessageIOHTTP1 *msg_io) +{ + soup_message_io_data_cleanup (&msg_io->base); + + if (msg_io->unpause_source) { + g_source_destroy (msg_io->unpause_source); + g_source_unref (msg_io->unpause_source); + msg_io->unpause_source = NULL; + } + + g_clear_object (&msg_io->msg); + g_clear_pointer (&msg_io->async_context, g_main_context_unref); + g_clear_pointer (&msg_io->write_chunk, g_bytes_unref); + + g_free (msg_io); +} + +static void +soup_server_message_io_http1_destroy (SoupServerMessageIO *iface) +{ + SoupServerMessageIOHTTP1 *io = (SoupServerMessageIOHTTP1 *)iface; + + g_clear_object (&io->iostream); + g_clear_pointer (&io->msg_io, soup_message_io_http1_free); + + g_slice_free (SoupServerMessageIOHTTP1, io); +} + +static void +soup_server_message_io_http1_finished (SoupServerMessageIO *iface, + SoupServerMessage *msg) +{ + SoupServerMessageIOHTTP1 *io = (SoupServerMessageIOHTTP1 *)iface; + SoupMessageIOCompletionFn completion_cb; + gpointer completion_data; + SoupMessageIOCompletion completion; + SoupServerConnection *conn; + + completion_cb = io->msg_io->base.completion_cb; + completion_data = io->msg_io->base.completion_data; + + if ((io->msg_io->base.read_state >= SOUP_MESSAGE_IO_STATE_FINISHING && + io->msg_io->base.write_state >= SOUP_MESSAGE_IO_STATE_FINISHING)) + completion = SOUP_MESSAGE_IO_COMPLETE; + else + completion = SOUP_MESSAGE_IO_INTERRUPTED; + + g_object_ref (msg); + g_clear_pointer (&io->msg_io, soup_message_io_http1_free); + if (completion_cb) + completion_cb (G_OBJECT (msg), completion, completion_data); + conn = soup_server_message_get_connection (msg); + if (completion == SOUP_MESSAGE_IO_COMPLETE && + soup_server_connection_is_connected (conn) && + soup_server_message_is_keepalive (msg)) { + io->msg_io = soup_message_io_http1_new (soup_server_message_new (conn)); + io->msg_io->base.io_source = soup_message_io_data_get_source (&io->msg_io->base, + G_OBJECT (io->msg_io->msg), + io->istream, + io->ostream, + NULL, + (SoupMessageIOSourceFunc)io_run_ready, + NULL); + g_source_attach (io->msg_io->base.io_source, io->msg_io->async_context); + } + g_object_unref (msg); +} + +static GIOStream * +soup_server_message_io_http1_steal (SoupServerMessageIO *iface) +{ + SoupServerMessageIOHTTP1 *io = (SoupServerMessageIOHTTP1 *)iface; + SoupServerMessage *msg; + SoupMessageIOCompletionFn completion_cb; + gpointer completion_data; + GIOStream *iostream; + + if (!io->iostream) + return NULL; + + iostream = g_object_ref (io->iostream); + completion_cb = io->msg_io->base.completion_cb; + completion_data = io->msg_io->base.completion_data; + + msg = io->msg_io->msg; + g_object_ref (msg); + g_clear_pointer (&io->msg_io, soup_message_io_http1_free); + if (completion_cb) + completion_cb (G_OBJECT (msg), SOUP_MESSAGE_IO_STOLEN, completion_data); + g_object_unref (msg); + + return iostream; +} + +static void +closed_async (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GOutputStream *body_ostream = G_OUTPUT_STREAM (source); + SoupServerMessage *msg = user_data; + SoupServerMessageIOHTTP1 *io; + GCancellable *async_wait; + + io = (SoupServerMessageIOHTTP1 *)soup_server_message_get_io_data (msg); + if (!io || !io->msg_io || !io->msg_io->base.async_wait || io->msg_io->base.body_ostream != body_ostream) { + g_object_unref (msg); + return; + } + + g_output_stream_close_finish (body_ostream, result, &io->msg_io->base.async_error); + g_clear_object (&io->msg_io->base.body_ostream); + + async_wait = g_steal_pointer (&io->msg_io->base.async_wait); + g_cancellable_cancel (async_wait); + g_object_unref (async_wait); + + g_object_unref (msg); +} + +/* + * There are two request/response formats: the basic request/response, + * possibly with one or more unsolicited informational responses (such + * as the WebDAV "102 Processing" response):
View file
_service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/server/http1/soup-server-message-io-http1.h
Added
@@ -0,0 +1,14 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2022 Igalia S.L. + */ + +#pragma once + +#include "soup-server-connection.h" +#include "soup-server-message-io.h" + +SoupServerMessageIO *soup_server_message_io_http1_new (SoupServerConnection *conn, + SoupServerMessage *msg, + SoupMessageIOStartedFn started_cb, + gpointer user_data);
View file
_service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/server/http2
Added
+(directory)
View file
_service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/server/http2/soup-server-message-io-http2.c
Added
@@ -0,0 +1,865 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ +/* + * soup-server-message-io-http1.c: HTTP message I/O + * + * Copyright (C) 2022, Igalia S.L. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#undef G_LOG_DOMAIN +#define G_LOG_DOMAIN "libsoup-server-http2" + +#include <glib/gi18n-lib.h> + +#include "soup-server-message-io-http2.h" +#include "soup.h" +#include "soup-body-input-stream.h" +#include "soup-body-output-stream.h" +#include "soup-filter-input-stream.h" +#include "soup-message-io-data.h" +#include "soup-message-headers-private.h" +#include "soup-server-message-private.h" +#include "soup-misc.h" +#include "soup-http2-utils.h" + +typedef struct { + SoupServerMessage *msg; + guint32 stream_id; + SoupHTTP2IOState state; + GSource *unpause_source; + gboolean paused; + + SoupMessageIOCompletionFn completion_cb; + gpointer completion_data; + + char *scheme; + char *authority; + char *path; + + GBytes *write_chunk; + goffset write_offset; + goffset chunk_written; +} SoupMessageIOHTTP2; + +typedef struct { + SoupServerMessageIO iface; + + SoupServerConnection *conn; + GIOStream *iostream; + GInputStream *istream; + GOutputStream *ostream; + + GSource *read_source; + GSource *write_source; + + nghttp2_session *session; + + /* Owned by nghttp2 */ + guint8 *write_buffer; + gssize write_buffer_size; + gssize written_bytes; + + SoupMessageIOStartedFn started_cb; + gpointer started_user_data; + + GHashTable *messages; + + guint in_callback; +} SoupServerMessageIOHTTP2; + +static void soup_server_message_io_http2_send_response (SoupServerMessageIOHTTP2 *io, + SoupMessageIOHTTP2 *msg_io); + +G_GNUC_PRINTF(3, 0) +static void +h2_debug (SoupServerMessageIOHTTP2 *io, + SoupMessageIOHTTP2 *msg_io, + const char *format, + ...) +{ + va_list args; + char *message; + SoupServerConnection *conn; + + if (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, G_LOG_DOMAIN)) + return; + + va_start (args, format); + message = g_strdup_vprintf (format, args); + va_end (args); + + conn = io ? io->conn : msg_io ? soup_server_message_get_connection (msg_io->msg) : NULL; + g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "SERVER C%p-S%u %s %s", conn, msg_io ? msg_io->stream_id : 0, msg_io ? soup_http2_io_state_to_string (msg_io->state) : "-", message); + + g_free (message); +} + + +static void +advance_state_from (SoupMessageIOHTTP2 *msg_io, + SoupHTTP2IOState from, + SoupHTTP2IOState to) +{ + if (msg_io->state != from) { + g_warning ("Unexpected state changed %s -> %s, expected to be from %s", + soup_http2_io_state_to_string (msg_io->state), soup_http2_io_state_to_string (to), + soup_http2_io_state_to_string (from)); + } + + h2_debug (NULL, msg_io, "SESSION State %s -> %s", soup_http2_io_state_to_string (msg_io->state), soup_http2_io_state_to_string (to)); + + msg_io->state = to; +} + +static SoupMessageIOHTTP2 * +soup_message_io_http2_new (SoupServerMessage *msg) +{ + SoupMessageIOHTTP2 *msg_io; + + msg_io = g_new0 (SoupMessageIOHTTP2, 1); + msg_io->msg = msg; + + return msg_io; +} + +static void +soup_message_io_http2_free (SoupMessageIOHTTP2 *msg_io) +{ + if (msg_io->unpause_source) { + g_source_destroy (msg_io->unpause_source); + g_source_unref (msg_io->unpause_source); + } + g_clear_object (&msg_io->msg); + g_free (msg_io->scheme); + g_free (msg_io->authority); + g_free (msg_io->path); + g_clear_pointer (&msg_io->write_chunk, g_bytes_unref); + g_free (msg_io); +} + +static void +soup_server_message_io_http2_destroy (SoupServerMessageIO *iface) +{ + SoupServerMessageIOHTTP2 *io = (SoupServerMessageIOHTTP2 *)iface; + + if (io->read_source) { + g_source_destroy (io->read_source); + g_source_unref (io->read_source); + } + if (io->write_source) { + g_source_destroy (io->write_source); + g_source_unref (io->write_source); + } + + g_clear_object (&io->iostream); + g_clear_pointer (&io->session, nghttp2_session_del); + g_clear_pointer (&io->messages, g_hash_table_unref); + + g_free (io); +} + +static void +soup_server_message_io_http2_finished (SoupServerMessageIO *iface, + SoupServerMessage *msg) +{ + SoupServerMessageIOHTTP2 *io = (SoupServerMessageIOHTTP2 *)iface; + SoupMessageIOHTTP2 *msg_io = NULL; + SoupMessageIOCompletionFn completion_cb; + gpointer completion_data; + SoupMessageIOCompletion completion; + + g_hash_table_steal_extended (io->messages, msg, NULL, (gpointer *)&msg_io); + completion = msg_io->state != STATE_WRITE_DONE ? SOUP_MESSAGE_IO_INTERRUPTED : SOUP_MESSAGE_IO_COMPLETE; + + h2_debug (io, msg_io, "Finished: %s", completion == SOUP_MESSAGE_IO_COMPLETE ? "completed" : "interrupted"); + + completion_cb = msg_io->completion_cb; + completion_data = msg_io->completion_data; + + g_object_ref (msg); + soup_message_io_http2_free (msg_io); + + if (completion_cb) + completion_cb (G_OBJECT (msg), completion, completion_data); + + g_object_unref (msg); +} + +static GIOStream * +soup_server_message_io_http2_steal (SoupServerMessageIO *iface) +{ + g_assert_not_reached (); + return NULL; +} + +static void +soup_server_message_io_http2_read_request (SoupServerMessageIO *iface,
View file
_service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/server/http2/soup-server-message-io-http2.h
Added
@@ -0,0 +1,14 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2022 Igalia S.L. + */ + +#pragma once + +#include "soup-server-connection.h" +#include "soup-server-message-io.h" + +SoupServerMessageIO *soup_server_message_io_http2_new (SoupServerConnection *conn, + SoupServerMessage *msg, + SoupMessageIOStartedFn started_cb, + gpointer user_data);
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/server/soup-auth-domain-basic.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/server/soup-auth-domain-basic.c
Changed
@@ -12,21 +12,17 @@ #include <string.h> #include "soup-auth-domain-basic.h" +#include "soup-auth-domain-private.h" #include "soup-message-headers-private.h" #include "soup.h" /** - * SECTION:soup-auth-domain-basic - * @short_description: Server-side "Basic" authentication + * SoupAuthDomainBasic: + * + * Server-side "Basic" authentication. * * #SoupAuthDomainBasic handles the server side of HTTP "Basic" (ie, * cleartext password) authentication. - **/ - -/** - * SoupAuthDomainBasic: - * - * Subclass of #SoupAuthDomain for Basic authentication. */ enum { @@ -118,9 +114,10 @@ * @optname1: name of first option, or %NULL * @...: option name/value pairs * - * Creates a #SoupAuthDomainBasic. You must set the - * SoupAuthDomain:realm property, to indicate the realm name to be - * returned with the authentication challenge to the client. Other + * Creates a #SoupAuthDomainBasic. + * + * You must set the property@AuthDomain:realm property, to indicate the realm + * name to be returned with the authentication challenge to the client. Other * parameters are optional. * * Returns: the new #SoupAuthDomain @@ -147,9 +144,10 @@ * @msg: the message being authenticated * @username: the username provided by the client * @password: the password provided by the client - * @user_data: the data passed to soup_auth_domain_basic_set_auth_callback() + * @user_data: the data passed to method@AuthDomainBasic.set_auth_callback * * Callback used by #SoupAuthDomainBasic for authentication purposes. + * * The application should verify that @username and @password and valid * and return %TRUE or %FALSE. * @@ -168,22 +166,24 @@ **/ /** - * soup_auth_domain_basic_set_auth_callback: + * soup_auth_domain_basic_set_auth_callback: (attributes org.gtk.Method.set_property=auth-callback) * @domain: (type SoupAuthDomainBasic): the domain * @callback: the callback * @user_data: data to pass to @auth_callback * @dnotify: destroy notifier to free @user_data when @domain - * is destroyed + * is destroyed * * Sets the callback that @domain will use to authenticate incoming - * requests. For each request containing authorization, @domain will - * invoke the callback, and then either accept or reject the request - * based on @callback's return value. + * requests. + * + * For each request containing authorization, @domain will invoke the callback, + * and then either accept or reject the request based on @callback's return + * value. * * You can also set the auth callback by setting the - * SoupAuthDomainBasic:auth-callback and - * SoupAuthDomainBasic:auth-data properties, which can also be - * used to set the callback at construct time. + * property@AuthDomainBasic:auth-callback and + * property@AuthDomainBasic:auth-data properties, which can also be used to + * set the callback at construct time. **/ void soup_auth_domain_basic_set_auth_callback (SoupAuthDomain *domain, @@ -322,9 +322,9 @@ object_class->get_property = soup_auth_domain_basic_get_property; /** - * SoupAuthDomainBasic:auth-callback: (type SoupAuthDomainBasicAuthCallback) + * SoupAuthDomainBasic:auth-callback: (type SoupAuthDomainBasicAuthCallback) (attributes org.gtk.Property.set=soup_auth_domain_basic_set_auth_callback) * - * The #SoupAuthDomainBasicAuthCallback + * The callback@AuthDomainBasicAuthCallback. */ propertiesPROP_AUTH_CALLBACK = g_param_spec_pointer ("auth-callback", @@ -335,7 +335,7 @@ /** * SoupAuthDomainBasic:auth-data: * - * The data to pass to the #SoupAuthDomainBasicAuthCallback + * The data to pass to the callback@AuthDomainBasicAuthCallback. */ propertiesPROP_AUTH_DATA = g_param_spec_pointer ("auth-data",
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/server/soup-auth-domain-digest.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/server/soup-auth-domain-digest.c
Changed
@@ -13,23 +13,19 @@ #include <stdlib.h> #include "soup-auth-domain-digest.h" +#include "soup-auth-domain-private.h" #include "soup-uri-utils-private.h" #include "soup-message-headers-private.h" #include "soup.h" #include "auth/soup-auth-digest-private.h" /** - * SECTION:soup-auth-domain-digest - * @short_description: Server-side "Digest" authentication + * SoupAuthDomainDigest: + * + * Server-side "Digest" authentication. * * #SoupAuthDomainDigest handles the server side of HTTP "Digest" * authentication. - **/ - -/** - * SoupAuthDomainDigest: - * - * Subclass of #SoupAuthDomain for Digest authentication. */ enum { @@ -122,10 +118,11 @@ * @optname1: name of first option, or %NULL * @...: option name/value pairs * - * Creates a #SoupAuthDomainDigest. You must set the - * SoupAuthDomain:realm property, to indicate the realm name to be - * returned with the authentication challenge to the client. Other - * parameters are optional. + * Creates a #SoupAuthDomainDigest. + * + * You must set the property@AuthDomain:realm property, to indicate the realm name to + * be returned with the authentication challenge to the client. Other parameters + * are optional. * * Returns: the new #SoupAuthDomain **/ @@ -150,35 +147,38 @@ * @domain: (type SoupAuthDomainDigest): the domain * @msg: the message being authenticated * @username: the username provided by the client - * @user_data: the data passed to soup_auth_domain_digest_set_auth_callback() + * @user_data: the data passed to method@AuthDomainDigest.set_auth_callback * * Callback used by #SoupAuthDomainDigest for authentication purposes. + * * The application should look up @username in its password database, * and return the corresponding encoded password (see - * soup_auth_domain_digest_encode_password()). + * func@AuthDomainDigest.encode_password. * * Returns: (nullable): the encoded password, or %NULL if - * @username is not a valid user. @domain will free the password when - * it is done with it. + * @username is not a valid user. @domain will free the password when + * it is done with it. **/ /** - * soup_auth_domain_digest_set_auth_callback: + * soup_auth_domain_digest_set_auth_callback: (attributes org.gtk.Method.set_property=auth-callback) * @domain: (type SoupAuthDomainDigest): the domain * @callback: the callback * @user_data: data to pass to @auth_callback * @dnotify: destroy notifier to free @user_data when @domain - * is destroyed + * is destroyed * * Sets the callback that @domain will use to authenticate incoming - * requests. For each request containing authorization, @domain will + * requests. + * + * For each request containing authorization, @domain will * invoke the callback, and then either accept or reject the request * based on @callback's return value. * * You can also set the auth callback by setting the - * SoupAuthDomainDigest:auth-callback and - * SoupAuthDomainDigest:auth-data properties, which can also be - * used to set the callback at construct time. + * property@AuthDomainDigest:auth-callback and + * property@AuthDomainDigest:auth-data properties, which can also be used to + * set the callback at construct time. **/ void soup_auth_domain_digest_set_auth_callback (SoupAuthDomain *domain, @@ -354,8 +354,10 @@ * @password: the password for @username in @realm * * Encodes the username/realm/password triplet for Digest - * authentication. (That is, it returns a stringified MD5 hash of - * @username, @realm, and @password concatenated together). This is + * authentication. + * + * That is, it returns a stringified MD5 hash of + * @username, @realm, and @password concatenated together. This is * the form that is needed as the return value of * #SoupAuthDomainDigest's auth handler. * @@ -431,9 +433,9 @@ object_class->get_property = soup_auth_domain_digest_get_property; /** - * SoupAuthDomainDigest:auth-callback: (type SoupAuthDomainDigestAuthCallback) + * SoupAuthDomainDigest:auth-callback: (type SoupAuthDomainDigestAuthCallback) (attributes org.gtk.Property.set=soup_auth_domain_digest_set_auth_callback) * - * The #SoupAuthDomainDigestAuthCallback + * The callback@AuthDomainDigestAuthCallback. */ propertiesPROP_AUTH_CALLBACK = g_param_spec_pointer ("auth-callback", @@ -444,7 +446,7 @@ /** * SoupAuthDomainDigest:auth-data: * - * The data to pass to the #SoupAuthDomainDigestAuthCallback + * The data to pass to the callback@AuthDomainDigestAuthCallback. */ propertiesPROP_AUTH_DATA = g_param_spec_pointer ("auth-data",
View file
_service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/server/soup-auth-domain-private.h
Added
@@ -0,0 +1,12 @@ +/* + * Copyright (C) 2007 Novell, Inc. + * Copyright (C) 2022 Igalia S.L. + */ + +#pragma once + +#include "soup-auth-domain.h" + +gboolean soup_auth_domain_try_generic_auth_callback (SoupAuthDomain *domain, + SoupServerMessage *msg, + const char *username);
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/server/soup-auth-domain.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/server/soup-auth-domain.c
Changed
@@ -11,41 +11,33 @@ #include <string.h> -#include "soup-auth-domain.h" +#include "soup-auth-domain-private.h" #include "soup-message-headers-private.h" #include "soup.h" #include "soup-path-map.h" /** - * SECTION:soup-auth-domain - * @short_description: Server-side authentication - * @see_also: #SoupServer + * SoupAuthDomain: + * + * Server-side authentication. * * A #SoupAuthDomain manages authentication for all or part of a - * #SoupServer. To make a server require authentication, first create + * class@Server. To make a server require authentication, first create * an appropriate subclass of #SoupAuthDomain, and then add it to the - * server with soup_server_add_auth_domain(). - * - * In order for an auth domain to have any effect, you must add one or - * more paths to it (via soup_auth_domain_add_path() or the - * SoupAuthDomain:add-path property). To require authentication for - * all ordinary requests, add the path "/". (Note that this does not - * include the special "*" URI (eg, "OPTIONS *"), which must be added - * as a separate path if you want to cover it.) - * - * If you need greater control over which requests should and - * shouldn't be authenticated, add paths covering everything you - * <emphasis>might</emphasis> want authenticated, and then use a - * filter (soup_auth_domain_set_filter()) to bypass authentication for - * those requests that don't need it. + * server with method@Server.add_auth_domain. + * + * In order for an auth domain to have any effect, you must add one or more + * paths to it (via method@AuthDomain.add_path). To require authentication for + * all ordinary requests, add the path `"/"`. (Note that this does not include + * the special `"*"` URI (eg, "OPTIONS *"), which must be added as a separate + * path if you want to cover it.) + * + * If you need greater control over which requests should and shouldn't be + * authenticated, add paths covering everything you *might* want authenticated, + * and then use a filter (method@AuthDomain.set_filter to bypass + * authentication for those requests that don't need it. **/ -/** - * SoupAuthDomain: - * - * Class managing authentication for #SoupServer. - */ - enum { PROP_0, @@ -183,6 +175,11 @@ object_class->set_property = soup_auth_domain_set_property; object_class->get_property = soup_auth_domain_get_property; + /** + * SoupAuthDomain:realm: (attributes org.gtk.Property.get=soup_auth_domain_get_realm) + * + * The realm of this auth domain. + */ propertiesPROP_REALM = g_param_spec_string ("realm", "Realm", @@ -191,6 +188,11 @@ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + /** + * SoupAuthDomain:proxy: + * + * Whether or not this is a proxy auth domain. + */ propertiesPROP_PROXY = g_param_spec_boolean ("proxy", "Proxy", @@ -200,9 +202,9 @@ G_PARAM_STATIC_STRINGS); /** - * SoupAuthDomain:filter: (type SoupAuthDomainFilter) + * SoupAuthDomain:filter: (type SoupAuthDomainFilter) (attributes org.gtk.Property.set=soup_auth_domain_set_filter) * - * The #SoupAuthDomainFilter for the domain. + * The callback@AuthDomainFilter for the domain. */ propertiesPROP_FILTER = g_param_spec_pointer ("filter", @@ -213,7 +215,7 @@ /** * SoupAuthDomain:filter-data: * - * Data to pass to the #SoupAuthDomainFilter. + * Data to pass to the callback@AuthDomainFilter. **/ propertiesPROP_FILTER_DATA = g_param_spec_pointer ("filter-data", @@ -222,9 +224,9 @@ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** - * SoupAuthDomain:generic-auth-callback: (type SoupAuthDomainGenericAuthCallback) + * SoupAuthDomain:generic-auth-callback: (type SoupAuthDomainGenericAuthCallback) (attributes org.gtk.Property.set=soup_auth_domain_set_generic_auth_callback) * - * The #SoupAuthDomainGenericAuthCallback. + * The callback@AuthDomainGenericAuthCallback. **/ propertiesPROP_GENERIC_AUTH_CALLBACK = g_param_spec_pointer ("generic-auth-callback", @@ -235,7 +237,7 @@ /** * SoupAuthDomain:generic-auth-data: * - * The data to pass to the #SoupAuthDomainGenericAuthCallback. + * The data to pass to the callback@AuthDomainGenericAuthCallback. **/ propertiesPROP_GENERIC_AUTH_DATA = g_param_spec_pointer ("generic-auth-data", @@ -252,13 +254,11 @@ * @domain: a #SoupAuthDomain * @path: the path to add to @domain * - * Adds @path to @domain, such that requests under @path on @domain's - * server will require authentication (unless overridden by - * soup_auth_domain_remove_path() or soup_auth_domain_set_filter()). + * Adds @path to @domain. * - * You can also add paths by setting the SoupAuthDomain:add-path - * property, which can also be used to add one or more paths at - * construct time. + * Requests under @path on @domain's server will require authentication (unless + * overridden by method@AuthDomain.remove_path or + * method@AuthDomain.set_filter). **/ void soup_auth_domain_add_path (SoupAuthDomain *domain, const char *path) @@ -277,20 +277,18 @@ * @domain: a #SoupAuthDomain * @path: the path to remove from @domain * - * Removes @path from @domain, such that requests under @path on - * @domain's server will NOT require authentication. + * Removes @path from @domain. + * + * Requests under @path on @domain's server will NOT require + * authentication. * - * This is not simply an undo-er for soup_auth_domain_add_path(); it + * This is not simply an undo-er for method@AuthDomain.add_path; it * can be used to "carve out" a subtree that does not require * authentication inside a hierarchy that does. Note also that unlike - * with soup_auth_domain_add_path(), this cannot be overridden by + * with method@AuthDomain.add_path, this cannot be overridden by * adding a filter, as filters can only bypass authentication that * would otherwise be required, not require it where it would * otherwise be unnecessary. - * - * You can also remove paths by setting the - * SoupAuthDomain:remove-path property, which can also be used to - * remove one or more paths at construct time. **/ void soup_auth_domain_remove_path (SoupAuthDomain *domain, const char *path) @@ -308,27 +306,29 @@ * SoupAuthDomainFilter: * @domain: a #SoupAuthDomain * @msg: a #SoupServerMessage - * @user_data: the data passed to soup_auth_domain_set_filter() + * @user_data: the data passed to method@AuthDomain.set_filter * - * The prototype for a #SoupAuthDomain filter; see - * soup_auth_domain_set_filter() for details. + * The prototype for a #SoupAuthDomain filter. + * + * See method@AuthDomain.set_filter for details. * * Returns: %TRUE if @msg requires authentication, %FALSE if not. **/ /** - * soup_auth_domain_set_filter: + * soup_auth_domain_set_filter: (attributes org.gtk.Method.set_property=filter) * @domain: a #SoupAuthDomain * @filter: the auth filter for @domain * @filter_data: data to pass to @filter * @dnotify: destroy notifier to free @filter_data when @domain - * is destroyed + * is destroyed + * + * Adds @filter as an authentication filter to @domain. * - * Adds @filter as an authentication filter to @domain. The filter - * gets a chance to bypass authentication for certain requests that
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/server/soup-auth-domain.h -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/server/soup-auth-domain.h
Changed
@@ -74,10 +74,4 @@ void soup_auth_domain_challenge (SoupAuthDomain *domain, SoupServerMessage *msg); -/* protected */ -SOUP_AVAILABLE_IN_ALL -gboolean soup_auth_domain_try_generic_auth_callback (SoupAuthDomain *domain, - SoupServerMessage *msg, - const char *username); - G_END_DECLS
View file
_service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/server/soup-listener.c
Added
@@ -0,0 +1,378 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ +/* + * soup-listener.c: Socket listening networking code. + * + * Copyright (C) 2022 Igalia S.L. + * Copyright (C) 2000-2003, Ximian, Inc. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <string.h> + +#include <glib/gi18n-lib.h> +#include <gio/gnetworking.h> + +#include "soup-listener.h" +#include "soup.h" +#include "soup-io-stream.h" +#include "soup-server-connection.h" + +enum { + NEW_CONNECTION, + LAST_SIGNAL +}; + +static guint signalsLAST_SIGNAL = { 0 }; + +enum { + PROP_0, + + PROP_SOCKET, + PROP_TLS_CERTIFICATE, + PROP_TLS_DATABASE, + PROP_TLS_AUTH_MODE, + + LAST_PROPERTY +}; + +static GParamSpec *propertiesLAST_PROPERTY = { NULL, }; + +struct _SoupListener { + GObject parent_instance; +}; + +typedef struct { + GSocket *socket; + GIOStream *conn; + GIOStream *iostream; + GInetSocketAddress *local_addr; + + GTlsCertificate *tls_certificate; + GTlsDatabase *tls_database; + GTlsAuthenticationMode tls_auth_mode; + + GSource *source; +} SoupListenerPrivate; + +G_DEFINE_FINAL_TYPE_WITH_PRIVATE (SoupListener, soup_listener, G_TYPE_OBJECT) + +static void +soup_listener_init (SoupListener *listener) +{ +} + +static gboolean +listen_watch (GObject *pollable, + SoupListener *listener) +{ + SoupListenerPrivate *priv = soup_listener_get_instance_private (listener); + GSocket *socket; + SoupServerConnection *conn; + + socket = g_socket_accept (priv->socket, NULL, NULL); + if (!socket) + return G_SOURCE_REMOVE; + + conn = soup_server_connection_new (socket, priv->tls_certificate, priv->tls_database, priv->tls_auth_mode); + g_signal_emit (listener, signalsNEW_CONNECTION, 0, conn); + g_object_unref (conn); + + return G_SOURCE_CONTINUE; +} + +static void +soup_listener_constructed (GObject *object) +{ + SoupListener *listener = SOUP_LISTENER (object); + SoupListenerPrivate *priv = soup_listener_get_instance_private (listener); + + g_socket_set_option (priv->socket, IPPROTO_TCP, TCP_NODELAY, TRUE, NULL); + + priv->conn = (GIOStream *)g_socket_connection_factory_create_connection (priv->socket); + priv->iostream = soup_io_stream_new (priv->conn, FALSE); + priv->source = g_pollable_input_stream_create_source (G_POLLABLE_INPUT_STREAM (g_io_stream_get_input_stream (priv->iostream)), NULL); + g_source_set_callback (priv->source, (GSourceFunc)listen_watch, listener, NULL); + g_source_attach (priv->source, g_main_context_get_thread_default ()); + + G_OBJECT_CLASS (soup_listener_parent_class)->constructed (object); +} + +static void +soup_listener_finalize (GObject *object) +{ + SoupListener *listener = SOUP_LISTENER (object); + SoupListenerPrivate *priv = soup_listener_get_instance_private (listener); + + if (priv->conn) { + g_io_stream_close (priv->conn, NULL, NULL); + g_clear_object (&priv->conn); + } + + g_clear_object (&priv->socket); + g_clear_object (&priv->iostream); + + g_clear_object (&priv->tls_certificate); + g_clear_object (&priv->tls_database); + + if (priv->source) { + g_source_destroy (priv->source); + g_source_unref (priv->source); + } + + G_OBJECT_CLASS (soup_listener_parent_class)->finalize (object); +} + +static void +soup_listener_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + SoupListener *listener = SOUP_LISTENER (object); + SoupListenerPrivate *priv = soup_listener_get_instance_private (listener); + + switch (prop_id) { + case PROP_SOCKET: + priv->socket = g_value_dup_object (value); + break; + case PROP_TLS_CERTIFICATE: + priv->tls_certificate = g_value_dup_object (value); + break; + case PROP_TLS_DATABASE: + priv->tls_database = g_value_dup_object (value); + break; + case PROP_TLS_AUTH_MODE: + priv->tls_auth_mode = g_value_get_enum (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +soup_listener_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + SoupListener *listener = SOUP_LISTENER (object); + SoupListenerPrivate *priv = soup_listener_get_instance_private (listener); + + switch (prop_id) { + case PROP_SOCKET: + g_value_set_object (value, priv->socket); + break; + case PROP_TLS_CERTIFICATE: + g_value_set_object (value, priv->tls_certificate); + break; + case PROP_TLS_DATABASE: + g_value_set_object (value, priv->tls_database); + break; + case PROP_TLS_AUTH_MODE: + g_value_set_enum (value, priv->tls_auth_mode); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +soup_listener_class_init (SoupListenerClass *listener_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (listener_class); + + object_class->constructed = soup_listener_constructed; + object_class->finalize = soup_listener_finalize; + object_class->set_property = soup_listener_set_property; + object_class->get_property = soup_listener_get_property; + + /** + * SoupListener::new-connection: + * @listener: the listener + * @conn: the new connection + * + * Emitted when a listening socket receives a new connection.
View file
_service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/server/soup-listener.h
Added
@@ -0,0 +1,26 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2022 Igalia S.L. + * Copyright (C) 2000-2003, Ximian, Inc. + */ + +#pragma once + +#include "soup-types.h" + +G_BEGIN_DECLS + +#define SOUP_TYPE_LISTENER (soup_listener_get_type ()) +G_DECLARE_FINAL_TYPE (SoupListener, soup_listener, SOUP, LISTENER, GObject) + +SoupListener *soup_listener_new (GSocket *socket, + GError **error); +SoupListener *soup_listener_new_for_address (GSocketAddress *address, + GError **error); + +void soup_listener_disconnect (SoupListener *listener); +gboolean soup_listener_is_ssl (SoupListener *listener); +GSocket *soup_listener_get_socket (SoupListener *listener); +GInetSocketAddress *soup_listener_get_address (SoupListener *listener); + +G_END_DECLS
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/server/soup-message-body.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/server/soup-message-body.c
Changed
@@ -15,24 +15,15 @@ #include "soup.h" /** - * SECTION:soup-message-body - * @short_description: HTTP message body - * @see_also: #SoupMessage - * - * #SoupMessageBody represents the request or response body of a - * #SoupMessage. - **/ - -/** * SoupMemoryUse: * @SOUP_MEMORY_STATIC: The memory is statically allocated and - * constant; libsoup can use the passed-in buffer directly and not - * need to worry about it being modified or freed. + * constant; libsoup can use the passed-in buffer directly and not + * need to worry about it being modified or freed. * @SOUP_MEMORY_TAKE: The caller has allocated the memory and libsoup - * will assume ownership of it and free it with g_free(). + * will assume ownership of it and free it with func@GLib.free. * @SOUP_MEMORY_COPY: The passed-in data belongs to the caller and - * libsoup will copy it into new memory leaving the caller free - * to reuse the original memory. + * libsoup will copy it into new memory leaving the caller free + * to reuse the original memory. * * The lifetime of the memory being passed. **/ @@ -42,18 +33,19 @@ * @data: (array length=length) (element-type guint8): the data * @length: length of @data * - * A #SoupMessage request or response body. + * #SoupMessageBody represents the request or response body of a + * class@Message. * * Note that while @length always reflects the full length of the * message body, @data is normally %NULL, and will only be filled in - * after soup_message_body_flatten() is called. For client-side + * after method@MessageBody.flatten is called. For client-side * messages, this automatically happens for the response body after it * has been fully read. Likewise, for server-side * messages, the request body is automatically filled in after being * read. * * As an added bonus, when @data is filled in, it is always terminated - * with a '\0' byte (which is not reflected in @length). + * with a `\0` byte (which is not reflected in @length). **/ typedef struct { @@ -67,7 +59,9 @@ /** * soup_message_body_new: * - * Creates a new #SoupMessageBody. #SoupMessage uses this internally; you + * Creates a new #SoupMessageBody. + * + * class@Message uses this internally; you * will not normally need to call it yourself. * * Returns: a new #SoupMessageBody. @@ -88,19 +82,19 @@ * @body: a #SoupMessageBody * @accumulate: whether or not to accumulate body chunks in @body * - * Sets or clears the accumulate flag on @body. (The default value is - * %TRUE.) If set to %FALSE, @body's data field will not be filled in - * after the body is fully sent/received, and the chunks that make up - * @body may be discarded when they are no longer needed. + * Sets or clears the accumulate flag on @body. + * + * (The default value is %TRUE.) If set to %FALSE, @body's data field will not + * be filled in after the body is fully sent/received, and the chunks that make + * up @body may be discarded when they are no longer needed. * - * If you set the flag to %FALSE on the #SoupMessage request_body of a + * If you set the flag to %FALSE on the class@Message request_body of a * client-side message, it will block the accumulation of chunks into * @body's data field, but it will not normally cause the chunks to * be discarded after being written like in the server-side - * #SoupMessage response_body case, because the request body needs to + * class@Message response_body case, because the request body needs to * be kept around in case the request needs to be sent a second time * due to redirection or authentication. - * **/ void soup_message_body_set_accumulate (SoupMessageBody *body, @@ -115,11 +109,11 @@ * soup_message_body_get_accumulate: * @body: a #SoupMessageBody * - * Gets the accumulate flag on @body; see - * soup_message_body_set_accumulate() for details. + * Gets the accumulate flag on @body. * - * Returns: the accumulate flag for @body. + * See method@MessageBody.set_accumulate. for details. * + * Returns: the accumulate flag for @body. **/ gboolean soup_message_body_get_accumulate (SoupMessageBody *body) @@ -180,10 +174,9 @@ * * Appends @length bytes from @data to @body. * - * This function is exactly equivalent to soup_message_body_append() + * This function is exactly equivalent to method@MessageBody.append * with %SOUP_MEMORY_TAKE as second argument; it exists mainly for * convenience and simplifying language bindings. - * **/ void soup_message_body_append_take (SoupMessageBody *body, @@ -229,8 +222,9 @@ * soup_message_body_complete: * @body: a #SoupMessageBody * - * Tags @body as being complete; Call this when using chunked encoding - * after you have appended the last chunk. + * Tags @body as being complete. + * + * Call this when using chunked encoding after you have appended the last chunk. **/ void soup_message_body_complete (SoupMessageBody *body) @@ -243,11 +237,13 @@ * @body: a #SoupMessageBody * * Fills in @body's data field with a buffer containing all of the - * data in @body (plus an additional '\0' byte not counted by @body's - * length field). + * data in @body. * - * Return: (transfer full): a #GBytes containing the same data as @body. - * (You must g_bytes_unref() this if you do not want it.) + * Adds an additional `\0` byte not counted by @body's + * length field. + * + * Returns: (transfer full): a #GBytes containing the same data as @body. + * (You must method@GLib.Bytes.unref this if you do not want it.) **/ GBytes * soup_message_body_flatten (SoupMessageBody *body) @@ -284,23 +280,24 @@ * @body: a #SoupMessageBody * @offset: an offset * - * Gets a #GBytes containing data from @body starting at @offset. + * Gets a struct@GLib.Bytes containing data from @body starting at @offset. + * * The size of the returned chunk is unspecified. You can iterate * through the entire body by first calling - * soup_message_body_get_chunk() with an offset of 0, and then on each + * method@MessageBody.get_chunk with an offset of 0, and then on each * successive call, increment the offset by the length of the * previously-returned chunk. * * If @offset is greater than or equal to the total length of @body, * then the return value depends on whether or not - * soup_message_body_complete() has been called or not; if it has, - * then soup_message_body_get_chunk() will return a 0-length chunk + * method@MessageBody.complete has been called or not; if it has, + * then method@MessageBody.get_chunk will return a 0-length chunk * (indicating the end of @body). If it has not, then - * soup_message_body_get_chunk() will return %NULL (indicating that + * method@MessageBody.get_chunk will return %NULL (indicating that * @body may still potentially have more data, but that data is not * currently available). * - * Returns: (nullable): a #GBytes, or %NULL. + * Returns: (nullable): a #GBytes **/ GBytes * soup_message_body_get_chunk (SoupMessageBody *body, goffset offset) @@ -332,13 +329,14 @@ * @chunk: a #GBytes received from the network * * Handles the #SoupMessageBody part of receiving a chunk of data from - * the network. Normally this means appending @chunk to @body, exactly - * as with soup_message_body_append_bytes(), but if you have set - * @body's accumulate flag to %FALSE, then that will not happen. + * the network. + * + * Normally this means appending @chunk to @body, exactly as with + * method@MessageBody.append_bytes, but if you have set @body's accumulate + * flag to %FALSE, then that will not happen. * * This is a low-level method which you should not normally need to * use. - * **/ void soup_message_body_got_chunk (SoupMessageBody *body, GBytes *chunk) @@ -354,17 +352,17 @@ /**
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/server/soup-path-map.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/server/soup-path-map.c
Changed
@@ -34,7 +34,7 @@ /** * soup_path_map_new: * @data_free_func: function to use to free data added with - * soup_path_map_add(). + * soup_path_map_add(). * * Creates a new %SoupPathMap. * @@ -176,7 +176,7 @@ * closest parent directory of @path that has data associated with it. * * Returns: (nullable): the data set with soup_path_map_add(), or - * %NULL if no data could be found for @path or any of its ancestors. + * %NULL if no data could be found for @path or any of its ancestors. **/ gpointer soup_path_map_lookup (SoupPathMap *map, const char *path)
View file
_service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/server/soup-server-connection.c
Added
@@ -0,0 +1,753 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ +/* + * soup-server-connection.c: Connection networking code. + * + * Copyright (C) 2022 Igalia S.L. + * Copyright (C) 2000-2003, Ximian, Inc. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <string.h> + +#include <glib/gi18n-lib.h> +#include <gio/gnetworking.h> + +#include "soup-server-connection.h" +#include "soup.h" +#include "soup-io-stream.h" +#include "soup-server-message-private.h" +#include "soup-server-message-io-http1.h" +#include "soup-server-message-io-http2.h" + +enum { + CONNECTED, + DISCONNECTED, + ACCEPT_CERTIFICATE, + REQUEST_STARTED, + LAST_SIGNAL +}; + +static guint signalsLAST_SIGNAL = { 0 }; + +enum { + PROP_0, + + PROP_SOCKET, + PROP_CONNECTION, + PROP_LOCAL_ADDRESS, + PROP_REMOTE_ADDRESS, + PROP_TLS_CERTIFICATE, + PROP_TLS_DATABASE, + PROP_TLS_AUTH_MODE, + PROP_TLS_PEER_CERTIFICATE, + PROP_TLS_PEER_CERTIFICATE_ERRORS, + + LAST_PROPERTY +}; + +static GParamSpec *propertiesLAST_PROPERTY = { NULL, }; + +struct _SoupServerConnection { + GObject parent_instance; +}; + +typedef struct { + GSocket *socket; + GIOStream *conn; + GIOStream *iostream; + SoupServerMessage *initial_msg; + gboolean advertise_http2; + SoupHTTPVersion http_version; + SoupServerMessageIO *io_data; + + GSocketAddress *local_addr; + GSocketAddress *remote_addr; + + GTlsCertificate *tls_certificate; + GTlsDatabase *tls_database; + GTlsAuthenticationMode tls_auth_mode; +} SoupServerConnectionPrivate; + +G_DEFINE_FINAL_TYPE_WITH_PRIVATE (SoupServerConnection, soup_server_connection, G_TYPE_OBJECT) + +static void +request_started_cb (SoupServerMessage *msg, + SoupServerConnection *conn) +{ + g_signal_emit (conn, signalsREQUEST_STARTED, 0, msg); +} + +static void +soup_server_connection_init (SoupServerConnection *conn) +{ + SoupServerConnectionPrivate *priv = soup_server_connection_get_instance_private (conn); + + priv->http_version = SOUP_HTTP_1_1; +} + +static void +disconnect_internal (SoupServerConnection *conn) +{ + SoupServerConnectionPrivate *priv = soup_server_connection_get_instance_private (conn); + + g_clear_object (&priv->socket); + + g_io_stream_close (priv->conn, NULL, NULL); + g_signal_handlers_disconnect_by_data (priv->conn, conn); + g_clear_object (&priv->conn); + + g_clear_pointer (&priv->io_data, soup_server_message_io_destroy); +} + +static void +soup_server_connection_finalize (GObject *object) +{ + SoupServerConnection *conn = SOUP_SERVER_CONNECTION (object); + SoupServerConnectionPrivate *priv = soup_server_connection_get_instance_private (conn); + + if (priv->conn) { + disconnect_internal (conn); + } else { + g_clear_object (&priv->socket); + g_clear_pointer (&priv->io_data, soup_server_message_io_destroy); + } + + g_clear_object (&priv->iostream); + + g_clear_object (&priv->local_addr); + g_clear_object (&priv->remote_addr); + + g_clear_object (&priv->tls_certificate); + g_clear_object (&priv->tls_database); + + G_OBJECT_CLASS (soup_server_connection_parent_class)->finalize (object); +} + +static void +soup_server_connection_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + SoupServerConnection *conn = SOUP_SERVER_CONNECTION (object); + SoupServerConnectionPrivate *priv = soup_server_connection_get_instance_private (conn); + + switch (prop_id) { + case PROP_SOCKET: + priv->socket = g_value_dup_object (value); + break; + case PROP_CONNECTION: + priv->conn = g_value_dup_object (value); + if (priv->conn) + priv->iostream = soup_io_stream_new (priv->conn, FALSE); + break; + case PROP_LOCAL_ADDRESS: + priv->local_addr = g_value_dup_object (value); + break; + case PROP_REMOTE_ADDRESS: + priv->remote_addr = g_value_dup_object (value); + break; + case PROP_TLS_CERTIFICATE: + priv->tls_certificate = g_value_dup_object (value); + break; + case PROP_TLS_DATABASE: + priv->tls_database = g_value_dup_object (value); + break; + case PROP_TLS_AUTH_MODE: + priv->tls_auth_mode = g_value_get_enum (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +soup_server_connection_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + SoupServerConnection *conn = SOUP_SERVER_CONNECTION (object); + SoupServerConnectionPrivate *priv = soup_server_connection_get_instance_private (conn); + + switch (prop_id) { + case PROP_SOCKET: + g_value_set_object (value, priv->socket); + break; + case PROP_CONNECTION: + g_value_set_object (value, priv->conn); + break; + case PROP_LOCAL_ADDRESS: + g_value_set_object (value, soup_server_connection_get_local_address (conn)); + break; + case PROP_REMOTE_ADDRESS: + g_value_set_object (value, soup_server_connection_get_remote_address (conn)); + break; + case PROP_TLS_CERTIFICATE: + g_value_set_object (value, priv->tls_certificate); + break; + case PROP_TLS_DATABASE: + g_value_set_object (value, priv->tls_database); + break; + case PROP_TLS_AUTH_MODE: + g_value_set_enum (value, priv->tls_auth_mode); + break; + case PROP_TLS_PEER_CERTIFICATE:
View file
_service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/server/soup-server-connection.h
Added
@@ -0,0 +1,40 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2022 Igalia S.L. + * Copyright (C) 2000-2003, Ximian, Inc. + */ + +#pragma once + +#include "soup-types.h" +#include "soup-server-message-io.h" +#include <gio/gio.h> + +G_BEGIN_DECLS + +#define SOUP_TYPE_SERVER_CONNECTION (soup_server_connection_get_type ()) +G_DECLARE_FINAL_TYPE (SoupServerConnection, soup_server_connection, SOUP, SERVER_CONNECTION, GObject) + +SoupServerConnection *soup_server_connection_new (GSocket *socket, + GTlsCertificate *tls_certificate, + GTlsDatabase *tls_database, + GTlsAuthenticationMode tls_auth_mode); +SoupServerConnection *soup_server_connection_new_for_connection (GIOStream *connection, + GSocketAddress *local_addr, + GSocketAddress *remote_addr); +void soup_server_connection_set_advertise_http2 (SoupServerConnection *conn, + gboolean advertise_http2); +void soup_server_connection_accepted (SoupServerConnection *conn); +SoupServerMessageIO *soup_server_connection_get_io_data (SoupServerConnection *conn); +gboolean soup_server_connection_is_ssl (SoupServerConnection *conn); +void soup_server_connection_disconnect (SoupServerConnection *conn); +gboolean soup_server_connection_is_connected (SoupServerConnection *conn); +GSocket *soup_server_connection_get_socket (SoupServerConnection *conn); +GIOStream *soup_server_connection_steal (SoupServerConnection *conn); +GIOStream *soup_server_connection_get_iostream (SoupServerConnection *conn); +GSocketAddress *soup_server_connection_get_local_address (SoupServerConnection *conn); +GSocketAddress *soup_server_connection_get_remote_address (SoupServerConnection *conn); +GTlsCertificate *soup_server_connection_get_tls_peer_certificate (SoupServerConnection *conn); +GTlsCertificateFlags soup_server_connection_get_tls_peer_certificate_errors (SoupServerConnection *conn); + +G_END_DECLS
View file
_service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/server/soup-server-message-io.c
Added
@@ -0,0 +1,62 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2022 Igalia S.L. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "soup-server-message-io.h" + +void +soup_server_message_io_destroy (SoupServerMessageIO *io) +{ + if (!io) + return; + + io->funcs->destroy (io); +} + +void +soup_server_message_io_finished (SoupServerMessageIO *io, + SoupServerMessage *msg) +{ + io->funcs->finished (io, msg); +} + +GIOStream * +soup_server_message_io_steal (SoupServerMessageIO *io) +{ + return io->funcs->steal (io); +} + +void +soup_server_message_io_read_request (SoupServerMessageIO *io, + SoupServerMessage *msg, + SoupMessageIOCompletionFn completion_cb, + gpointer user_data) +{ + io->funcs->read_request (io, msg, completion_cb, user_data); +} + +void +soup_server_message_io_pause (SoupServerMessageIO *io, + SoupServerMessage *msg) +{ + io->funcs->pause (io, msg); +} + +void +soup_server_message_io_unpause (SoupServerMessageIO *io, + SoupServerMessage *msg) +{ + io->funcs->unpause (io, msg); +} + +gboolean +soup_server_message_io_is_paused (SoupServerMessageIO *io, + SoupServerMessage *msg) +{ + return io->funcs->is_paused (io, msg); +}
View file
_service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/server/soup-server-message-io.h
Added
@@ -0,0 +1,50 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2022 Igalia S.L. + */ + +#pragma once + +#include "soup-server-message.h" +#include "soup-message-io-completion.h" + +typedef struct _SoupServerMessageIO SoupServerMessageIO; + +typedef struct { + void (*destroy) (SoupServerMessageIO *io); + void (*finished) (SoupServerMessageIO *io, + SoupServerMessage *msg); + GIOStream *(*steal) (SoupServerMessageIO *io); + void (*read_request) (SoupServerMessageIO *io, + SoupServerMessage *msg, + SoupMessageIOCompletionFn completion_cb, + gpointer user_data); + void (*pause) (SoupServerMessageIO *io, + SoupServerMessage *msg); + void (*unpause) (SoupServerMessageIO *io, + SoupServerMessage *msg); + gboolean (*is_paused) (SoupServerMessageIO *io, + SoupServerMessage *msg); +} SoupServerMessageIOFuncs; + +struct _SoupServerMessageIO { + const SoupServerMessageIOFuncs *funcs; +}; + +typedef void (* SoupMessageIOStartedFn) (SoupServerMessage *msg, + gpointer user_data); + +void soup_server_message_io_destroy (SoupServerMessageIO *io); +void soup_server_message_io_finished (SoupServerMessageIO *io, + SoupServerMessage *msg); +GIOStream *soup_server_message_io_steal (SoupServerMessageIO *io); +void soup_server_message_io_read_request (SoupServerMessageIO *io, + SoupServerMessage *msg, + SoupMessageIOCompletionFn completion_cb, + gpointer user_data); +void soup_server_message_io_pause (SoupServerMessageIO *io, + SoupServerMessage *msg); +void soup_server_message_io_unpause (SoupServerMessageIO *io, + SoupServerMessage *msg); +gboolean soup_server_message_io_is_paused (SoupServerMessageIO *io, + SoupServerMessage *msg);
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/server/soup-server-message-private.h -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/server/soup-server-message-private.h
Changed
@@ -8,23 +8,20 @@ #include "soup-server-message.h" #include "soup-auth-domain.h" #include "soup-message-io-data.h" -#include "soup-socket.h" +#include "soup-server-connection.h" -SoupServerMessage *soup_server_message_new (SoupSocket *sock); +SoupServerMessage *soup_server_message_new (SoupServerConnection *conn); void soup_server_message_set_uri (SoupServerMessage *msg, GUri *uri); void soup_server_message_set_method (SoupServerMessage *msg, const char *method); -SoupSocket *soup_server_message_get_soup_socket (SoupServerMessage *msg); +SoupServerConnection *soup_server_message_get_connection (SoupServerMessage *msg); void soup_server_message_set_auth (SoupServerMessage *msg, SoupAuthDomain *domain, char *user); gboolean soup_server_message_is_keepalive (SoupServerMessage *msg); -GIOStream *soup_server_message_io_steal (SoupServerMessage *msg); -void soup_server_message_io_pause (SoupServerMessage *msg); -void soup_server_message_io_unpause (SoupServerMessage *msg); gboolean soup_server_message_is_io_paused (SoupServerMessage *msg); -void soup_server_message_io_finished (SoupServerMessage *msg); +void soup_server_message_finish (SoupServerMessage *msg); void soup_server_message_cleanup_response (SoupServerMessage *msg); void soup_server_message_wrote_informational (SoupServerMessage *msg); void soup_server_message_wrote_headers (SoupServerMessage *msg); @@ -40,13 +37,11 @@ void soup_server_message_read_request (SoupServerMessage *msg, SoupMessageIOCompletionFn completion_cb, gpointer user_data); + void soup_server_message_set_options_ping (SoupServerMessage *msg, gboolean is_options_ping); -typedef struct _SoupServerMessageIOData SoupServerMessageIOData; -void soup_server_message_io_data_free (SoupServerMessageIOData *io); -void soup_server_message_set_io_data (SoupServerMessage *msg, - SoupServerMessageIOData *io); -SoupServerMessageIOData *soup_server_message_get_io_data (SoupServerMessage *msg); +SoupServerMessageIO *soup_server_message_get_io_data (SoupServerMessage *msg); + #endif /* __SOUP_SERVER_MESSAGE_PRIVATE_H__ */
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/server/soup-server-message.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/server/soup-server-message.c
Changed
@@ -15,44 +15,33 @@ #include "soup-connection.h" #include "soup-server-message-private.h" #include "soup-message-headers-private.h" -#include "soup-socket.h" #include "soup-uri-utils-private.h" /** - * SECTION:soup-server-message - * @short_description: An HTTP server request and response. - * @see_also: #SoupMessageHeaders, #SoupMessageBody + * SoupServerMessage: + * + * An HTTP server request and response pair. * * A SoupServerMessage represents an HTTP message that is being sent or - * received on a #SoupServer + * received on a class@Server. * - * #SoupServer will create #SoupServerMessage<!-- -->s automatically for + * class@Server will create `SoupServerMessage`s automatically for * incoming requests, which your application will receive via handlers. * * Note that libsoup's terminology here does not quite match the HTTP - * specification: in RFC 2616, an "HTTP-message" is - * <emphasis>either</emphasis> a Request, <emphasis>or</emphasis> a - * Response. In libsoup, a #SoupServerMessage combines both the request and - * the response. + * specification: in RFC 2616, an "HTTP-message" is *either* a Request, *or* a + * Response. In libsoup, a #SoupServerMessage combines both the request and the + * response. **/ -/** - * SoupServerMessage: - * - * Class represnting an HTTP request and response pair for a server. - */ - struct _SoupServerMessage { GObject parent; - SoupSocket *sock; - GSocket *gsock; + SoupServerConnection *conn; SoupAuthDomain *auth_domain; char *auth_user; - GSocketAddress *remote_addr; char *remote_ip; - GSocketAddress *local_addr; const char *method; SoupHTTPVersion http_version; @@ -69,9 +58,12 @@ SoupMessageBody *response_body; SoupMessageHeaders *response_headers; - SoupServerMessageIOData *io_data; + SoupServerMessageIO *io_data; gboolean options_ping; + + GTlsCertificate *tls_peer_certificate; + GTlsCertificateFlags tls_peer_certificate_errors; }; struct _SoupServerMessageClass { @@ -91,6 +83,7 @@ GOT_CHUNK, GOT_BODY, + CONNECTED, DISCONNECTED, FINISHED, @@ -101,6 +94,17 @@ static guint signalsLAST_SIGNAL = { 0 }; +enum { + PROP_0, + + PROP_TLS_PEER_CERTIFICATE, + PROP_TLS_PEER_CERTIFICATE_ERRORS, + + LAST_PROPERTY +}; + +static GParamSpec *propertiesLAST_PROPERTY = { NULL, }; + static void soup_server_message_init (SoupServerMessage *msg) { @@ -116,18 +120,13 @@ { SoupServerMessage *msg = SOUP_SERVER_MESSAGE (object); - soup_server_message_io_data_free (msg->io_data); - g_clear_object (&msg->auth_domain); g_clear_pointer (&msg->auth_user, g_free); - g_clear_object (&msg->remote_addr); - g_clear_object (&msg->local_addr); - if (msg->sock) { - g_signal_handlers_disconnect_by_data (msg->sock, msg); - g_object_unref (msg->sock); + if (msg->conn) { + g_signal_handlers_disconnect_by_data (msg->conn, msg); + g_object_unref (msg->conn); } - g_clear_object (&msg->gsock); g_clear_pointer (&msg->remote_ip, g_free); g_clear_pointer (&msg->uri, g_uri_unref); @@ -142,11 +141,31 @@ } static void +soup_server_message_get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + SoupServerMessage *msg = SOUP_SERVER_MESSAGE (object); + + switch (prop_id) { + case PROP_TLS_PEER_CERTIFICATE: + g_value_set_object (value, msg->tls_peer_certificate); + break; + case PROP_TLS_PEER_CERTIFICATE_ERRORS: + g_value_set_flags (value, msg->tls_peer_certificate_errors); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void soup_server_message_class_init (SoupServerMessageClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = soup_server_message_finalize; + object_class->get_property = soup_server_message_get_property; /** * SoupServerMessage::wrote-informational: @@ -186,11 +205,11 @@ * Emitted immediately after writing a body chunk for a message. * * Note that this signal is not parallel to - * #SoupServerMessage::got-chunk; it is emitted only when a complete - * chunk (added with soup_message_body_append() or - * soup_message_body_append_bytes()) has been written. To get + * signal@ServerMessage::got-chunk; it is emitted only when a complete + * chunk (added with method@MessageBody.append or + * method@MessageBody.append_bytes has been written. To get * more useful continuous progress information, use - * #SoupServerMessage::wrote-body-data. + * signal@ServerMessage::wrote-body-data. */ signalsWROTE_CHUNK = g_signal_new ("wrote-chunk", @@ -255,10 +274,10 @@ * @msg: the message * @chunk: the just-read chunk * - * Emitted after receiving a chunk of a message body. Note - * that "chunk" in this context means any subpiece of the - * body, not necessarily the specific HTTP 1.1 chunks sent by - * the other side. + * Emitted after receiving a chunk of a message body. + * + * Note that "chunk" in this context means any subpiece of the body, not + * necessarily the specific HTTP 1.1 chunks sent by the other side. */ signalsGOT_CHUNK = g_signal_new ("got-chunk", @@ -290,7 +309,7 @@ * @msg: the message * * Emitted when all HTTP processing is finished for a message. - * (After #SoupServerMessage::wrote-body). + * (After signal@ServerMessage::wrote-body). */ signalsFINISHED = g_signal_new ("finished", @@ -300,6 +319,20 @@ NULL, NULL, NULL, G_TYPE_NONE, 0); + /** + * SoupServerMessage::connected: + * @msg: the message + * + * Emitted when the @msg's socket is connected and the TLS handshake completed. + */ + signalsCONNECTED = + g_signal_new ("connected",
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/server/soup-server-message.h -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/server/soup-server-message.h
Changed
@@ -80,6 +80,18 @@ SOUP_AVAILABLE_IN_ALL gboolean soup_server_message_is_options_ping (SoupServerMessage *msg); +SOUP_AVAILABLE_IN_3_2 +void soup_server_message_pause (SoupServerMessage *msg); + +SOUP_AVAILABLE_IN_3_2 +void soup_server_message_unpause (SoupServerMessage *msg); + +SOUP_AVAILABLE_IN_3_2 +GTlsCertificate *soup_server_message_get_tls_peer_certificate (SoupServerMessage *msg); + +SOUP_AVAILABLE_IN_3_2 +GTlsCertificateFlags soup_server_message_get_tls_peer_certificate_errors (SoupServerMessage *msg); + G_END_DECLS #endif /* __SOUP_SERVER_MESSAGE_H__ */
View file
_service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/server/soup-server-private.h
Added
@@ -0,0 +1,14 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2022, Igalia S.L. + */ + +#ifndef __SOUP_SERVER_PRIVATE_H__ +#define __SOUP_SERVER_PRIVATE_H__ 1 + +#include "soup-server.h" + +void soup_server_set_http2_enabled (SoupServer *server, + gboolean enabled); + +#endif /* __SOUP_SERVER_PRIVATE_H__ */
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/server/soup-server.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/server/soup-server.c
Changed
@@ -13,63 +13,57 @@ #include <glib/gi18n-lib.h> -#include "soup-server.h" +#include "soup-server-private.h" #include "soup-server-message-private.h" #include "soup-message-headers-private.h" #include "soup.h" #include "soup-misc.h" #include "soup-path-map.h" -#include "soup-socket.h" +#include "soup-listener.h" #include "soup-uri-utils-private.h" #include "websocket/soup-websocket.h" #include "websocket/soup-websocket-connection.h" #include "websocket/soup-websocket-extension-deflate.h" /** - * SECTION:soup-server - * @short_description: HTTP server - * @see_also: #SoupAuthDomain + * SoupServer: + * + * A HTTP server. * * #SoupServer implements a simple HTTP server. * - * (The following documentation describes the current #SoupServer API, - * available in <application>libsoup</application> 2.48 and later. See - * the section "<link linkend="soup-server-old-api">The Old SoupServer - * Listening API</link>" in the server how-to documentation for - * details on the older #SoupServer API.) - * - * To begin, create a server using soup_server_new(). Add at least one - * handler by calling soup_server_add_handler() or - * soup_server_add_early_handler(); the handler will be called to + * To begin, create a server using ctor@Server.new. Add at least one + * handler by calling method@Server.add_handler or + * method@Server.add_early_handler; the handler will be called to * process any requests underneath the path you pass. (If you want all * requests to go to the same handler, just pass "/" (or %NULL) for * the path.) * * When a new connection is accepted (or a new request is started on * an existing persistent connection), the #SoupServer will emit - * #SoupServer::request-started and then begin processing the request + * signal@Server::request-started and then begin processing the request * as described below, but note that once the message is assigned a * status-code, then callbacks after that point will be * skipped. Note also that it is not defined when the callbacks happen - * relative to various #SoupServerMessage signals. + * relative to various class@ServerMessage signals. * * Once the headers have been read, #SoupServer will check if there is - * a #SoupAuthDomain (qv) covering the Request-URI; if so, and if the + * a class@AuthDomain `(qv)` covering the Request-URI; if so, and if the * message does not contain suitable authorization, then the - * #SoupAuthDomain will set a status of %SOUP_STATUS_UNAUTHORIZED on + * class@AuthDomain will set a status of %SOUP_STATUS_UNAUTHORIZED on * the message. * * After checking for authorization, #SoupServer will look for "early" - * handlers (added with soup_server_add_early_handler()) matching the + * handlers (added with method@Server.add_early_handler) matching the * Request-URI. If one is found, it will be run; in particular, this * can be used to connect to signals to do a streaming read of the * request body. * - * (At this point, if the request headers contain "<literal>Expect: - * 100-continue</literal>", and a status code has been set, then + * (At this point, if the request headers contain `Expect: + * 100-continue`, and a status code has been set, then * #SoupServer will skip the remaining steps and return the response. - * If the request headers contain "<literal>Expect: - * 100-continue</literal>" and no status code has been set, + * If the request headers contain `Expect: + * 100-continue` and no status code has been set, * #SoupServer will return a %SOUP_STATUS_CONTINUE status before * continuing.) * @@ -80,7 +74,7 @@ * * Otherwise (assuming no previous step assigned a status to the * message) any "normal" handlers (added with - * soup_server_add_handler()) for the message's Request-URI will be + * method@Server.add_handler) for the message's Request-URI will be * run. * * Then, if the path has a WebSocket handler registered (and has @@ -90,12 +84,12 @@ * %SOUP_STATUS_BAD_REQUEST accordingly. * * If the message still has no status code at this point (and has not - * been paused with soup_server_pause_message()), then it will be + * been paused with method@ServerMessage.pause), then it will be * given a status of %SOUP_STATUS_INTERNAL_SERVER_ERROR (because at * least one handler ran, but returned without assigning a status). * - * Finally, the server will emit #SoupServer::request-finished (or - * #SoupServer::request-aborted if an I/O error occurred before + * Finally, the server will emit signal@Server::request-finished (or + * signal@Server::request-aborted if an I/O error occurred before * handling was completed). * * If you want to handle the special "*" URI (eg, "OPTIONS *"), you @@ -103,27 +97,21 @@ * will not be used for that case. * * If you want to process https connections in addition to (or instead - * of) http connections, you can set the #SoupServer:tls-certificate + * of) http connections, you can set the property@Server:tls-certificate * property. * * Once the server is set up, make one or more calls to - * soup_server_listen(), soup_server_listen_local(), or - * soup_server_listen_all() to tell it where to listen for + * method@Server.listen, method@Server.listen_local, or + * method@Server.listen_all to tell it where to listen for * connections. (All ports on a #SoupServer use the same handlers; if * you need to handle some ports differently, such as returning * different data for http and https, you'll need to create multiple - * #SoupServers, or else check the passed-in URI in the handler + * `SoupServer`s, or else check the passed-in URI in the handler * function.). * * #SoupServer will begin processing connections as soon as you return * to (or start) the main loop for the current thread-default - * #GMainContext. - */ - -/** - * SoupServer: - * - * Class implementing an HTTP server. + * struct@GLib.MainContext. */ enum { @@ -176,6 +164,7 @@ GPtrArray *websocket_extension_types; gboolean disposed; + gboolean http2_enabled; } SoupServerPrivate; @@ -197,8 +186,10 @@ G_DEFINE_TYPE_WITH_PRIVATE (SoupServer, soup_server, G_TYPE_OBJECT) -static void start_request (SoupServer *server, - SoupServerMessage *msg); +static void request_finished (SoupServerMessage *msg, + SoupMessageIOCompletion completion, + SoupServer *server); + static void free_handler (SoupServerHandler *handler) { @@ -220,6 +211,7 @@ { SoupServerPrivate *priv = soup_server_get_instance_private (server); + priv->http2_enabled = !!g_getenv ("SOUP_SERVER_HTTP2"); priv->handlers = soup_path_map_new ((GDestroyNotify)free_handler); priv->websocket_extension_types = g_ptr_array_new_with_free_func ((GDestroyNotify)g_type_class_unref); @@ -352,16 +344,17 @@ * @message: the new message * * Emitted when the server has started reading a new request. + * * @message will be completely blank; not even the * Request-Line will have been read yet. About the only thing * you can usefully do with it is connect to its signals. * * If the request is read successfully, this will eventually - * be followed by a #SoupServer::request_read signal. If a + * be followed by a signal@Server::request_read signal. If a * response is then sent, the request processing will end with - * a #SoupServer::request_finished signal. If a network error + * a signal@Server::request-finished signal. If a network error * occurs, the processing will instead end with - * #SoupServer::request_aborted. + * signal@Server::request-aborted. **/ signalsREQUEST_STARTED = g_signal_new ("request-started", @@ -379,6 +372,7 @@ * @message: the message * * Emitted when the server has successfully read a request. + * * @message will have all of its request-side information * filled in, and if the message was authenticated, @client * will have information about that. This signal is emitted @@ -419,17 +413,17 @@ * @server: the server * @message: the message
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/server/soup-server.h -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/server/soup-server.h
Changed
@@ -150,10 +150,10 @@ SoupAuthDomain *auth_domain); /* I/O */ -SOUP_AVAILABLE_IN_ALL +SOUP_DEPRECATED_IN_3_2_FOR(soup_server_message_pause) void soup_server_pause_message (SoupServer *server, SoupServerMessage *msg); -SOUP_AVAILABLE_IN_ALL +SOUP_DEPRECATED_IN_3_2_FOR(soup_server_message_unpause) void soup_server_unpause_message (SoupServer *server, SoupServerMessage *msg);
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/soup-client-message-io.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/soup-client-message-io.c
Changed
@@ -140,3 +140,10 @@ { return io->funcs->get_cancellable (io, msg); } + +void +soup_client_message_io_owner_changed (SoupClientMessageIO *io) +{ + if (io->funcs->owner_changed) + io->funcs->owner_changed (io); +}
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/soup-client-message-io.h -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/soup-client-message-io.h
Changed
@@ -55,6 +55,7 @@ gboolean (*is_reusable) (SoupClientMessageIO *io); GCancellable *(*get_cancellable) (SoupClientMessageIO *io, SoupMessage *msg); + void (*owner_changed) (SoupClientMessageIO *io); } SoupClientMessageIOFuncs; struct _SoupClientMessageIO { @@ -105,3 +106,4 @@ gboolean soup_client_message_io_is_reusable (SoupClientMessageIO *io); GCancellable *soup_client_message_io_get_cancellable (SoupClientMessageIO *io, SoupMessage *msg); +void soup_client_message_io_owner_changed (SoupClientMessageIO *io);
View file
_service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/soup-connection-manager.c
Added
@@ -0,0 +1,558 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ +/* + * Copyright 2022 Igalia S.L. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "soup-connection-manager.h" +#include "soup-message-private.h" +#include "soup-misc.h" +#include "soup-session-private.h" +#include "soup-uri-utils-private.h" +#include "soup.h" + +struct _SoupConnectionManager { + SoupSession *session; + + GMutex mutex; + GCond cond; + GSocketConnectable *remote_connectable; + guint max_conns; + guint max_conns_per_host; + guint num_conns; + + GHashTable *http_hosts; + GHashTable *https_hosts; + GHashTable *conns; + + guint64 last_connection_id; +}; + +typedef struct { + GUri *uri; + GHashTable *owner_map; + GNetworkAddress *addr; + + GList *conns; + guint num_conns; + + GSource *keep_alive_src; + SoupConnectionManager *conn_manager; +} SoupHost; + +#define HOST_KEEP_ALIVE 5 * 60 * 1000 /* 5 min in msecs */ + +static SoupHost * +soup_host_new (GUri *uri, + GHashTable *owner_map) +{ + SoupHost *host; + const char *scheme = g_uri_get_scheme (uri); + + host = g_new0 (SoupHost, 1); + host->owner_map = owner_map; + if (g_strcmp0 (scheme, "http") != 0 && g_strcmp0 (scheme, "https") != 0) { + host->uri = soup_uri_copy (uri, + SOUP_URI_SCHEME, soup_uri_is_https (uri) ? "https" : "http", + SOUP_URI_NONE); + } else + host->uri = g_uri_ref (uri); + + host->addr = g_object_new (G_TYPE_NETWORK_ADDRESS, + "hostname", g_uri_get_host (host->uri), + "port", g_uri_get_port (host->uri), + "scheme", g_uri_get_scheme (host->uri), + NULL); + + g_hash_table_insert (host->owner_map, host->uri, host); + + return host; +} + +static void +soup_host_free (SoupHost *host) +{ + g_warn_if_fail (host->conns == NULL); + + if (host->keep_alive_src) { + g_source_destroy (host->keep_alive_src); + g_source_unref (host->keep_alive_src); + } + + g_uri_unref (host->uri); + g_object_unref (host->addr); + g_free (host); +} + +/* Note that we can't use soup_uri_host_hash() and soup_uri_host_equal() + * because we want to ignore the protocol; http://example.com and + * webcal://example.com are the same host. + */ +static guint +soup_host_uri_hash (gconstpointer key) +{ + GUri *uri = (GUri*)key; + + g_warn_if_fail (uri != NULL && g_uri_get_host (uri) != NULL); + + return g_uri_get_port (uri) + soup_str_case_hash (g_uri_get_host (uri)); +} + +static gboolean +soup_host_uri_equal (gconstpointer v1, gconstpointer v2) +{ + GUri *one = (GUri*)v1; + GUri *two = (GUri*)v2; + + g_warn_if_fail (one != NULL && two != NULL); + + const char *one_host = g_uri_get_host (one); + const char *two_host = g_uri_get_host (two); + g_warn_if_fail (one_host != NULL && two_host != NULL); + + if (g_uri_get_port (one) != g_uri_get_port (two)) + return FALSE; + + return g_ascii_strcasecmp (one_host, two_host) == 0; +} + +static gboolean +free_unused_host (gpointer user_data) +{ + SoupHost *host = (SoupHost *)user_data; + + if (host->conns) + return FALSE; + + /* This will free the host in addition to removing it from the hash table */ + g_hash_table_remove (host->owner_map, host->uri); + + return FALSE; +} + +static void +soup_host_add_connection (SoupHost *host, + SoupConnection *conn) +{ + host->conns = g_list_prepend (host->conns, conn); + host->num_conns++; + + if (host->keep_alive_src) { + g_source_destroy (host->keep_alive_src); + g_source_unref (host->keep_alive_src); + host->keep_alive_src = NULL; + } +} + +static void +soup_host_remove_connection (SoupHost *host, + SoupConnection *conn) +{ + host->conns = g_list_remove (host->conns, conn); + host->num_conns--; + + /* Free the SoupHost (and its GNetworkAddress) if there + * has not been any new connection to the host during + * the last HOST_KEEP_ALIVE msecs. + */ + if (host->num_conns == 0) { + g_assert (host->keep_alive_src == NULL); + host->keep_alive_src = soup_add_timeout (g_main_context_get_thread_default (), + HOST_KEEP_ALIVE, + free_unused_host, + host); + } +} + +static SoupHost * +soup_connection_manager_get_host_for_message (SoupConnectionManager *manager, + SoupMessage *msg) +{ + GUri *uri = soup_message_get_uri (msg); + SoupHost *host; + GHashTable *map; + + map = soup_uri_is_https (uri) ? manager->https_hosts : manager->http_hosts; + host = g_hash_table_lookup (map, uri); + if (!host) + host = soup_host_new (uri, map); + + return host; +} + +SoupConnectionManager * +soup_connection_manager_new (SoupSession *session, + guint max_conns, + guint max_conns_per_host) +{ + SoupConnectionManager *manager; + + manager = g_new0 (SoupConnectionManager, 1); + manager->session = session; + manager->max_conns = max_conns; + manager->max_conns_per_host = max_conns_per_host; + manager->http_hosts = g_hash_table_new_full (soup_host_uri_hash, + soup_host_uri_equal, + NULL,
View file
_service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/soup-connection-manager.h
Added
@@ -0,0 +1,36 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ +/* + * Copyright 2022 Igalia S.L. + */ + +#ifndef __SOUP_CONNECTION_MANAGER_H__ +#define __SOUP_CONNECTION_MANAGER_H__ 1 + +#include "soup-connection.h" +#include "soup-message-queue-item.h" +#include <gio/gio.h> + +typedef struct _SoupConnectionManager SoupConnectionManager; + +SoupConnectionManager *soup_connection_manager_new (SoupSession *session, + guint max_conns, + guint max_conns_per_host); +void soup_connection_manager_free (SoupConnectionManager *manager); +void soup_connection_manager_set_max_conns (SoupConnectionManager *manager, + guint max_conns); +guint soup_connection_manager_get_max_conns (SoupConnectionManager *manager); +void soup_connection_manager_set_max_conns_per_host (SoupConnectionManager *manager, + guint max_conns_per_host); +guint soup_connection_manager_get_max_conns_per_host (SoupConnectionManager *manager); +void soup_connection_manager_set_remote_connectable (SoupConnectionManager *manager, + GSocketConnectable *connectable); +GSocketConnectable *soup_connection_manager_get_remote_connectable (SoupConnectionManager *manager); +guint soup_connection_manager_get_num_conns (SoupConnectionManager *manager); +SoupConnection *soup_connection_manager_get_connection (SoupConnectionManager *manager, + SoupMessageQueueItem *item); +gboolean soup_connection_manager_cleanup (SoupConnectionManager *manager, + gboolean cleanup_idle); +GIOStream *soup_connection_manager_steal_connection (SoupConnectionManager *manager, + SoupMessage *msg); + +#endif /* __SOUP_CONNECTION_MANAGER_H__ */
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/soup-connection.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/soup-connection.c
Changed
@@ -31,7 +31,7 @@ SoupSocketProperties *socket_props; guint64 id; GSocketAddress *remote_address; - gboolean force_http1; + guint8 force_http_version; GUri *proxy_uri; gboolean ssl; @@ -47,6 +47,7 @@ GTlsCertificate *tls_client_cert; GCancellable *cancellable; + GThread *owner; } SoupConnectionPrivate; G_DEFINE_FINAL_TYPE_WITH_PRIVATE (SoupConnection, soup_connection, G_TYPE_OBJECT) @@ -75,14 +76,15 @@ PROP_TLS_CERTIFICATE_ERRORS, PROP_TLS_PROTOCOL_VERSION, PROP_TLS_CIPHERSUITE_NAME, - PROP_FORCE_HTTP1, + PROP_FORCE_HTTP_VERSION, + PROP_CONTEXT, LAST_PROPERTY }; static GParamSpec *propertiesLAST_PROPERTY = { NULL, }; -static void stop_idle_timer (SoupConnectionPrivate *priv); +static gboolean idle_timeout (gpointer conn); /* Number of seconds after which we close a connection that hasn't yet * been used. @@ -95,6 +97,8 @@ SoupConnectionPrivate *priv = soup_connection_get_instance_private (conn); priv->http_version = SOUP_HTTP_1_1; + priv->force_http_version = G_MAXUINT8; + priv->owner = g_thread_self (); } static void @@ -132,7 +136,11 @@ SoupConnection *conn = SOUP_CONNECTION (object); SoupConnectionPrivate *priv = soup_connection_get_instance_private (conn); - stop_idle_timer (priv); + if (priv->idle_timeout_src) { + g_source_destroy (priv->idle_timeout_src); + g_source_unref (priv->idle_timeout_src); + priv->idle_timeout_src = NULL; + } G_OBJECT_CLASS (soup_connection_parent_class)->dispose (object); } @@ -156,9 +164,16 @@ case PROP_ID: priv->id = g_value_get_uint64 (value); break; - case PROP_FORCE_HTTP1: - priv->force_http1 = g_value_get_boolean (value); + case PROP_FORCE_HTTP_VERSION: + priv->force_http_version = g_value_get_uchar (value); break; + case PROP_CONTEXT: + priv->idle_timeout_src = g_timeout_source_new (0); + g_source_set_ready_time (priv->idle_timeout_src, -1); + g_source_set_name (priv->idle_timeout_src, "Soup connection idle timeout"); + g_source_set_callback (priv->idle_timeout_src, idle_timeout, object, NULL); + g_source_attach (priv->idle_timeout_src, g_value_get_pointer (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -182,7 +197,7 @@ g_value_set_boxed (value, priv->socket_props); break; case PROP_STATE: - g_value_set_enum (value, priv->state); + g_value_set_enum (value, g_atomic_int_get (&priv->state)); break; case PROP_SSL: g_value_set_boolean (value, priv->ssl); @@ -202,8 +217,8 @@ case PROP_TLS_CIPHERSUITE_NAME: g_value_set_string (value, soup_connection_get_tls_ciphersuite_name (SOUP_CONNECTION (object))); break; - case PROP_FORCE_HTTP1: - g_value_set_boolean (value, priv->force_http1); + case PROP_FORCE_HTTP_VERSION: + g_value_set_uchar (value, priv->force_http_version); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -344,11 +359,18 @@ NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - propertiesPROP_FORCE_HTTP1 = - g_param_spec_boolean ("force-http1", - "Force HTTP 1.x", - "Force connection to use HTTP 1.x", - FALSE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + propertiesPROP_FORCE_HTTP_VERSION = + g_param_spec_uchar ("force-http-version", + "Force HTTP version", + "Force connection to use a specific HTTP version", + 0, G_MAXUINT8, G_MAXUINT8, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + propertiesPROP_CONTEXT = + g_param_spec_pointer ("context", + "Context", + "The session main context", + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, LAST_PROPERTY, properties); @@ -369,7 +391,7 @@ idle_timeout (gpointer conn) { soup_connection_disconnect (conn); - return FALSE; + return G_SOURCE_REMOVE; } static void @@ -377,21 +399,14 @@ { SoupConnectionPrivate *priv = soup_connection_get_instance_private (conn); - if (priv->socket_props->idle_timeout > 0 && !priv->idle_timeout_src) { - priv->idle_timeout_src = - soup_add_timeout (g_main_context_get_thread_default (), - priv->socket_props->idle_timeout * 1000, - idle_timeout, conn); - } -} + if (priv->socket_props->idle_timeout == 0) + return; -static void -stop_idle_timer (SoupConnectionPrivate *priv) -{ - if (priv->idle_timeout_src) { - g_source_destroy (priv->idle_timeout_src); - g_clear_pointer (&priv->idle_timeout_src, g_source_unref); - } + if (g_source_get_ready_time (priv->idle_timeout_src) >= 0) + return; + + g_source_set_ready_time (priv->idle_timeout_src, + g_get_monotonic_time () + (guint64)priv->socket_props->idle_timeout * G_USEC_PER_SEC); } static void @@ -400,11 +415,11 @@ { SoupConnectionPrivate *priv = soup_connection_get_instance_private (conn); - if (priv->state == state) + if (g_atomic_int_get (&priv->state) == state) return; - priv->state = state; - if (priv->state == SOUP_CONNECTION_IDLE) + g_atomic_int_set (&priv->state, state); + if (state == SOUP_CONNECTION_IDLE) start_idle_timer (conn); g_object_notify_by_pspec (G_OBJECT (conn), propertiesPROP_STATE); @@ -512,13 +527,14 @@ G_CALLBACK (re_emit_socket_event), conn, 0); - if (!props->proxy_use_default) { - if (props->proxy_resolver) { - g_socket_client_set_proxy_resolver (client, props->proxy_resolver); - g_socket_client_add_application_proxy (client, "http"); - } else - g_socket_client_set_enable_proxy (client, FALSE); - } + if (!props->proxy_use_default && !props->proxy_resolver) { + g_socket_client_set_enable_proxy (client, FALSE); + } else { + if (props->proxy_resolver) + g_socket_client_set_proxy_resolver (client, props->proxy_resolver); + g_socket_client_add_application_proxy (client, "http"); + } + if (props->io_timeout) g_socket_client_set_timeout (client, props->io_timeout); if (props->local_addr) @@ -568,11 +584,23 @@ GPtrArray *advertised_protocols = g_ptr_array_sized_new (4); // https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml - if (!priv->force_http1)
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/soup-connection.h -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/soup-connection.h
Changed
@@ -85,6 +85,7 @@ GSocketAddress *soup_connection_get_remote_address (SoupConnection *conn); SoupHTTPVersion soup_connection_get_negotiated_protocol (SoupConnection *conn); gboolean soup_connection_is_reusable (SoupConnection *conn); +GThread *soup_connection_get_owner (SoupConnection *conn); G_END_DECLS
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/soup-date-utils.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/soup-date-utils.c
Changed
@@ -27,15 +27,6 @@ #include "soup-date-utils-private.h" /** - * SECTION:soup-date-utils - * @section_id: SoupDateTime - * @title: DateTime Utilities - * @short_description: Functions to help working with #GDateTime and HTTP - * - * These are simple utility functions to help using #GDateTime. - */ - -/** * soup_date_time_is_past: * @date: a #GDateTime * @@ -58,11 +49,11 @@ /** * SoupDateFormat: * @SOUP_DATE_HTTP: RFC 1123 format, used by the HTTP "Date" header. Eg - * "Sun, 06 Nov 1994 08:49:37 GMT" + * "Sun, 06 Nov 1994 08:49:37 GMT". * @SOUP_DATE_COOKIE: The format for the "Expires" timestamp in the - * Netscape cookie specification. Eg, "Sun, 06-Nov-1994 08:49:37 GMT". + * Netscape cookie specification. Eg, "Sun, 06-Nov-1994 08:49:37 GMT". * - * Date formats that soup_date_time_to_string() can use. + * Date formats that func@date_time_to_string can use. * * @SOUP_DATE_HTTP and @SOUP_DATE_COOKIE always coerce the time to * UTC. @@ -88,7 +79,7 @@ * * Converts @date to a string in the format described by @format. * - * Return: (transfer full): @date as a string or %NULL + * Returns: (transfer full): @date as a string or %NULL **/ char * soup_date_time_to_string (GDateTime *date, @@ -307,13 +298,14 @@ * soup_date_time_new_from_http_string: * @date_string: The date as a string * - * Parses @date_string and tries to extract a date from it. This - * recognizes all of the "HTTP-date" formats from RFC 2616, RFC 2822 - * dates, and reasonable approximations thereof. (Eg, it is lenient about - * whitespace, leading "0"s, etc.) + * Parses @date_string and tries to extract a date from it. + * + * This recognizes all of the "HTTP-date" formats from RFC 2616, RFC 2822 dates, + * and reasonable approximations thereof. (Eg, it is lenient about whitespace, + * leading "0"s, etc.) * * Returns: (nullable): a new #GDateTime, or %NULL if @date_string - * could not be parsed. + * could not be parsed. **/ GDateTime * soup_date_time_new_from_http_string (const char *date_string)
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/soup-form.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/soup-form.c
Changed
@@ -15,31 +15,19 @@ #include "soup.h" /** - * SECTION:soup-form - * @section_id: SoupForm - * @short_description: HTML form handling - * @see_also: #SoupMultipart - * - * libsoup contains several help methods for processing HTML forms as - * defined by the the HTML 4.01 specification(http://www.w3.org/TR/html401/interact/forms.html#h-17.13). - **/ - -/** * SOUP_FORM_MIME_TYPE_URLENCODED: * * A macro containing the value - * <literal>"application/x-www-form-urlencoded"</literal>; the default + * `application/x-www-form-urlencoded`; the default * MIME type for POSTing HTML form data. - * **/ /** * SOUP_FORM_MIME_TYPE_MULTIPART: * * A macro containing the value - * <literal>"multipart/form-data"</literal>; the MIME type used for + * `multipart/form-data`; the MIME type used for * posting form data that contains files to be uploaded. - * **/ #define XDIGIT(c) ((c) <= '9' ? (c) - '0' : ((c) & 0x4F) - 'A' + 10) @@ -71,12 +59,13 @@ * soup_form_decode: * @encoded_form: data of type "application/x-www-form-urlencoded" * - * Decodes @form, which is an urlencoded dataset as defined in the - * HTML 4.01 spec. + * Decodes @form. + * + * which is an urlencoded dataset as defined in the HTML 4.01 spec. * * Returns: (element-type utf8 utf8) (transfer container): a hash - * table containing the name/value pairs from @encoded_form, which you - * can free with g_hash_table_destroy(). + * table containing the name/value pairs from @encoded_form, which you + * can free with func@GLib.HashTable.destroy. **/ GHashTable * soup_form_decode (const char *encoded_form) @@ -111,35 +100,35 @@ /** * soup_form_decode_multipart: * @multipart: a #SoupMultipart - * @file_control_name: (nullable): the name of the HTML file upload control, or %NULL - * @filename: (out) (optional): return location for the name of the uploaded file, or %NULL - * @content_type: (out) (optional): return location for the MIME type of the uploaded file, or %NULL - * @file: (out) (optional): return location for the uploaded file data, or %NULL + * @file_control_name: (nullable): the name of the HTML file upload control + * @filename: (out) (optional): return location for the name of the uploaded file + * @content_type: (out) (optional): return location for the MIME type of the uploaded file + * @file: (out) (optional): return location for the uploaded file data + * + * Decodes the "multipart/form-data" request in @multipart. * - * Decodes the "multipart/form-data" request in @multipart; this is a - * convenience method for the case when you have a single file upload - * control in a form. (Or when you don't have any file upload - * controls, but are still using "multipart/form-data" anyway.) Pass - * the name of the file upload control in @file_control_name, and - * soup_form_decode_multipart() will extract the uploaded file data - * into @filename, @content_type, and @file. All of the other form - * control data will be returned (as strings, as with - * soup_form_decode()) in the returned #GHashTable. + * this is a convenience method for the case when you have a single file upload + * control in a form. (Or when you don't have any file upload controls, but are + * still using "multipart/form-data" anyway.) Pass the name of the file upload + * control in @file_control_name, and func@form_decode_multipart will extract + * the uploaded file data into @filename, @content_type, and @file. All of the + * other form control data will be returned (as strings, as with + * func@form_decode in the returned struct@GLib.HashTable. * * You may pass %NULL for @filename, @content_type and/or @file if you do not - * care about those fields. soup_form_decode_multipart() may also + * care about those fields. func@form_decode_multipart may also * return %NULL in those fields if the client did not provide that * information. You must free the returned filename and content-type - * with g_free(), and the returned file data with g_bytes_unref(). + * with func@GLib.free, and the returned file data with method@Glib.Bytes.unref. * * If you have a form with more than one file upload control, you will - * need to decode it manually, using soup_multipart_new_from_message() - * and soup_multipart_get_part(). + * need to decode it manually, using ctor@Multipart.new_from_message + * and method@Multipart.get_part. * * Returns: (nullable) (element-type utf8 utf8) (transfer container): - * a hash table containing the name/value pairs (other than - * @file_control_name) from @msg, which you can free with - * g_hash_table_destroy(). On error, it will return %NULL. + * a hash table containing the name/value pairs (other than + * @file_control_name) from @msg, which you can free with + * func@GLib.HashTable.destroy. On error, it will return %NULL. */ GHashTable * soup_form_decode_multipart (SoupMultipart *multipart, @@ -234,20 +223,21 @@ * soup_form_encode: * @first_field: name of the first form field * @...: value of @first_field, followed by additional field names - * and values, terminated by %NULL. + * and values, terminated by %NULL. * * Encodes the given field names and values into a value of type - * "application/x-www-form-urlencoded", as defined in the HTML 4.01 - * spec. + * "application/x-www-form-urlencoded". + * + * Encodes as defined in the HTML 4.01 spec. * * This method requires you to know the names of the form fields (or * at the very least, the total number of fields) at compile time; for - * working with dynamic forms, use soup_form_encode_hash() or - * soup_form_encode_datalist(). + * working with dynamic forms, use func@form_encode_hash or + * func@form_encode_datalist. * - * Returns: the encoded form + * See also: ctor@Message.new_from_encoded_form. * - * See also: soup_message_new_from_encoded_form() + * Returns: the encoded form **/ char * soup_form_encode (const char *first_field, ...) @@ -265,20 +255,21 @@ /** * soup_form_encode_hash: * @form_data_set: (element-type utf8 utf8): a hash table containing - * name/value pairs (as strings) + * name/value pairs (as strings) * * Encodes @form_data_set into a value of type - * "application/x-www-form-urlencoded", as defined in the HTML 4.01 - * spec. + * "application/x-www-form-urlencoded". + * + * Encodes as defined in the HTML 4.01 spec. * * Note that the HTML spec states that "The control names/values are * listed in the order they appear in the document." Since this method * takes a hash table, it cannot enforce that; if you care about the - * ordering of the form fields, use soup_form_encode_datalist(). + * ordering of the form fields, use func@form_encode_datalist. * - * Returns: the encoded form + * See also: ctor@Message.new_from_encoded_form. * - * See also: soup_message_new_from_encoded_form() + * Returns: the encoded form **/ char * soup_form_encode_hash (GHashTable *form_data_set) @@ -304,13 +295,15 @@ * @form_data_set: a datalist containing name/value pairs * * Encodes @form_data_set into a value of type - * "application/x-www-form-urlencoded", as defined in the HTML 4.01 - * spec. Unlike soup_form_encode_hash(), this preserves the ordering - * of the form elements, which may be required in some situations. + * "application/x-www-form-urlencoded". * - * Returns: the encoded form + * Encodes as defined in the HTML 4.01 spec. Unlike func@form_encode_hash, + * this preserves the ordering of the form elements, which may be required in + * some situations. * - * See also: soup_message_new_from_encoded_form() + * See also: ctor@Message.new_from_encoded_form. + * + * Returns: the encoded form **/ char * soup_form_encode_datalist (GData **form_data_set) @@ -324,14 +317,16 @@ /** * soup_form_encode_valist: * @first_field: name of the first form field - * @args: pointer to additional values, as in soup_form_encode() + * @args: pointer to additional values, as in func@form_encode * - * See soup_form_encode(). This is mostly an internal method, used by - * various other methods such as soup_form_encode(). + * See func@form_encode. * - * Returns: the encoded form + * This is mostly an internal method, used by various other methods such as + * func@form_encode.
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/soup-headers.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/soup-headers.c
Changed
@@ -18,15 +18,6 @@ #include "soup.h" /** - * SECTION:soup-headers - * @section_id: SoupHeaders - * @title: SoupHeaders - * @short_description: Functions to help working with HTTP Headers - * - * These are utility functions to help working with HTTP headers. - */ - -/** * soup_headers_parse: * @str: the header string (including the Request-Line or Status-Line, * but not the trailing blank line) @@ -34,14 +25,14 @@ * @dest: #SoupMessageHeaders to store the header values in * * Parses the headers of an HTTP request or response in @str and - * stores the results in @dest. Beware that @dest may be modified even - * on failure. + * stores the results in @dest. + * + * Beware that @dest may be modified even on failure. * * This is a low-level method; normally you would use - * soup_headers_parse_request() or soup_headers_parse_response(). + * func@headers_parse_request or func@headers_parse_response. * * Returns: success or failure - * **/ gboolean soup_headers_parse (const char *str, int len, SoupMessageHeaders *dest) @@ -170,11 +161,11 @@ * @len: length of @str * @req_headers: #SoupMessageHeaders to store the header values in * @req_method: (out) (optional): if non-%NULL, will be filled in with the - * request method + * request method * @req_path: (out) (optional): if non-%NULL, will be filled in with the - * request path + * request path * @ver: (out) (optional): if non-%NULL, will be filled in with the HTTP - * version + * version * * Parses the headers of an HTTP request in @str and stores the * results in @req_method, @req_path, @ver, and @req_headers. @@ -182,7 +173,7 @@ * Beware that @req_headers may be modified even on failure. * * Returns: %SOUP_STATUS_OK if the headers could be parsed, or an - * HTTP error to be returned to the client if they could not be. + * HTTP error to be returned to the client if they could not be. **/ guint soup_headers_parse_request (const char *str, @@ -280,15 +271,16 @@ * soup_headers_parse_status_line: * @status_line: an HTTP Status-Line * @ver: (out) (optional): if non-%NULL, will be filled in with the HTTP - * version + * version * @status_code: (out) (optional): if non-%NULL, will be filled in with - * the status code + * the status code * @reason_phrase: (out) (optional): if non-%NULL, will be filled in with - * the reason phrase + * the reason phrase * * Parses the HTTP Status-Line string in @status_line into @ver, - * @status_code, and @reason_phrase. @status_line must be terminated by - * either "\0" or "\r\n". + * @status_code, and @reason_phrase. + * + * @status_line must be terminated by either "\0" or "\r\n". * * Returns: %TRUE if @status_line was parsed successfully. **/ @@ -357,11 +349,11 @@ * @len: length of @str * @headers: #SoupMessageHeaders to store the header values in * @ver: (out) (optional): if non-%NULL, will be filled in with the HTTP - * version + * version * @status_code: (out) (optional): if non-%NULL, will be filled in with - * the status code + * the status code * @reason_phrase: (out) (optional): if non-%NULL, will be filled in with - * the reason phrase + * the reason phrase * * Parses the headers of an HTTP response in @str and stores the * results in @ver, @status_code, @reason_phrase, and @headers. @@ -488,12 +480,12 @@ * soup_header_parse_list: * @header: a header value * - * Parses a header whose content is described by RFC2616 as - * "#something", where "something" does not itself contain commas, - * except as part of quoted-strings. + * Parses a header whose content is described by RFC2616 as `#something`. + * + * "something" does not itself contain commas, except as part of quoted-strings. * * Returns: (transfer full) (element-type utf8): a #GSList of - * list elements, as allocated strings + * list elements, as allocated strings **/ GSList * soup_header_parse_list (const char *header) @@ -526,7 +518,7 @@ * soup_header_parse_quality_list: * @header: a header value * @unacceptable: (out) (optional) (transfer full) (element-type utf8): on - * return, will contain a list of unacceptable values + * return, will contain a list of unacceptable values * * Parses a header whose content is a list of items with optional * "qvalue"s (eg, Accept, Accept-Charset, Accept-Encoding, @@ -537,7 +529,7 @@ * the main list. * * Returns: (transfer full) (element-type utf8): a #GSList of - * acceptable values (as allocated strings), highest-qvalue first. + * acceptable values (as allocated strings), highest-qvalue first. **/ GSList * soup_header_parse_quality_list (const char *header, GSList **unacceptable) @@ -613,8 +605,8 @@ /** * soup_header_free_list: (skip) - * @list: a #GSList returned from soup_header_parse_list() or - * soup_header_parse_quality_list() + * @list: a #GSList returned from func@header_parse_list or + * func@header_parse_quality_list * * Frees @list. **/ @@ -627,12 +619,13 @@ /** * soup_header_contains: * @header: An HTTP header suitable for parsing with - * soup_header_parse_list() + * func@header_parse_list * @token: a token * * Parses @header to see if it contains the token @token (matched - * case-insensitively). Note that this can't be used with lists - * that have qvalues. + * case-insensitively). + * + * Note that this can't be used with lists that have qvalues. * * Returns: whether or not @header contains @token **/ @@ -786,7 +779,7 @@ * @header: a header value * * Parses a header which is a comma-delimited list of something like: - * <literal>token "=" ( token | quoted-string ) </literal>. + * `token "=" ( token | quoted-string ) `. * * Tokens that don't have an associated value will still be added to * the resulting hash table, but with a %NULL value. @@ -796,8 +789,8 @@ * header). * * Returns: (element-type utf8 utf8) (transfer full): a - * #GHashTable of list elements, which can be freed with - * soup_header_free_param_list(). + * #GHashTable of list elements, which can be freed with + * func@header_free_param_list. **/ GHashTable * soup_header_parse_param_list (const char *header) @@ -812,7 +805,7 @@ * @header: a header value * * Parses a header which is a semicolon-delimited list of something - * like: <literal>token "=" ( token | quoted-string ) </literal>. + * like: `token "=" ( token | quoted-string ) `. * * Tokens that don't have an associated value will still be added to * the resulting hash table, but with a %NULL value. @@ -822,9 +815,8 @@ * header). * * Returns: (element-type utf8 utf8) (transfer full): a - * #GHashTable of list elements, which can be freed with - * soup_header_free_param_list(). - * + * #GHashTable of list elements, which can be freed with + * func@header_free_param_list. **/ GHashTable * soup_header_parse_semi_param_list (const char *header)
View file
_service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/soup-http2-utils.c
Added
@@ -0,0 +1,115 @@ +/* + * Copyright 2022 Igalia, S.L. + */ + +#include <glib.h> + +#include "soup-http2-utils.h" + +const char * +soup_http2_io_state_to_string (SoupHTTP2IOState state) +{ + switch (state) { + case STATE_NONE: + return "NONE"; + case STATE_WRITE_HEADERS: + return "WRITE_HEADERS"; + case STATE_WRITE_DATA: + return "WRITE_DATA"; + case STATE_WRITE_DONE: + return "WRITE_DONE"; + case STATE_READ_HEADERS: + return "READ_HEADERS"; + case STATE_READ_DATA_START: + return "READ_DATA_START"; + case STATE_READ_DATA: + return "READ_DATA"; + case STATE_READ_DONE: + return "READ_DONE"; + } + g_assert_not_reached (); + return ""; +} + +const char * +soup_http2_frame_type_to_string (nghttp2_frame_type type) +{ + switch (type) { + case NGHTTP2_DATA: + return "DATA"; + case NGHTTP2_HEADERS: + return "HEADERS"; + case NGHTTP2_PRIORITY: + return "PRIORITY"; + case NGHTTP2_RST_STREAM: + return "RST_STREAM"; + case NGHTTP2_SETTINGS: + return "SETTINGS"; + case NGHTTP2_PING: + return "PING"; + case NGHTTP2_GOAWAY: + return "GOAWAY"; + case NGHTTP2_WINDOW_UPDATE: + return "WINDOW_UPDATE"; + /* LCOV_EXCL_START */ + case NGHTTP2_PUSH_PROMISE: + return "PUSH_PROMISE"; + case NGHTTP2_CONTINUATION: + return "CONTINUATION"; + case NGHTTP2_ALTSVC: + return "ALTSVC"; + case NGHTTP2_ORIGIN: + return "ORIGIN"; + default: + g_warn_if_reached (); + return "UNKNOWN"; + /* LCOV_EXCL_STOP */ + } +} + +const char * +soup_http2_headers_category_to_string (nghttp2_headers_category catergory) +{ + switch (catergory) { + case NGHTTP2_HCAT_REQUEST: + return "REQUEST"; + case NGHTTP2_HCAT_RESPONSE: + return "RESPONSE"; + case NGHTTP2_HCAT_PUSH_RESPONSE: + return "PUSH_RESPONSE"; + case NGHTTP2_HCAT_HEADERS: + return "HEADERS"; + } + g_assert_not_reached (); + return ""; +} + +G_GNUC_PRINTF(1, 0) +static void +debug_nghttp2 (const char *format, + va_list args) +{ + char *message; + gsize len; + + if (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "nghttp2")) + return; + + message = g_strdup_vprintf (format, args); + len = strlen (message); + if (len >= 1 && messagelen - 1 == '\n') + messagelen - 1 = '\0'; + g_log ("nghttp2", G_LOG_LEVEL_DEBUG, "NGHTTP2 %s", message); + g_free (message); +} + +void +soup_http2_debug_init (void) +{ + static gsize nghttp2_debug_init = 0; + if (g_once_init_enter (&nghttp2_debug_init)) { + nghttp2_set_debug_vprintf_callback(debug_nghttp2); + g_once_init_leave (&nghttp2_debug_init, 1); + } + +}
View file
_service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/soup-http2-utils.h
Added
@@ -0,0 +1,49 @@ +/* + * Copyright 2022 Igalia, S.L. + */ + +#pragma once + +#include <nghttp2/nghttp2.h> + +#define NGCHECK(stm) \ + G_STMT_START { \ + int return_code = stm; \ + if (return_code == NGHTTP2_ERR_NOMEM) \ + g_abort (); \ + else if (return_code < 0) \ + g_debug ("Unhandled NGHTTP2 Error: %s", nghttp2_strerror (return_code)); \ + } G_STMT_END + +#define MAKE_NV(NAME, VALUE, VALUELEN) \ + { \ + (uint8_t *)NAME, (uint8_t *)VALUE, strlen (NAME), VALUELEN, NGHTTP2_NV_FLAG_NONE \ + } + +#define MAKE_NV2(NAME, VALUE) \ + { \ + (uint8_t *)NAME, (uint8_t *)VALUE, strlen (NAME), strlen (VALUE), NGHTTP2_NV_FLAG_NONE \ + } + +#define MAKE_NV3(NAME, VALUE, FLAGS) \ + { \ + (uint8_t *)NAME, (uint8_t *)VALUE, strlen (NAME), strlen (VALUE), FLAGS \ + } + + +typedef enum { + STATE_NONE, + STATE_WRITE_HEADERS, + STATE_WRITE_DATA, + STATE_WRITE_DONE, + STATE_READ_HEADERS, + STATE_READ_DATA_START, + STATE_READ_DATA, + STATE_READ_DONE, +} SoupHTTP2IOState; + +const char *soup_http2_io_state_to_string (SoupHTTP2IOState state); +const char *soup_http2_frame_type_to_string (nghttp2_frame_type type); +const char *soup_http2_headers_category_to_string (nghttp2_headers_category catergory); + +void soup_http2_debug_init (void);
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/soup-logger-private.h -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/soup-logger-private.h
Changed
@@ -9,10 +9,6 @@ G_BEGIN_DECLS -void soup_logger_request_body_setup (SoupLogger *logger, - SoupMessage *msg, - SoupBodyOutputStream *stream); - void soup_logger_log_request_data (SoupLogger *logger, SoupMessage *msg, const char *buffer, gsize len); G_END_DECLS
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/soup-logger.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/soup-logger.c
Changed
@@ -23,24 +23,25 @@ #include "soup-session-feature-private.h" /** - * SECTION:soup-logger - * @short_description: Debug logging support + * SoupLogger: + * + * Debug logging support * - * #SoupLogger watches a #SoupSession and logs the HTTP traffic that + * #SoupLogger watches a class@Session and logs the HTTP traffic that * it generates, for debugging purposes. Many applications use an * environment variable to determine whether or not to use * #SoupLogger, and to determine the amount of debugging output. * - * To use #SoupLogger, first create a logger with soup_logger_new(), - * optionally configure it with soup_logger_set_request_filter(), - * soup_logger_set_response_filter(), and soup_logger_set_printer(), - * and then attach it to a session (or multiple sessions) with - * soup_session_add_feature(). + * To use #SoupLogger, first create a logger with ctor@Logger.new, optionally + * configure it with method@Logger.set_request_filter, + * method@Logger.set_response_filter, and method@Logger.set_printer, and + * then attach it to a session (or multiple sessions) with + * method@Session.add_feature. * - * By default, the debugging output is sent to - * <literal>stdout</literal>, and looks something like: + * By default, the debugging output is sent to `stdout`, and looks something + * like: * - * <informalexample><screen> + * ``` * > POST /unauth HTTP/1.1 * > Soup-Debug-Timestamp: 1200171744 * > Soup-Debug: SoupSession 1 (0x612190), SoupMessage 1 (0x617000), GSocket 1 (0x612220) @@ -53,45 +54,36 @@ * < Soup-Debug: SoupMessage 1 (0x617000) * < Date: Sun, 12 Jan 2008 21:02:24 GMT * < Content-Length: 0 - * </screen></informalexample> + * ``` * - * The <literal>Soup-Debug-Timestamp</literal> line gives the time (as - * a <type>time_t</type>) when the request was sent, or the response fully - * received. + * The `Soup-Debug-Timestamp` line gives the time (as a `time_t`) when the + * request was sent, or the response fully received. * - * The <literal>Soup-Debug</literal> line gives further debugging - * information about the #SoupSession, #SoupMessage, and #GSocket - * involved; the hex numbers are the addresses of the objects in - * question (which may be useful if you are running in a debugger). - * The decimal IDs are simply counters that uniquely identify objects - * across the lifetime of the #SoupLogger. In particular, this can be - * used to identify when multiple messages are sent across the same - * connection. + * The `Soup-Debug` line gives further debugging information about the + * class@Session, class@Message, and class@Gio.Socket involved; the hex + * numbers are the addresses of the objects in question (which may be useful if + * you are running in a debugger). The decimal IDs are simply counters that + * uniquely identify objects across the lifetime of the #SoupLogger. In + * particular, this can be used to identify when multiple messages are sent + * across the same connection. * * Currently, the request half of the message is logged just before * the first byte of the request gets written to the network (from the - * #SoupMessage::starting signal). - * - * The response is logged just after the last byte of the response - * body is read from the network (from the #SoupMessage::got-body or - * #SoupMessage::got-informational signal), which means that the - * #SoupMessage::got-headers signal, and anything triggered off it - * (such as #SoupMessage::authenticate) will be emitted - * <emphasis>before</emphasis> the response headers are actually - * logged. - * - * If the response doesn't happen to trigger the - * #SoupMessage::got-body nor #SoupMessage::got-informational signals - * due to, for example, a cancellation before receiving the last byte - * of the response body, the response will still be logged on the - * event of the #SoupMessage::finished signal. - **/ - -/** - * SoupLogger: + * signal@Message::starting signal). * - * Class implementing logging. - */ + * The response is logged just after the last byte of the response body is read + * from the network (from the signal@Message::got-body or + * signal@Message::got-informational signal), which means that the + * signal@Message::got-headers signal, and anything triggered off it (such as + * #SoupMessage::authenticate) will be emitted *before* the response headers are + * actually logged. + * + * If the response doesn't happen to trigger the signal@Message::got-body nor + * signal@Message::got-informational signals due to, for example, a + * cancellation before receiving the last byte of the response body, the + * response will still be logged on the event of the signal@Message::finished + * signal. + **/ struct _SoupLogger { GObject parent; @@ -99,9 +91,9 @@ typedef struct { GQuark tag; + GMutex mutex; GHashTable *ids; GHashTable *request_bodies; - GHashTable *request_messages; GHashTable *response_bodies; SoupSession *session; @@ -132,8 +124,6 @@ static GParamSpec *propertiesLAST_PROPERTY = { NULL, }; -static void body_ostream_done (gpointer data, GObject *bostream); - static void soup_logger_session_feature_init (SoupSessionFeatureInterface *feature_interface, gpointer interface_data); static SoupContentProcessorInterface *soup_logger_default_content_processor_interface; @@ -156,12 +146,14 @@ if (!nread) return; + g_mutex_lock (&priv->mutex); body = g_hash_table_lookup (bodies, key); if (!body) { body = g_string_new (NULL); g_hash_table_insert (bodies, key, body); } + g_mutex_unlock (&priv->mutex); if (priv->max_body_size >= 0) { /* longer than max => we've written the extra ... */ @@ -255,13 +247,7 @@ priv->ids = g_hash_table_new (NULL, NULL); priv->request_bodies = g_hash_table_new_full (NULL, NULL, NULL, body_free); priv->response_bodies = g_hash_table_new_full (NULL, NULL, NULL, body_free); - priv->request_messages = g_hash_table_new (NULL, NULL); -} - -static void -body_ostream_drop_ref (gpointer key, gpointer value, gpointer data) -{ - g_object_weak_unref (key, body_ostream_done, data); + g_mutex_init (&priv->mutex); } static void @@ -270,13 +256,9 @@ SoupLogger *logger = SOUP_LOGGER (object); SoupLoggerPrivate *priv = soup_logger_get_instance_private (logger); - g_hash_table_foreach (priv->request_messages, - body_ostream_drop_ref, priv); - g_hash_table_destroy (priv->ids); g_hash_table_destroy (priv->request_bodies); g_hash_table_destroy (priv->response_bodies); - g_hash_table_destroy (priv->request_messages); if (priv->request_filter_dnotify) priv->request_filter_dnotify (priv->request_filter_data); @@ -285,6 +267,8 @@ if (priv->printer_dnotify) priv->printer_dnotify (priv->printer_data); + g_mutex_clear (&priv->mutex); + G_OBJECT_CLASS (soup_logger_parent_class)->finalize (object); } @@ -341,8 +325,7 @@ /** * SoupLogger:level: * - * The level of logging output - * + * The level of logging output. */ propertiesPROP_LEVEL = g_param_spec_enum ("level", @@ -353,12 +336,11 @@ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** - * SoupLogger:max-body-size: + * SoupLogger:max-body-size: (attributes org.gtk.Property.get=soup_logger_get_max_body_size org.gtk.Property.set=soup_logger_set_max_body_size) * - * If #SoupLogger:level is %SOUP_LOGGER_LOG_BODY, this gives + * If property@Logger:level is %SOUP_LOGGER_LOG_BODY, this gives * the maximum number of bytes of the body that will be logged.
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/soup-message-headers.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/soup-message-headers.c
Changed
@@ -16,15 +16,6 @@ #include "soup-misc.h" /** - * SECTION:soup-message-headers - * @short_description: HTTP message headers - * @see_also: #SoupMessage - * - * #SoupMessageHeaders represents the HTTP message headers associated - * with a request or response. - **/ - -/** * SoupMessageHeaders: * * The HTTP message headers associated with a request or response. @@ -36,7 +27,7 @@ * @SOUP_MESSAGE_HEADERS_RESPONSE: response headers * @SOUP_MESSAGE_HEADERS_MULTIPART: multipart body part headers * - * Value passed to soup_message_headers_new() to set certain default + * Value passed to ctor@MessageHeaders.new to set certain default * behaviors. **/ @@ -71,9 +62,11 @@ * soup_message_headers_new: * @type: the type of headers * - * Creates a #SoupMessageHeaders. (#SoupMessage does this - * automatically for its own headers. You would only need to use this - * method if you are manually parsing or generating message headers.) + * Creates a #SoupMessageHeaders. + * + * (class@Message does this automatically for its own headers. You would only + * need to use this method if you are manually parsing or generating message + * headers.) * * Returns: a new #SoupMessageHeaders **/ @@ -122,6 +115,7 @@ * @hdrs: a #SoupMessageHeaders * * Atomically decrements the reference count of @hdrs by one. + * * When the reference count reaches zero, the resources allocated by * @hdrs are freed */ @@ -140,7 +134,6 @@ * Gets the type of headers. * * Returns: the header's type. - * **/ SoupMessageHeadersType soup_message_headers_get_headers_type (SoupMessageHeaders *hdrs) @@ -256,7 +249,6 @@ * @hdrs: a #SoupMessageHeaders * * Removes all the headers listed in the Connection header. - * */ void soup_message_headers_clean_connection_headers (SoupMessageHeaders *hdrs) @@ -300,10 +292,11 @@ * @name: the header name to add * @value: the new value of @name * - * Appends a new header with name @name and value @value to @hdrs. (If - * there is an existing header with name @name, then this creates a - * second one, which is only allowed for list-valued headers; see also - * soup_message_headers_replace().) + * Appends a new header with name @name and value @value to @hdrs. + * + * (If there is an existing header with name @name, then this creates a second + * one, which is only allowed for list-valued headers; see also + * method@MessageHeaders.replace.) * * The caller is expected to make sure that @name and @value are * syntactically correct. @@ -383,8 +376,9 @@ * @name: the header name to replace * @value: the new value of @name * - * Replaces the value of the header @name in @hdrs with @value. (See - * also soup_message_headers_append().) + * Replaces the value of the header @name in @hdrs with @value. + * + * See also method@MessageHeaders.append. * * The caller is expected to make sure that @name and @value are * syntactically correct. @@ -493,8 +487,9 @@ * @hdrs: a #SoupMessageHeaders * @name: the header name to remove * - * Removes @name from @hdrs. If there are multiple values for @name, - * they are all removed. + * Removes @name from @hdrs. + * + * If there are multiple values for @name, they are all removed. **/ void soup_message_headers_remove (SoupMessageHeaders *hdrs, const char *name) @@ -547,10 +542,11 @@ * @hdrs: a #SoupMessageHeaders * @name: (in): header name * - * Gets the value of header @name in @hdrs. Use this for headers whose - * values are <emphasis>not</emphasis> comma-delimited lists, and - * which therefore can only appear at most once in the headers. For - * list-valued headers, use soup_message_headers_get_list(). + * Gets the value of header @name in @hdrs. + * + * Use this for headers whose values are *not* comma-delimited lists, and which + * therefore can only appear at most once in the headers. For list-valued + * headers, use method@MessageHeaders.get_list. * * If @hdrs does erroneously contain multiple copies of the header, it * is not defined which one will be returned. (Ideally, it will return @@ -558,7 +554,6 @@ * implementations.) * * Returns: (nullable) (transfer none): the header's value or %NULL if not found. - * **/ const char * soup_message_headers_get_one (SoupMessageHeaders *hdrs, const char *name) @@ -603,11 +598,10 @@ * and contains a case-insensitive match for @token. * * (If @name is present in @hdrs, then this is equivalent to calling - * soup_header_contains() on its value.) + * func@header_contains on its value.) * * Returns: %TRUE if the header is present and contains @token, * %FALSE otherwise. - * **/ gboolean soup_message_headers_header_contains (SoupMessageHeaders *hdrs, const char *name, const char *token) @@ -642,7 +636,6 @@ * * Returns: %TRUE if the header is present and its value is * @value, %FALSE otherwise. - * **/ gboolean soup_message_headers_header_equals (SoupMessageHeaders *hdrs, const char *name, const char *value) @@ -700,13 +693,14 @@ * @hdrs: a #SoupMessageHeaders * @name: header name * - * Gets the value of header @name in @hdrs. Use this for headers whose - * values are comma-delimited lists, and which are therefore allowed - * to appear multiple times in the headers. For non-list-valued - * headers, use soup_message_headers_get_one(). + * Gets the value of header @name in @hdrs. + * + * Use this for headers whose values are comma-delimited lists, and which are + * therefore allowed to appear multiple times in the headers. For + * non-list-valued headers, use method@MessageHeaders.get_one. * * If @name appears multiple times in @hdrs, - * soup_message_headers_get_list() will concatenate all of the values + * method@MessageHeaders.get_list will concatenate all of the values * together, separated by commas. This is sometimes awkward to parse * (eg, WWW-Authenticate, Set-Cookie), but you have to be able to deal * with it anyway, because the HTTP spec explicitly states that this @@ -714,7 +708,6 @@ * same thing. * * Returns: (nullable) (transfer none): the header's value or %NULL if not found. - * **/ const char * soup_message_headers_get_list (SoupMessageHeaders *hdrs, const char *name) @@ -770,9 +763,8 @@ * An opaque type used to iterate over a %SoupMessageHeaders * structure. * - * After intializing the iterator with - * soup_message_headers_iter_init(), call - * soup_message_headers_iter_next() to fetch data from it. + * After intializing the iterator with func@MessageHeadersIter.init, call + * method@MessageHeadersIter.next to fetch data from it. * * You may not modify the headers while iterating over them. **/ @@ -786,7 +778,7 @@ /** * soup_message_headers_iter_init: * @iter: (out) (transfer none): a pointer to a %SoupMessageHeadersIter - * structure + * structure * @hdrs: a %SoupMessageHeaders * * Initializes @iter for iterating @hdrs. @@ -806,17 +798,19 @@ * soup_message_headers_iter_next:
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/soup-message-metrics.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/soup-message-metrics.c
Changed
@@ -12,29 +12,21 @@ #include "soup-message-metrics-private.h" /** - * SECTION:soup-message-metrics - * @short_description: Message metrics - * @see_also: #SoupMessage + * SoupMessageMetrics: * - * Metrics collected while loading a #SoupMessage. + * Contains metrics collected while loading a class@Message either from the + * network or the disk cache. * - * Metrics are not collected by default for a #SoupMessage, you need to add the + * Metrics are not collected by default for a class@Message, you need to add the * flag %SOUP_MESSAGE_COLLECT_METRICS to enable the feature. - */ - -/** - * SoupMessageMetrics: - * - * SoupMessageMetrics contains metrics collected while loading a #SoupMessage - * either from the network or the disk cache. * * Temporal metrics are expressed as a monotonic time and always start with a * fetch start event and finish with response end. All other events are optional. * An event can be 0 because it hasn't happened yet, because it's optional or * because the load failed before the event reached. * - * Size metrics are expressed in bytes and aree updated while the #SoupMessage is - * being loaded. You can connect to different #SoupMessage signals to get the + * Size metrics are expressed in bytes and aree updated while the class@Message is + * being loaded. You can connect to different class@Message signals to get the * final result of every value. */ @@ -53,7 +45,6 @@ * Copies @metrics. * * Returns: a copy of @metrics - * **/ SoupMessageMetrics * soup_message_metrics_copy (SoupMessageMetrics *metrics) @@ -72,7 +63,7 @@ * soup_message_metrics_free: * @metrics: a #SoupMessageMetrics * - * Frees @metrics + * Frees @metrics. */ void soup_message_metrics_free (SoupMessageMetrics *metrics) @@ -86,7 +77,7 @@ * soup_message_metrics_get_fetch_start: * @metrics: a #SoupMessageMetrics * - * Get the time immediately before the #SoupMessage started to + * Get the time immediately before the class@Message started to * fetch a resource either from a remote server or local disk cache. * * Returns: the fetch start time @@ -103,10 +94,12 @@ * soup_message_metrics_get_dns_start: * @metrics: a #SoupMessageMetrics * - * Get the time immediately before the #SoupMessage started the - * domain lookup name for the resource. It will be 0 if no domain - * lookup was required to fetch the resource (a persistent connection - * was used or resource was loaded from the local disk cache). + * Get the time immediately before the class@Message started the + * domain lookup name for the resource. + * + * It will be 0 if no domain lookup was required to fetch the resource (a + * persistent connection was used or resource was loaded from the local disk + * cache). * * Returns: the domain lookup start time */ @@ -122,10 +115,12 @@ * soup_message_metrics_get_dns_end: * @metrics: a #SoupMessageMetrics * - * Get the time immediately after the #SoupMessage completed the - * domain lookup name for the resource. It will be 0 if no domain - * lookup was required to fetch the resource (a persistent connection - * was used or resource was loaded from the local disk cache). + * Get the time immediately after the class@Message completed the + * domain lookup name for the resource. + * + * It will be 0 if no domain lookup was required to fetch the resource (a + * persistent connection was used or resource was loaded from the local disk + * cache). * * Returns: the domain lookup end time */ @@ -141,10 +136,12 @@ * soup_message_metrics_get_connect_start: * @metrics: a #SoupMessageMetrics * - * Get the time immediately before the #SoupMessage started to - * establish the connection to the server. It will be 0 if no - * network connection was required to fetch the resource (a persistent - * connection was used or resource was loaded from the local disk cache). + * Get the time immediately before the class@Message started to + * establish the connection to the server. + * + * It will be 0 if no network connection was required to fetch the resource (a + * persistent connection was used or resource was loaded from the local disk + * cache). * * Returns: the connection start time */ @@ -160,11 +157,13 @@ * soup_message_metrics_get_connect_end: * @metrics: a #SoupMessageMetrics * - * Get the time immediately after the #SoupMessage completed the + * Get the time immediately after the class@Message completed the * connection to the server. This includes the time for the proxy - * negotiation and TLS handshake. It will be 0 if no network connection - * was required to fetch the resource (a persistent connection was used - * or resource was loaded from the local disk cache). + * negotiation and TLS handshake. + * + * It will be 0 if no network connection was required to fetch the resource (a + * persistent connection was used or resource was loaded from the local disk + * cache). * * Returns: the connection end time */ @@ -180,10 +179,12 @@ * soup_message_metrics_get_tls_start: * @metrics: a #SoupMessageMetrics * - * Get the time immediately before the #SoupMessage started the - * TLS handshake. It will be 0 if no TLS handshake was required - * to fetch the resource (connection was not secure, a persistent - * connection was used or resource was loaded from the local disk cache). + * Get the time immediately before the class@Message started the + * TLS handshake. + * + * It will be 0 if no TLS handshake was required to fetch the resource + * (connection was not secure, a persistent connection was used or resource was + * loaded from the local disk cache). * * Returns: the tls start time */ @@ -199,7 +200,7 @@ * soup_message_metrics_get_request_start: * @metrics: a #SoupMessageMetrics * - * Get the time immediately before the #SoupMessage started the + * Get the time immediately before the class@Message started the * request of the resource from the server or the local disk cache. * * Returns: the request start time @@ -216,7 +217,7 @@ * soup_message_metrics_get_response_start: * @metrics: a #SoupMessageMetrics * - * Get the time immediately after the #SoupMessage received the first + * Get the time immediately after the class@Message received the first * bytes of the response from the server or the local disk cache. * * Returns: the response start time @@ -233,8 +234,9 @@ * soup_message_metrics_get_response_end: * @metrics: a #SoupMessageMetrics * - * Get the time immediately after the #SoupMessage received the last + * Get the time immediately after the class@Message received the last * bytes of the response from the server or the local disk cache. + * * In case of load failure, this returns the time immediately before the * fetch is aborted. * @@ -253,7 +255,8 @@ * @metrics: a #SoupMessageMetrics * * Get the number of bytes sent to the network for the request headers. - * This value is available right before #SoupMessage::wrote-headers signal + * + * This value is available right before signal@Message::wrote-headers signal * is emitted, but you might get an intermediate value if called before. * * Returns: the request headers bytes sent @@ -271,9 +274,10 @@ * @metrics: a #SoupMessageMetrics * * Get the request body size in bytes. This is the size of the original body - * given to the request before any encoding is applied. This value is available - * right before #SoupMessage::wrote-body signal is emitted, but you might get - * an intermediate value if called before. + * given to the request before any encoding is applied. + * + * This value is available right before signal@Message::wrote-body signal is + * emitted, but you might get an intermediate value if called before. * * Returns: the request body size
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/soup-message-private.h -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/soup-message-private.h
Changed
@@ -147,10 +147,10 @@ void soup_message_force_keep_alive_if_needed (SoupMessage *msg); -void soup_message_set_force_http1 (SoupMessage *msg, - gboolean force_http1); +void soup_message_set_force_http_version (SoupMessage *msg, + guint8 version); -gboolean soup_message_get_force_http1 (SoupMessage *msg); +guint8 soup_message_get_force_http_version (SoupMessage *msg); void soup_message_set_is_misdirected_retry (SoupMessage *msg, gboolean is_misdirected_retry);
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/soup-message-queue-item.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/soup-message-queue-item.c
Changed
@@ -24,6 +24,7 @@ item = g_atomic_rc_box_new0 (SoupMessageQueueItem); item->session = g_object_ref (session); item->msg = g_object_ref (msg); + item->context = g_main_context_ref_thread_default (); item->async = async; item->cancellable = cancellable ? g_object_ref (cancellable) : g_cancellable_new (); @@ -41,11 +42,13 @@ static void soup_message_queue_item_destroy (SoupMessageQueueItem *item) { - if (!g_error_matches (item->error, SOUP_SESSION_ERROR, SOUP_SESSION_ERROR_MESSAGE_ALREADY_IN_QUEUE)) + if (!g_error_matches (item->error, SOUP_SESSION_ERROR, SOUP_SESSION_ERROR_MESSAGE_ALREADY_IN_QUEUE)) { g_warn_if_fail (soup_message_get_connection (item->msg) == NULL); + } g_object_unref (item->session); g_object_unref (item->msg); + g_main_context_unref (item->context); g_object_unref (item->cancellable); g_clear_error (&item->error); g_clear_object (&item->task);
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/soup-message-queue-item.h -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/soup-message-queue-item.h
Changed
@@ -29,6 +29,7 @@ struct _SoupMessageQueueItem { SoupSession *session; SoupMessage *msg; + GMainContext *context; GCancellable *cancellable; GError *error;
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/soup-message.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/soup-message.c
Changed
@@ -21,39 +21,30 @@ #include "content-sniffer/soup-content-sniffer-stream.h" /** - * SECTION:soup-message - * @short_description: An HTTP request and response. - * @see_also: #SoupMessageHeaders + * SoupMessage: + * + * Represents an HTTP message being sent or received. * * A #SoupMessage represents an HTTP message that is being sent or * received. * - * You would create a #SoupMessage with soup_message_new() or - * soup_message_new_from_uri(), set up its - * fields appropriately, and send it. + * You would create a #SoupMessage with ctor@Message.new or + * ctor@Message.new_from_uri, set up its fields appropriately, and send it. * - * Note that libsoup's terminology here does not quite match the HTTP - * specification: in RFC 2616, an "HTTP-message" is - * <emphasis>either</emphasis> a Request, <emphasis>or</emphasis> a - * Response. In libsoup, a #SoupMessage combines both the request and - * the response. - **/ - -/** - * SoupMessage: + * property@Message:status-code will normally be a enum@Status value, eg, + * %SOUP_STATUS_OK, though of course it might actually be an unknown status + * code. property@Message:reason-phrase is the actual text returned from the + * server, which may or may not correspond to the "standard" description of + * @status_code. At any rate, it is almost certainly not localized, and not very + * descriptive even if it is in the user's language; you should not use + * property@Message:reason-phrase in user-visible messages. Rather, you should + * look at property@Message:status-code, and determine an end-user-appropriate + * message based on that and on what you were trying to do. * - * Represents an HTTP message being sent or received. - * - * @status_code will normally be a #SoupStatus value, eg, - * %SOUP_STATUS_OK, though of course it might actually be an unknown - * status code. @reason_phrase is the actual text returned from the - * server, which may or may not correspond to the "standard" - * description of @status_code. At any rate, it is almost certainly - * not localized, and not very descriptive even if it is in the user's - * language; you should not use @reason_phrase in user-visible - * messages. Rather, you should look at @status_code, and determine an - * end-user-appropriate message based on that and on what you were - * trying to do. + * Note that libsoup's terminology here does not quite match the HTTP + * specification: in RFC 2616, an "HTTP-message" is *either* a Request, *or* a + * Response. In libsoup, a #SoupMessage combines both the request and the + * response. */ struct _SoupMessage { @@ -80,7 +71,7 @@ GUri *uri; SoupAuth *auth, *proxy_auth; - SoupConnection *connection; + GWeakRef connection; GHashTable *disabled_features; @@ -103,9 +94,9 @@ gboolean is_top_level_navigation; gboolean is_options_ping; gboolean is_preconnect; - gboolean force_http1; gboolean is_misdirected_retry; guint last_connection_id; + guint8 force_http_version; GSocketAddress *remote_address; SoupMessageMetrics *metrics; @@ -173,9 +164,12 @@ priv->http_version = priv->orig_http_version = SOUP_HTTP_1_1; priv->priority = SOUP_MESSAGE_PRIORITY_NORMAL; + priv->force_http_version = G_MAXUINT8; priv->request_headers = soup_message_headers_new (SOUP_MESSAGE_HEADERS_REQUEST); priv->response_headers = soup_message_headers_new (SOUP_MESSAGE_HEADERS_RESPONSE); + + g_weak_ref_init (&priv->connection, NULL); } static void @@ -197,6 +191,7 @@ g_clear_object (&priv->pending_tls_cert_password); soup_message_set_connection (msg, NULL); + g_weak_ref_clear (&priv->connection); g_clear_pointer (&priv->uri, g_uri_unref); g_clear_pointer (&priv->first_party, g_uri_unref); @@ -362,7 +357,6 @@ * * Emitted immediately after writing a portion of the message * body to the network. - * **/ signalsWROTE_BODY_DATA = g_signal_new ("wrote-body-data", @@ -395,10 +389,11 @@ * @msg: the message * * Emitted after receiving a 1xx (Informational) response for - * a (client-side) message. The response_headers will be - * filled in with the headers associated with the - * informational response; however, those header values will - * be erased after this signal is done. + * a (client-side) message. + * + * The response_headers will be filled in with the headers associated + * with the informational response; however, those header values will be + * erased after this signal is done. * * If you cancel or requeue @msg while processing this signal, * then the current HTTP I/O will be stopped after this signal @@ -419,17 +414,17 @@ * * Emitted after receiving the Status-Line and response headers. * - * See also soup_message_add_header_handler() and - * soup_message_add_status_code_handler(), which can be used - * to connect to a subset of emissions of this signal. + * See also method@Message.add_header_handler and + * method@Message.add_status_code_handler, which can be used to + * connect to a subset of emissions of this signal. * * If you cancel or requeue @msg while processing this signal, * then the current HTTP I/O will be stopped after this signal * emission finished, and @msg's connection will be closed. * (If you need to requeue a message--eg, after handling * authentication or redirection--it is usually better to - * requeue it from a #SoupMessage::got_body handler rather - * than a #SoupMessage::got_headers handler, so that the + * requeue it from a signal@Message::got-body handler rather + * than a signal@Message::got_headers handler, so that the * existing HTTP connection can be reused.) **/ signalsGOT_HEADERS = @@ -445,11 +440,7 @@ * SoupMessage::got-body: * @msg: the message * - * Emitted after receiving the complete message request body. - * - * See also soup_message_add_header_handler() and - * soup_message_add_status_code_handler(), which can be used - * to connect to a subset of emissions of this signal. + * Emitted after receiving the complete message response body. **/ signalsGOT_BODY = g_signal_new ("got-body", @@ -466,13 +457,13 @@ * @type: the content type that we got from sniffing * @params: (element-type utf8 utf8): a #GHashTable with the parameters * - * This signal is emitted after #SoupMessage::got-headers. + * This signal is emitted after signal@Message::got-headers. + * * If content sniffing is disabled, or no content sniffing will be * performed, due to the sniffer deciding to trust the * Content-Type sent by the server, this signal is emitted - * immediately after #SoupMessage::got-headers, and @type is + * immediately after signal@Message::got-headers, and @type is * %NULL. - * **/ signalsCONTENT_SNIFFED = g_signal_new ("content-sniffed", @@ -490,7 +481,6 @@ * @msg: the message * * Emitted just before a message is sent. - * */ signalsSTARTING = g_signal_new ("starting", @@ -506,9 +496,11 @@ * @msg: the message * * Emitted when a request that was already sent once is now - * being sent again (eg, because the first attempt received a + * being sent again. + * + * e.g. because the first attempt received a * redirection response, or because we needed to use - * authentication). + * authentication. **/ signalsRESTARTED = g_signal_new ("restarted", @@ -524,7 +516,8 @@ * @msg: the message
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/soup-misc.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/soup-misc.c
Changed
@@ -92,16 +92,16 @@ /** * soup_add_timeout: (skip) * @async_context: (nullable): the #GMainContext to dispatch the I/O - * watch in, or %NULL for the default context + * watch in, or %NULL for the default context * @interval: the timeout interval, in milliseconds * @function: the callback to invoke at timeout time * @data: user data to pass to @function * - * Adds a timeout as with g_timeout_add(), but using the given + * Adds a timeout as with func@GLib.timeout_add, but using the given * @async_context. * * Returns: (transfer full): a #GSource, which can be removed from @async_context - * with g_source_destroy(). + * with method@GLib.Source.destroy. **/ GSource * soup_add_timeout (GMainContext *async_context, @@ -114,6 +114,18 @@ return source; } +GMainContext * +soup_thread_default_context (void) +{ + GMainContext *context; + + context = g_main_context_get_thread_default (); + if (!context) + context = g_main_context_default (); + + return context; +} + /* 00 URI_UNRESERVED * 01 URI_PCT_ENCODED * 02 URI_GEN_DELIMS
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/soup-misc.h -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/soup-misc.h
Changed
@@ -24,6 +24,7 @@ guint interval, GSourceFunc function, gpointer data); +GMainContext *soup_thread_default_context (void); /* Misc utils */
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/soup-multipart-input-stream.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/soup-multipart-input-stream.c
Changed
@@ -21,27 +21,21 @@ #define RESPONSE_BLOCK_SIZE 8192 /** - * SECTION:soup-multipart-input-stream - * @short_description: Multipart input handling stream + * SoupMultipartInputStream: + * + * Handles streams of multipart messages. * * This adds support for the multipart responses. For handling the - * multiple parts the user needs to wrap the #GInputStream obtained by - * sending the request with a #SoupMultipartInputStream and use - * soup_multipart_input_stream_next_part() before reading. Responses + * multiple parts the user needs to wrap the class@Gio.InputStream obtained by + * sending the request with a class@MultipartInputStream and use + * method@MultipartInputStream.next_part before reading. Responses * which are not wrapped will be treated like non-multipart responses. * - * Note that although #SoupMultipartInputStream is a #GInputStream, + * Note that although #SoupMultipartInputStream is a class@Gio.InputStream, * you should not read directly from it, and the results are undefined * if you do. - * **/ -/** - * SoupMultipartInputStream: - * - * Class for handling streams of multipart messages. - */ - enum { PROP_0, @@ -310,6 +304,11 @@ input_stream_class->read_fn = soup_multipart_input_stream_read; + /** + * SoupMultipartInputStream:message: + * + * The class@Message. + */ propertiesPROP_MESSAGE = g_param_spec_object ("message", "Message", @@ -433,13 +432,13 @@ * @base_stream: the #GInputStream returned by sending the request. * * Creates a new #SoupMultipartInputStream that wraps the - * #GInputStream obtained by sending the #SoupMessage. Reads should - * not be done directly through this object, use the input streams - * returned by soup_multipart_input_stream_next_part() or its async + * class@Gio.InputStream obtained by sending the class@Message. + * + * Reads should not be done directly through this object, use the input streams + * returned by method@MultipartInputStream.next_part or its async * counterpart instead. * * Returns: a new #SoupMultipartInputStream - * **/ SoupMultipartInputStream * soup_multipart_input_stream_new (SoupMessage *msg, @@ -457,21 +456,20 @@ * @cancellable: a #GCancellable * @error: a #GError * - * Obtains an input stream for the next part. When dealing with a - * multipart response the input stream needs to be wrapped in a - * #SoupMultipartInputStream and this function or its async - * counterpart need to be called to obtain the first part for - * reading. + * Obtains an input stream for the next part. + * + * When dealing with a multipart response the input stream needs to be wrapped + * in a #SoupMultipartInputStream and this function or its async counterpart + * need to be called to obtain the first part for reading. * * After calling this function, - * soup_multipart_input_stream_get_headers() can be used to obtain the + * method@MultipartInputStream.get_headers can be used to obtain the * headers for the first part. A read of 0 bytes indicates the end of * the part; a new call to this function should be done at that point, * to obtain the next part. * * Returns: (nullable) (transfer full): a new #GInputStream, or - * %NULL if there are no more parts - * + * %NULL if there are no more parts */ GInputStream * soup_multipart_input_stream_next_part (SoupMultipartInputStream *multipart, @@ -523,10 +521,9 @@ * @callback: callback to call when request is satisfied. * @data: data for @callback * - * Obtains a #GInputStream for the next request. See - * soup_multipart_input_stream_next_part() for details on the - * workflow. + * Obtains a class@Gio.InputStream for the next request. * + * See method@MultipartInputStream.next_part for details on the workflow. */ void soup_multipart_input_stream_next_part_async (SoupMultipartInputStream *multipart, @@ -563,9 +560,8 @@ * Finishes an asynchronous request for the next part. * * Returns: (nullable) (transfer full): a newly created - * #GInputStream for reading the next part or %NULL if there are no - * more parts. - * + * class@Gio.InputStream for reading the next part or %NULL if there are no + * more parts. */ GInputStream * soup_multipart_input_stream_next_part_finish (SoupMultipartInputStream *multipart, @@ -581,20 +577,19 @@ * soup_multipart_input_stream_get_headers: * @multipart: a #SoupMultipartInputStream. * - * Obtains the headers for the part currently being processed. Note - * that the #SoupMessageHeaders that are returned are owned by the - * #SoupMultipartInputStream and will be replaced when a call is made - * to soup_multipart_input_stream_next_part() or its async - * counterpart, so if keeping the headers is required, a copy must be - * made. + * Obtains the headers for the part currently being processed. + * + * Note that the struct@MessageHeaders that are returned are owned by the + * #SoupMultipartInputStream and will be replaced when a call is made to + * method@MultipartInputStream.next_part or its async counterpart, so if + * keeping the headers is required, a copy must be made. * - * Note that if a part had no headers at all an empty #SoupMessageHeaders + * Note that if a part had no headers at all an empty struct@MessageHeaders * will be returned. * * Returns: (nullable) (transfer none): a #SoupMessageHeaders - * containing the headers for the part currently being processed or - * %NULL if the headers failed to parse. - * + * containing the headers for the part currently being processed or + * %NULL if the headers failed to parse. */ SoupMessageHeaders * soup_multipart_input_stream_get_headers (SoupMultipartInputStream *multipart)
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/soup-multipart.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/soup-multipart.c
Changed
@@ -17,20 +17,13 @@ #include "soup.h" /** - * SECTION:soup-multipart - * @short_description: multipart HTTP message bodies - * @see_also: #SoupMessageBody, #SoupMessageHeaders - * - * Functions to use multi-part HTTP messages. - **/ - -/** * SoupMultipart: * * Represents a multipart HTTP message body, parsed according to the - * syntax of RFC 2046. Of particular interest to HTTP are - * <literal>multipart/byte-ranges</literal> and - * <literal>multipart/form-data</literal>. + * syntax of RFC 2046. + * + * Of particular interest to HTTP are `multipart/byte-ranges` and + * `multipart/form-data`, * * Although the headers of a #SoupMultipart body part will contain the * full headers from that body part, libsoup does not interpret them @@ -81,12 +74,13 @@ * @mime_type: the MIME type of the multipart to create. * * Creates a new empty #SoupMultipart with a randomly-generated - * boundary string. Note that @mime_type must be the full MIME type, - * including "multipart/". + * boundary string. + * + * Note that @mime_type must be the full MIME type, including "multipart/". + * + * See also: ctor@Message.new_from_multipart. * * Returns: a new empty #SoupMultipart of the given @mime_type - * - * See also: soup_message_new_from_multipart() **/ SoupMultipart * soup_multipart_new (const char *mime_type) @@ -129,8 +123,7 @@ * Parses @headers and @body to form a new #SoupMultipart * * Returns: (nullable): a new #SoupMultipart (or %NULL if the - * message couldn't be parsed or wasn't multipart). - * + * message couldn't be parsed or wasn't multipart). **/ SoupMultipart * soup_multipart_new_from_message (SoupMessageHeaders *headers, @@ -224,10 +217,9 @@ * soup_multipart_get_length: * @multipart: a #SoupMultipart * - * Gets the number of body parts in @multipart + * Gets the number of body parts in @multipart. * * Returns: the number of body parts in @multipart - * **/ int soup_multipart_get_length (SoupMultipart *multipart) @@ -240,15 +232,14 @@ * @multipart: a #SoupMultipart * @part: the part number to get (counting from 0) * @headers: (out) (transfer none): return location for the MIME part - * headers + * headers * @body: (out) (transfer none): return location for the MIME part - * body + * body * * Gets the indicated body part from @multipart. * * Returns: %TRUE on success, %FALSE if @part is out of range (in - * which case @headers and @body won't be set) - * + * which case @headers and @body won't be set) **/ gboolean soup_multipart_get_part (SoupMultipart *multipart, int part, @@ -268,10 +259,10 @@ * @body: the MIME part body * * Adds a new MIME part to @multipart with the given headers and body. + * * (The multipart will make its own copies of @headers and @body, so * you should free your copies if you are not using them for anything * else.) - * **/ void soup_multipart_append_part (SoupMultipart *multipart, @@ -319,11 +310,10 @@ * @control_name: the name of the control associated with @data * @data: the body data * - * Adds a new MIME part containing @data to @multipart, using - * "Content-Disposition: form-data", as per the HTML forms - * specification. + * Adds a new MIME part containing @data to @multipart. * - **/ + * Uses "Content-Disposition: form-data", as per the HTML forms specification. + **/ void soup_multipart_append_form_string (SoupMultipart *multipart, const char *control_name, const char *data) @@ -344,11 +334,10 @@ * @content_type: the MIME type of the file, or %NULL if not known * @body: the file data * - * Adds a new MIME part containing @body to @multipart, using - * "Content-Disposition: form-data", as per the HTML forms - * specification. + * Adds a new MIME part containing @body to @multipart * - **/ + * Uses "Content-Disposition: form-data", as per the HTML forms specification. + **/ void soup_multipart_append_form_file (SoupMultipart *multipart, const char *control_name, const char *filename, @@ -384,7 +373,6 @@ * @dest_body: (out): the body of the HTTP message to serialize @multipart to * * Serializes @multipart to @dest_headers and @dest_body. - * **/ void soup_multipart_to_message (SoupMultipart *multipart, @@ -442,8 +430,7 @@ * soup_multipart_free: * @multipart: a #SoupMultipart * - * Frees @multipart - * + * Frees @multipart. **/ void soup_multipart_free (SoupMultipart *multipart)
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/soup-session-feature.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/soup-session-feature.c
Changed
@@ -14,24 +14,17 @@ #include "soup-message-private.h" /** - * SECTION:soup-session-feature - * @short_description: Interface for miscellaneous session features + * SoupSessionFeature: + * + * Interface for miscellaneous class@Session features. * * #SoupSessionFeature is the interface used by classes that extend - * the functionality of a #SoupSession. Some features like HTTP + * the functionality of a class@Session. Some features like HTTP * authentication handling are implemented internally via - * #SoupSessionFeature<!-- -->s. Other features can be added to the session - * by the application. (Eg, #SoupLogger, #SoupCookieJar.) - * - * See soup_session_add_feature(), etc, to add a feature to a session. - **/ - -/** - * SoupSessionFeature: - * - * An object that implement some sort of optional feature for - * #SoupSession. + * `SoupSessionFeature`s. Other features can be added to the session + * by the application. (Eg, class@Logger, class@CookieJar.) * + * See method@Session.add_feature, etc, to add a feature to a session. **/ /** @@ -39,14 +32,13 @@ * @parent: The parent interface. * @attach: Perform setup when a feature is added to a session * @detach: Perform cleanup when a feature is removed from a session - * @request_queued: Proxies the session's #SoupSession::request_queued signal - * @request_unqueued: Proxies the session's #SoupSession::request_unqueued signal + * @request_queued: Proxies the session's signal@Session::request_queued signal + * @request_unqueued: Proxies the session's signal@Session::request_unqueued signal * @add_feature: adds a sub-feature to the main feature * @remove_feature: removes a sub-feature from the main feature * @has_feature: tests if the feature includes a sub-feature * - * The interface implemented by #SoupSessionFeature<!-- -->s. - * + * The interface implemented by iface@SessionFeatures. **/ G_DEFINE_INTERFACE (SoupSessionFeature, soup_session_feature, G_TYPE_OBJECT) @@ -124,12 +116,12 @@ * @type: the #GType of a "sub-feature" * * Adds a "sub-feature" of type @type to the base feature @feature. + * * This is used for features that can be extended with multiple * different types. Eg, the authentication manager can be extended - * with subtypes of #SoupAuth. + * with subtypes of class@Auth. * * Returns: %TRUE if @feature accepted @type as a subfeature. - * */ gboolean soup_session_feature_add_feature (SoupSessionFeature *feature, @@ -150,10 +142,11 @@ * @type: the #GType of a "sub-feature" * * Removes the "sub-feature" of type @type from the base feature - * @feature. See soup_session_feature_add_feature(). + * @feature. * - * Returns: %TRUE if @type was removed from @feature + * See method@SessionFeature.add_feature. * + * Returns: %TRUE if @type was removed from @feature */ gboolean soup_session_feature_remove_feature (SoupSessionFeature *feature, @@ -173,11 +166,11 @@ * @feature: the "base" feature * @type: the #GType of a "sub-feature" * - * Tests if @feature has a "sub-feature" of type @type. See - * soup_session_feature_add_feature(). + * Tests if @feature has a "sub-feature" of type @type. * - * Returns: %TRUE if @feature has a subfeature of type @type + * See method@SessionFeature.add_feature. * + * Returns: %TRUE if @feature has a subfeature of type @type */ gboolean soup_session_feature_has_feature (SoupSessionFeature *feature,
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/soup-session-private.h -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/soup-session-private.h
Changed
@@ -7,7 +7,10 @@ #define __SOUP_SESSION_PRIVATE_H__ 1 #include "soup-session.h" +#include "soup-connection.h" #include "soup-content-processor.h" +#include "soup-message-queue-item.h" +#include "soup-socket-properties.h" G_BEGIN_DECLS @@ -31,6 +34,16 @@ GSList *soup_session_get_features (SoupSession *session, GType feature_type); +gboolean soup_session_steal_preconnection (SoupSession *session, + SoupMessageQueueItem *item, + SoupConnection *conn); + +void soup_session_kick_queue (SoupSession *session); + +SoupSocketProperties *soup_session_ensure_socket_props (SoupSession *session); + +GMainContext *soup_session_get_context (SoupSession *session); + G_END_DECLS #endif /* __SOUP_SESSION_PRIVATE_H__ */
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/soup-session.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/soup-session.c
Changed
@@ -16,7 +16,7 @@ #include "auth/soup-auth-manager.h" #include "auth/soup-auth-ntlm.h" #include "cache/soup-cache-private.h" -#include "soup-connection.h" +#include "soup-connection-manager.h" #include "soup-message-private.h" #include "soup-message-headers-private.h" #include "soup-misc.h" @@ -29,11 +29,10 @@ #include "websocket/soup-websocket-connection.h" #include "websocket/soup-websocket-extension-manager-private.h" -#define HOST_KEEP_ALIVE 5 * 60 * 1000 /* 5 min in msecs */ - /** - * SECTION:soup-session - * @short_description: Soup session state object + * SoupSession: + * + * Soup session state object. * * #SoupSession is the object that controls client-side HTTP. A * #SoupSession encapsulates all of the state that libsoup is keeping @@ -45,54 +44,31 @@ * reason you might need multiple sessions is if you need to have * multiple independent authentication contexts. (Eg, you are * connecting to a server and authenticating as two different users at - * different times; the easiest way to ensure that each #SoupMessage + * different times; the easiest way to ensure that each class@Message * is sent with the authentication information you intended is to use * one session for the first user, and a second session for the other * user.) * * Additional #SoupSession functionality is provided by - * #SoupSessionFeature objects, which can be added to a session with - * soup_session_add_feature() or soup_session_add_feature_by_type() - * For example, #SoupLogger provides support for - * logging HTTP traffic, #SoupContentDecoder provides support for - * compressed response handling, and #SoupContentSniffer provides + * iface@SessionFeature objects, which can be added to a session with + * method@Session.add_feature or method@Session.add_feature_by_type + * For example, class@Logger provides support for + * logging HTTP traffic, class@ContentDecoder provides support for + * compressed response handling, and class@ContentSniffer provides * support for HTML5-style response body content sniffing. - * Additionally, subtypes of #SoupAuth can be added + * Additionally, subtypes of class@Auth can be added * as features, to add support for additional authentication types. * - * All #SoupSessions are created with a #SoupAuthManager, and support + * All `SoupSession`s are created with a class@AuthManager, and support * for %SOUP_TYPE_AUTH_BASIC and %SOUP_TYPE_AUTH_DIGEST. Additionally, * sessions using the plain #SoupSession class (rather than one of its deprecated - * subtypes) have a #SoupContentDecoder by default. + * subtypes) have a class@ContentDecoder by default. * * Note that all async methods will invoke their callbacks on the thread-default * context at the time of the function call. **/ -/** - * SoupSession: - * - * Class managing options and state for #SoupMessage<!-- -->s. - */ - -typedef struct { - GUri *uri; - GNetworkAddress *addr; - - GSList *connections; /* CONTAINS: SoupConnection */ - guint num_conns; - - guint num_messages; - - GSource *keep_alive_src; - SoupSession *session; -} SoupSessionHost; -static guint soup_host_uri_hash (gconstpointer key); -static gboolean soup_host_uri_equal (gconstpointer v1, gconstpointer v2); - typedef struct { - gboolean disposed; - GTlsDatabase *tlsdb; GTlsInteraction *tls_interaction; gboolean tlsdb_use_default; @@ -105,45 +81,31 @@ SoupSocketProperties *socket_props; + GMainContext *context; + GMutex queue_mutex; GQueue *queue; - GSource *queue_source; - guint16 in_async_run_queue; + GMutex queue_sources_mutex; + GHashTable *queue_sources; + gint num_async_items; + guint in_async_run_queue; gboolean needs_queue_sort; char *user_agent; char *accept_language; gboolean accept_language_auto; - GSocketConnectable *remote_connectable; - GSList *features; - GHashTable *features_cache; - GHashTable *http_hosts, *https_hosts; /* char* -> SoupSessionHost */ - GHashTable *conns; /* SoupConnection -> SoupSessionHost */ - guint num_conns; - guint max_conns, max_conns_per_host; - guint64 last_connection_id; + SoupConnectionManager *conn_manager; } SoupSessionPrivate; -static void free_host (SoupSessionHost *host); -static void connection_state_changed (GObject *object, GParamSpec *param, - gpointer user_data); -static void connection_disconnected (SoupConnection *conn, gpointer user_data); -static void drop_connection (SoupSession *session, SoupSessionHost *host, - SoupConnection *conn); - static void async_run_queue (SoupSession *session); static void async_send_request_running (SoupSession *session, SoupMessageQueueItem *item); -static void soup_session_kick_queue (SoupSession *session); - -static void -soup_session_process_queue_item (SoupSession *session, - SoupMessageQueueItem *item, - gboolean *should_cleanup, - gboolean loop); +static void soup_session_process_queue_item (SoupSession *session, + SoupMessageQueueItem *item, + gboolean loop); #define SOUP_SESSION_MAX_CONNS_DEFAULT 10 #define SOUP_SESSION_MAX_CONNS_PER_HOST_DEFAULT 2 @@ -184,12 +146,6 @@ static GParamSpec *propertiesLAST_PROPERTY = { NULL, }; /** - * SOUP_SESSION_ERROR: - * - * A #GError domain for #SoupSession<!-- -->-related errors. Used with - * #SoupSessionError. - */ -/** * SoupSessionError: * @SOUP_SESSION_ERROR_PARSING: the server's response could not * be parsed @@ -212,7 +168,8 @@ typedef struct { GSource source; - SoupSession* session; + GWeakRef session; + guint num_items; } SoupMessageQueueSource; static gboolean @@ -220,48 +177,127 @@ GSourceFunc callback, gpointer user_data) { - SoupSession *session = ((SoupMessageQueueSource *)source)->session; + SoupMessageQueueSource *queue_source = (SoupMessageQueueSource *)source; + SoupSession *session = g_weak_ref_get (&queue_source->session); + + if (!session) + return G_SOURCE_REMOVE; g_source_set_ready_time (source, -1); async_run_queue (session); + g_object_unref (session); + return G_SOURCE_CONTINUE; } +static void +queue_finalize (GSource *source) +{ + SoupMessageQueueSource *queue_source = (SoupMessageQueueSource *)source; + + g_weak_ref_clear (&queue_source->session); +} + static GSourceFuncs queue_source_funcs = { NULL, //queue_prepare, NULL, //queue_check, queue_dispatch, - NULL, NULL, NULL + queue_finalize, + NULL, NULL
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/soup-session.h -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/soup-session.h
Changed
@@ -33,6 +33,12 @@ void (*_soup_reserved8) (void); }; +/** + * soup_session_error_quark: + * Registers error quark for SoupSession if needed. + * + * Returns: Error quark for SoupSession. + */ SOUP_AVAILABLE_IN_ALL GQuark soup_session_error_quark (void); #define SOUP_SESSION_ERROR soup_session_error_quark ()
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/soup-status.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/soup-status.c
Changed
@@ -13,14 +13,6 @@ #include "soup.h" /** - * SECTION:soup-status - * @section_id: SoupStatus - * @short_description: HTTP (and libsoup) status codes - * - * HTTP (and libsoup) status codes. - **/ - -/** * SOUP_STATUS_IS_INFORMATIONAL: * @status: an HTTP status code * @@ -224,10 +216,10 @@ * * Looks up the stock HTTP description of @status_code. * - * <emphasis>There is no reason for you to ever use this - * function.</emphasis> If you wanted the textual description for the - * #SoupMessage:status_code of a given #SoupMessage, you should just - * look at the message's #SoupMessage:reason_phrase. However, you + * *There is no reason for you to ever use this + * function.* If you wanted the textual description for the + * property@Message:status-code of a given class@Message, you should just + * look at the message's property@Message:reason-phrase. However, you * should only do that for use in debugging messages; HTTP reason * phrases are not localized, and are not generally very descriptive * anyway, and so they should never be presented to the user directly.
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/soup-tld.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/soup-tld.c
Changed
@@ -17,16 +17,6 @@ #include "soup-tld.h" #include "soup.h" -/** - * SECTION:soup-tld - * @section_id: SoupTLD - * @short_description: Top-Level Domain Utilities - * - * These functions can be used to parse hostnames to attempt to determine - * what part of the name belongs to the domain owner, and what part is - * simply a "public suffix" such as ".com". - */ - static const char *soup_tld_get_base_domain_internal (const char *hostname, GError **error); @@ -36,10 +26,11 @@ * @error: return location for a #GError, or %NULL to ignore * errors. See #SoupTLDError for the available error codes * - * Finds the base domain for a given @hostname. The base domain is - * composed by the top level domain (such as .org, .com, .co.uk, etc) - * plus the second level domain, for example for myhost.mydomain.com - * it will return mydomain.com. + * Finds the base domain for a given @hostname + * + * The base domain is composed by the top level domain (such as .org, .com, + * .co.uk, etc) plus the second level domain, for example for + * myhost.mydomain.com it will return mydomain.com. * * Note that %NULL will be returned for private URLs (those not ending * with any well known TLD) because choosing a base domain for them @@ -51,8 +42,7 @@ * format). * * Returns: a pointer to the start of the base domain in @hostname. If - * an error occurs, %NULL will be returned and @error set. - * + * an error occurs, %NULL will be returned and @error set. **/ const char * soup_tld_get_base_domain (const char *hostname, GError **error) @@ -85,7 +75,6 @@ * UTF-8 or ASCII format. * * Returns: %TRUE if it is a public domain, %FALSE otherwise. - * **/ gboolean soup_tld_domain_is_public_suffix (const char *domain) @@ -106,7 +95,6 @@ * SOUP_TLD_ERROR: * * The #GError domain for soup-tld-related errors. - * */ /** * SoupTLDError: @@ -117,14 +105,13 @@ * public suffix). * @SOUP_TLD_ERROR_NOT_ENOUGH_DOMAINS: The passed-in hostname * did not have enough components. Eg, calling - * soup_tld_get_base_domain() on <literal>"co.uk"</literal>. + * func@tld_get_base_domain on <literal>"co.uk"</literal>. * @SOUP_TLD_ERROR_NO_BASE_DOMAIN: The passed-in hostname has * no recognized public suffix. * @SOUP_TLD_ERROR_NO_PSL_DATA: The Public Suffix List was not * available. * * Error codes for %SOUP_TLD_ERROR. - * */ G_DEFINE_QUARK (soup-tld-error-quark, soup_tld_error)
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/soup-tld.h -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/soup-tld.h
Changed
@@ -16,7 +16,13 @@ SOUP_AVAILABLE_IN_ALL gboolean soup_tld_domain_is_public_suffix (const char *domain); -/* Errors */ + +/** + * soup_tld_error_quark: + * Registers error quark for soup_tld_get_base_domain() if needed. + * + * Returns: Error quark for Soup TLD functions. + */ SOUP_AVAILABLE_IN_ALL GQuark soup_tld_error_quark (void); #define SOUP_TLD_ERROR soup_tld_error_quark()
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/soup-uri-utils.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/soup-uri-utils.c
Changed
@@ -33,15 +33,6 @@ #include "soup-misc.h" /** - * SECTION:soup-uri-utils - * @section_id: SoupURIUtils - * @title: URI Utilities - * @short_description: Functions to help working with #GUri and HTTP - * - * Utility functions and defines to help working with URIs. - */ - -/** * SOUP_HTTP_URI_FLAGS: * * The set of #GUriFlags libsoup expects all #GUri to use. @@ -99,7 +90,7 @@ * @uri1: a #GUri * @uri2: another #GUri * - * Tests whether or not @uri1 and @uri2 are equal in all parts + * Tests whether or not @uri1 and @uri2 are equal in all parts. * * Returns: %TRUE if equal otherwise %FALSE **/ @@ -150,9 +141,10 @@ * soup_uri_uses_default_port: * @uri: a #GUri * - * Tests if @uri uses the default port for its scheme. (Eg, 80 for - * http.) (This only works for http, https and ftp; libsoup does not know - * the default ports of other protocols.) + * Tests if @uri uses the default port for its scheme. + * + * (Eg, 80 for http.) (This only works for http, https and ftp; libsoup does not + * know the default ports of other protocols.) * * Returns: %TRUE or %FALSE **/ @@ -278,7 +270,7 @@ /** * soup_uri_decode_data_uri: * @uri: a data URI, in string form - * @content_type: (out) (nullable) (transfer full): location to store content type, or %NULL + * @content_type: (out) (nullable) (transfer full): location to store content type * * Decodes the given data URI and returns its contents and @content_type. * @@ -367,7 +359,7 @@ * @SOUP_URI_QUERY: the URI query component * @SOUP_URI_FRAGMENT: the URI fragment component * - * Enum values passed to soup_uri_copy() to indicate the components of + * Enum values passed to func@uri_copy to indicate the components of * the URI that should be updated with the given values. */ @@ -378,7 +370,7 @@ * @...: value of @first_component followed by additional * components and values, terminated by %SOUP_URI_NONE * - * Return a copy of @uri with the given components updated + * Return a copy of @uri with the given components updated. * * Returns: (transfer full): a new #GUri */
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/soup-version.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/soup-version.c
Changed
@@ -12,26 +12,18 @@ #include "soup-version.h" /** - * SECTION:soup-version - * @section_id: SoupVersion - * @short_description: Variables and functions to check the libsoup version - * - * Variables and functions to check the libsoup version. - **/ - -/** * SOUP_MAJOR_VERSION: * - * Like soup_get_major_version(), but from the headers used at - * application compile time, rather than from the library linked - * against at application run time. + * Like func@get_major_version, but from the headers used at application + * compile time, rather than from the library linked against at application run + * time. * */ /** * SOUP_MINOR_VERSION: * - * Like soup_get_minor_version(), but from the headers used at + * Like func@get_minor_version, but from the headers used at * application compile time, rather than from the library linked * against at application run time. * @@ -40,7 +32,7 @@ /** * SOUP_MICRO_VERSION: * - * Like soup_get_micro_version(), but from the headers used at + * Like func@get_micro_version, but from the headers used at * application compile time, rather than from the library linked * against at application run time. * @@ -54,16 +46,16 @@ * * Macro to test the version of libsoup being compiled against. * - * Returns: %TRUE if the version of the libsoup header files + * Returns %TRUE if the version of the libsoup header files * is the same as or newer than the passed-in version. - * */ /** * soup_get_major_version: * * Returns the major version number of the libsoup library. - * (e.g. in libsoup version 2.42.0 this is 2.) + * + * e.g. in libsoup version 2.42.0 this is 2. * * This function is in the library, so it represents the libsoup library * your code is running against. Contrast with the #SOUP_MAJOR_VERSION @@ -71,7 +63,6 @@ * have included when compiling your code. * * Returns: the major version number of the libsoup library - * */ guint soup_get_major_version (void) @@ -83,7 +74,8 @@ * soup_get_minor_version: * * Returns the minor version number of the libsoup library. - * (e.g. in libsoup version 2.42.0 this is 42.) + * + * e.g. in libsoup version 2.42.0 this is 42. * * This function is in the library, so it represents the libsoup library * your code is running against. Contrast with the #SOUP_MINOR_VERSION @@ -91,7 +83,6 @@ * have included when compiling your code. * * Returns: the minor version number of the libsoup library - * */ guint soup_get_minor_version (void) @@ -103,7 +94,8 @@ * soup_get_micro_version: * * Returns the micro version number of the libsoup library. - * (e.g. in libsoup version 2.42.0 this is 0.) + * + * e.g. in libsoup version 2.42.0 this is 0. * * This function is in the library, so it represents the libsoup library * your code is running against. Contrast with the #SOUP_MICRO_VERSION @@ -111,7 +103,6 @@ * have included when compiling your code. * * Returns: the micro version number of the libsoup library - * */ guint soup_get_micro_version (void) @@ -125,14 +116,14 @@ * @minor: the minor version to check * @micro: the micro version to check * - * Like SOUP_CHECK_VERSION, but the check for soup_check_version is - * at runtime instead of compile time. This is useful for compiling - * against older versions of libsoup, but using features from newer - * versions. + * Like func@CHECK_VERSION, but the check for soup_check_version is + * at runtime instead of compile time. * - * Returns: %TRUE if the version of the libsoup currently loaded - * is the same as or newer than the passed-in version. + * This is useful for compiling against older versions of libsoup, but using + * features from newer versions. * + * Returns: %TRUE if the version of the libsoup currently loaded + * is the same as or newer than the passed-in version. */ gboolean soup_check_version (guint major, @@ -146,7 +137,9 @@ * SOUP_VERSION_MIN_REQUIRED: * * A macro that should be defined by the user prior to including - * libsoup.h. The definition should be one of the predefined libsoup + * `libsoup.h`. + * + * The definition should be one of the predefined libsoup * version macros: %SOUP_VERSION_2_24, %SOUP_VERSION_2_26, ... * * This macro defines the earliest version of libsoup that the package @@ -156,14 +149,15 @@ * functions, then using functions that were deprecated in version * %SOUP_VERSION_MIN_REQUIRED or earlier will cause warnings (but * using functions deprecated in later releases will not). - * */ /** * SOUP_VERSION_MAX_ALLOWED: * * A macro that should be defined by the user prior to including - * libsoup.h. The definition should be one of the predefined libsoup + * libsoup.h. + * + * The definition should be one of the predefined libsoup * version macros: %SOUP_VERSION_2_24, %SOUP_VERSION_2_26, ... * * This macro defines the latest version of the libsoup API that the @@ -173,8 +167,7 @@ * functions, then using functions added after version * %SOUP_VERSION_MAX_ALLOWED will cause warnings. * - * Unless you are using SOUP_CHECK_VERSION() or the like to compile + * Unless you are using func@CHECK_VERSION or the like to compile * different code depending on the libsoup version, then this should be * set to the same value as %SOUP_VERSION_MIN_REQUIRED. - * */
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/soup-version.h.in -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/soup-version.h.in
Changed
@@ -91,6 +91,52 @@ #error "SOUP_VERSION_MIN_REQUIRED must be >= SOUP_VERSION_3_0" #endif +/** + * SOUP_DISABLE_DEPRECATION_WARNINGS: + * + * A macro that should be defined before including the `soup.h` header. + * + * If this symbol is defined, no compiler warnings will be produced for + * uses of deprecated libsoup APIs. + */ + +/** + * SOUP_DEPRECATED: + * + * Marks a symbol as deprecated. + * + * You should use `SOUP_DEPRECATED_IN_*` in order to handle versioning. + */ + +/** + * SOUP_DEPRECATED_FOR: + * @f: the symbol that replaces the deprecated one + * + * Marks a symbol as deprecated in favor of another symbol. + * + * You should use `SOUP_DEPRECATED_FOR_IN_*` in order to handle versioning. + */ + +/** + * SOUP_UNAVAILABLE + * @maj: the major version that introduced the symbol + * @min: the minor version that introduced the symbol + * + * Marks a symbol unavailable before the given major and minor version. + * + * You should use `SOUP_AVAILABLE_IN_*` in order to handle versioning. + */ + +#ifdef SOUP_DISABLE_DEPRECATION_WARNINGS +#define SOUP_DEPRECATED _SOUP_EXTERN +#define SOUP_DEPRECATED_FOR(f) _SOUP_EXTERN +#define SOUP_UNAVAILABLE(maj,min) _SOUP_EXTERN +#else +#define SOUP_DEPRECATED G_DEPRECATED _SOUP_EXTERN +#define SOUP_DEPRECATED_FOR(f) G_DEPRECATED_FOR(f) _SOUP_EXTERN +#define SOUP_UNAVAILABLE(maj,min) G_UNAVAILABLE(maj,min) _SOUP_EXTERN +#endif + #define SOUP_AVAILABLE_IN_ALL _SOUP_EXTERN {version_attributes}
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/websocket/soup-websocket-connection.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/websocket/soup-websocket-connection.c
Changed
@@ -29,48 +29,40 @@ #include "soup-websocket-extension.h" /* - * SECTION:websocketconnection - * @title: SoupWebsocketConnection - * @short_description: A WebSocket connection + * SoupWebsocketConnection: + * + * A WebSocket connection. * * A #SoupWebsocketConnection is a WebSocket connection to a peer. * This API is modeled after the W3C API for interacting with * WebSockets. * - * The #SoupWebsocketConnection:state property will indicate the + * The property@WebsocketConnection:state property will indicate the * state of the connection. * - * Use soup_websocket_connection_send() to send a message to the peer. - * When a message is received the #SoupWebsocketConnection::message + * Use method@WebsocketConnection.send to send a message to the peer. + * When a message is received the signal@WebsocketConnection::message * signal will fire. * - * The soup_websocket_connection_close() function will perform an + * The method@WebsocketConnection.close function will perform an * orderly close of the connection. The - * #SoupWebsocketConnection::closed signal will fire once the + * signal@WebsocketConnection::closed signal will fire once the * connection closes, whether it was initiated by this side or the * peer. * - * Connect to the #SoupWebsocketConnection::closing signal to detect + * Connect to the signal@WebsocketConnection::closing signal to detect * when either peer begins closing the connection. */ /** - * SoupWebsocketConnection: - * - * A class representing a WebSocket connection. - * - */ - -/** * SoupWebsocketConnectionClass: - * @message: default handler for the #SoupWebsocketConnection::message signal - * @error: default handler for the #SoupWebsocketConnection::error signal - * @closing: the default handler for the #SoupWebsocketConnection:closing signal - * @closed: default handler for the #SoupWebsocketConnection::closed signal - * @pong: default handler for the #SoupWebsocketConnection::pong signal - * - * The abstract base class for #SoupWebsocketConnection + * @message: default handler for the signal@WebsocketConnection::message signal + * @error: default handler for the signal@WebsocketConnection::error signal + * @closing: the default handler for the signal@WebsocketConnection:closing signal + * @closed: default handler for the signal@WebsocketConnection::closed signal + * @pong: default handler for the signal@WebsocketConnection::pong signal * + * The abstract base class for class@WebsocketConnection. */ enum { @@ -727,7 +719,7 @@ code = 0; break; default: - if (code < 3000) { + if (code < 3000 || code >= 5000) { g_debug ("Wrong closing code %d received", code); protocol_error_and_close (self); return; @@ -774,6 +766,18 @@ break; } + /* 1005, 1006 and 1015 are reserved values and MUST NOT be set as a status code in a Close control frame by an endpoint */ + switch (priv->peer_close_code) { + case SOUP_WEBSOCKET_CLOSE_NO_STATUS: + case SOUP_WEBSOCKET_CLOSE_ABNORMAL: + case SOUP_WEBSOCKET_CLOSE_TLS_HANDSHAKE: + g_debug ("received a broken close frame containing reserved status code %u", priv->peer_close_code); + protocol_error_and_close (self); + return; + default: + break; + } + if (len > 2) { data += 2; len -= 2; @@ -1486,7 +1490,6 @@ * over. * * The input and output streams must be pollable streams. - * */ propertiesPROP_IO_STREAM = g_param_spec_object ("io-stream", @@ -1501,7 +1504,6 @@ * SoupWebsocketConnection:connection-type: * * The type of connection (client/server). - * */ propertiesPROP_CONNECTION_TYPE = g_param_spec_enum ("connection-type", @@ -1520,7 +1522,6 @@ * * For servers this represents the address of the WebSocket, * and for clients it is the address connected to. - * */ propertiesPROP_URI = g_param_spec_boxed ("uri", @@ -1535,7 +1536,6 @@ * SoupWebsocketConnection:origin: * * The client's Origin. - * */ propertiesPROP_ORIGIN = g_param_spec_string ("origin", @@ -1551,7 +1551,6 @@ * * The chosen protocol, or %NULL if a protocol was not agreed * upon. - * */ propertiesPROP_PROTOCOL = g_param_spec_string ("protocol", @@ -1566,7 +1565,6 @@ * SoupWebsocketConnection:state: * * The current state of the WebSocket. - * */ propertiesPROP_STATE = g_param_spec_enum ("state", @@ -1580,9 +1578,9 @@ /** * SoupWebsocketConnection:max-incoming-payload-size: * - * The maximum payload size for incoming packets the protocol expects - * or 0 to not limit it. + * The maximum payload size for incoming packets. * + * The protocol expects or 0 to not limit it. */ propertiesPROP_MAX_INCOMING_PAYLOAD_SIZE = g_param_spec_uint64 ("max-incoming-payload-size", @@ -1599,9 +1597,9 @@ * SoupWebsocketConnection:keepalive-interval: * * Interval in seconds on when to send a ping message which will - * serve as a keepalive message. If set to 0 the keepalive message is - * disabled. + * serve as a keepalive message. * + * If set to 0 the keepalive message is disabled. */ propertiesPROP_KEEPALIVE_INTERVAL = g_param_spec_uint ("keepalive-interval", @@ -1617,8 +1615,7 @@ /** * SoupWebsocketConnection:extensions: * - * List of #SoupWebsocketExtension objects that are active in the connection. - * + * List of class@WebsocketExtension objects that are active in the connection. */ propertiesPROP_EXTENSIONS = g_param_spec_pointer ("extensions", @@ -1639,9 +1636,8 @@ * Emitted when we receive a message from the peer. * * As a convenience, the @message data will always be - * NUL-terminated, but the NUL byte will not be included in + * %NULL-terminated, but the NUL byte will not be included in * the length count. - * */ signalsMESSAGE = g_signal_new ("message", SOUP_TYPE_WEBSOCKET_CONNECTION, @@ -1655,10 +1651,10 @@ * @self: the WebSocket * @error: the error that occured * - * Emitted when an error occurred on the WebSocket. This may - * be fired multiple times. Fatal errors will be followed by - * the #SoupWebsocketConnection::closed signal being emitted. + * Emitted when an error occurred on the WebSocket. * + * This may be fired multiple times. Fatal errors will be followed by + * the signal@WebsocketConnection::closed signal being emitted. */ signalsERROR = g_signal_new ("error", SOUP_TYPE_WEBSOCKET_CONNECTION, @@ -1672,7 +1668,6 @@
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/websocket/soup-websocket-extension-deflate.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/websocket/soup-websocket-extension-deflate.c
Changed
@@ -69,19 +69,11 @@ /** * SoupWebsocketExtensionDeflate: * - * A SoupWebsocketExtensionDeflate is a #SoupWebsocketExtension + * A SoupWebsocketExtensionDeflate is a class@WebsocketExtension * implementing permessage-deflate (RFC 7692). * - * This extension is used by default in a #SoupSession when #SoupWebsocketExtensionManager - * feature is present, and always used by #SoupServer. - * - */ - -/** - * SOUP_TYPE_WEBSOCKET_EXTENSION_DEFLATE: - * - * A #GType corresponding to permessage-deflate WebSocket extension. - * + * This extension is used by default in a class@Session when class@WebsocketExtensionManager + * feature is present, and always used by class@Server. */ G_DEFINE_FINAL_TYPE_WITH_PRIVATE (SoupWebsocketExtensionDeflate, soup_websocket_extension_deflate, SOUP_TYPE_WEBSOCKET_EXTENSION)
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/websocket/soup-websocket-extension-manager.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/websocket/soup-websocket-extension-manager.c
Changed
@@ -35,24 +35,22 @@ /** * SoupWebsocketExtensionManager: * - * SoupWebsocketExtensionManager is the #SoupSessionFeature that handles WebSockets - * extensions for a #SoupSession. + * SoupWebsocketExtensionManager is the iface@SessionFeature that handles WebSockets + * extensions for a class@Session. * - * A SoupWebsocketExtensionManager is added to the session by default, and normally + * A #SoupWebsocketExtensionManager is added to the session by default, and normally * you don't need to worry about it at all. However, if you want to * disable WebSocket extensions, you can remove the feature from the - * session with soup_session_remove_feature_by_type(), or disable it on - * individual requests with soup_message_disable_feature(). - * + * session with method@Session.remove_feature_by_type or disable it on + * individual requests with method@Message.disable_feature. **/ /** * SOUP_TYPE_WEBSOCKET_EXTENSION_MANAGER: * - * The #GType of #SoupWebsocketExtensionManager; you can use this with - * soup_session_remove_feature_by_type() or - * soup_message_disable_feature(). - * + * The #GType of class@WebsocketExtensionManager; you can use this with + * method@Session.remove_feature_by_type or + * method@Message.disable_feature. */ static void soup_websocket_extension_manager_session_feature_init (SoupSessionFeatureInterface *feature_interface, gpointer interface_data);
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/websocket/soup-websocket-extension.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/websocket/soup-websocket-extension.c
Changed
@@ -27,18 +27,11 @@ #include "soup-websocket-extension.h" /** - * SECTION:soup-websocket-extension - * @short_description: a WebSocket extension - * @see_also: #SoupSession, #SoupWebsocketExtensionManager - * - * SoupWebsocketExtension is the base class for WebSocket extension objects. - * - */ - -/** * SoupWebsocketExtension: * - * Class for impelementing websocket extensions. + * A WebSocket extension + * + * #SoupWebsocketExtension is the base class for WebSocket extension objects. */ /** @@ -55,8 +48,7 @@ * @process_incoming_message: called to process the payload data of a message * after it's received. Reserved bits of the header should be cleared. * - * The class structure for the SoupWebsocketExtension. - * + * The class structure for the #SoupWebsocketExtension. */ G_DEFINE_ABSTRACT_TYPE (SoupWebsocketExtension, soup_websocket_extension, G_TYPE_OBJECT) @@ -75,10 +67,10 @@ * soup_websocket_extension_configure: * @extension: a #SoupWebsocketExtension * @connection_type: either %SOUP_WEBSOCKET_CONNECTION_CLIENT or %SOUP_WEBSOCKET_CONNECTION_SERVER - * @params: (nullable): the parameters, or %NULL + * @params: (nullable): the parameters * @error: return location for a #GError * - * Configures @extension with the given @params + * Configures @extension with the given @params. * * Returns: %TRUE if extension could be configured with the given parameters, or %FALSE otherwise */ @@ -105,11 +97,12 @@ * soup_websocket_extension_get_request_params: * @extension: a #SoupWebsocketExtension * - * Get the parameters strings to be included in the request header. If the extension - * doesn't include any parameter in the request, this function returns %NULL. + * Get the parameters strings to be included in the request header. * - * Returns: (nullable) (transfer full): a new allocated string with the parameters + * If the extension doesn't include any parameter in the request, this function + * returns %NULL. * + * Returns: (nullable) (transfer full): a new allocated string with the parameters */ char * soup_websocket_extension_get_request_params (SoupWebsocketExtension *extension) @@ -129,11 +122,12 @@ * soup_websocket_extension_get_response_params: * @extension: a #SoupWebsocketExtension * - * Get the parameters strings to be included in the response header. If the extension - * doesn't include any parameter in the response, this function returns %NULL. + * Get the parameters strings to be included in the response header. * - * Returns: (nullable) (transfer full): a new allocated string with the parameters + * If the extension doesn't include any parameter in the response, this function + * returns %NULL. * + * Returns: (nullable) (transfer full): a new allocated string with the parameters */ char * soup_websocket_extension_get_response_params (SoupWebsocketExtension *extension) @@ -156,14 +150,15 @@ * @payload: (transfer full): the payload data * @error: return location for a #GError * - * Process a message before it's sent. If the payload isn't changed the given - * @payload is just returned, otherwise g_bytes_unref() is called on the given - * @payload and a new #GBytes is returned with the new data. + * Process a message before it's sent. + * + * If the payload isn't changed the given @payload is just returned, otherwise + * method@Glib.Bytes.unref is called on the given @payload and a new + * struct@GLib.Bytes is returned with the new data. * * Extensions using reserved bits of the header will change them in @header. * * Returns: (transfer full): the message payload data, or %NULL in case of error - * */ GBytes * soup_websocket_extension_process_outgoing_message (SoupWebsocketExtension *extension, @@ -192,14 +187,15 @@ * @payload: (transfer full): the payload data * @error: return location for a #GError * - * Process a message after it's received. If the payload isn't changed the given - * @payload is just returned, otherwise g_bytes_unref() is called on the given - * @payload and a new #GBytes is returned with the new data. + * Process a message after it's received. + * + * If the payload isn't changed the given @payload is just returned, otherwise + * method@GLib.Bytes.unref is called on the given @payload and a new + * struct@GLib.Bytes is returned with the new data. * * Extensions using reserved bits of the header will reset them in @header. * * Returns: (transfer full): the message payload data, or %NULL in case of error - * */ GBytes * soup_websocket_extension_process_incoming_message (SoupWebsocketExtension *extension,
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/websocket/soup-websocket.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/websocket/soup-websocket.c
Changed
@@ -34,42 +34,37 @@ #define FIXED_DIGEST_LEN 20 /** - * SECTION:soup-websocket - * @section_id: SoupWebsocket - * @short_description: The WebSocket Protocol - * @see_also: soup_session_websocket_connect_async(), - * soup_server_add_websocket_handler() + * SoupWebsocketConnection: * - * #SoupWebsocketConnection provides support for the <ulink - * url="http://tools.ietf.org/html/rfc6455">WebSocket</ulink> protocol. + * The WebSocket Protocol * - * To connect to a WebSocket server, create a #SoupSession and call - * soup_session_websocket_connect_async(). To accept WebSocket - * connections, create a #SoupServer and add a handler to it with - * soup_server_add_websocket_handler(). + * Provides support for the WebSocket(http://tools.ietf.org/html/rfc6455) + * protocol. * - * (Lower-level support is available via - * soup_websocket_client_prepare_handshake() and - * soup_websocket_client_verify_handshake(), for handling the client - * side of the WebSocket handshake, and - * soup_websocket_server_process_handshake() for handling the server - * side.) - * - * #SoupWebsocketConnection handles the details of WebSocket - * communication. You can use soup_websocket_connection_send_text() - * and soup_websocket_connection_send_binary() to send data, and the - * #SoupWebsocketConnection::message signal to receive data. - * (#SoupWebsocketConnection currently only supports asynchronous - * I/O.) + * To connect to a WebSocket server, create a class@Session and call + * method@Session.websocket_connect_async. To accept WebSocket + * connections, create a class@Server and add a handler to it with + * method@Server.add_websocket_handler. * + * (Lower-level support is available via + * func@websocket_client_prepare_handshake and + * func@websocket_client_verify_handshake, for handling the client side of the + * WebSocket handshake, and func@websocket_server_process_handshake for + * handling the server side.) + * + * #SoupWebsocketConnection handles the details of WebSocket communication. You + * can use method@WebsocketConnection.send_text and + * method@WebsocketConnection.send_binary to send data, and the + * signal@WebsocketConnection::message signal to receive data. + * (#SoupWebsocketConnection currently only supports asynchronous I/O.) */ /** * SOUP_WEBSOCKET_ERROR: * - * A #GError domain for WebSocket-related errors. Used with - * #SoupWebsocketError. + * A struct@GLib.Error domain for WebSocket-related errors. * + * Used with error@WebsocketError. */ /** @@ -83,7 +78,6 @@ * because the "Origin" header was not an allowed value. * * WebSocket-related errors. - * */ /** @@ -92,8 +86,7 @@ * @SOUP_WEBSOCKET_CONNECTION_CLIENT: a client-side connection * @SOUP_WEBSOCKET_CONNECTION_SERVER: a server-side connection * - * The type of a #SoupWebsocketConnection. - * + * The type of a class@WebsocketConnection. */ /** @@ -101,9 +94,7 @@ * @SOUP_WEBSOCKET_DATA_TEXT: UTF-8 text * @SOUP_WEBSOCKET_DATA_BINARY: binary data * - * The type of data contained in a #SoupWebsocketConnection::message - * signal. - * + * The type of data contained in a signal@WebsocketConnection::message signal. */ /** @@ -132,10 +123,10 @@ * the TLS handshake failed; must not be sent. * * Pre-defined close codes that can be passed to - * soup_websocket_connection_close() or received from - * soup_websocket_connection_get_close_code(). (However, other codes - * are also allowed.) + * method@WebsocketConnection.close or received from + * method@WebsocketConnection.get_close_code. * + * However, other codes are also allowed. */ /** @@ -146,7 +137,6 @@ * @SOUP_WEBSOCKET_STATE_CLOSED: the connection is completely closed down * * The state of the WebSocket connection. - * */ G_DEFINE_QUARK (soup-websocket-error-quark, soup_websocket_error) @@ -248,12 +238,13 @@ * * Adds the necessary headers to @msg to request a WebSocket * handshake including supported WebSocket extensions. + * * The message body and non-WebSocket-related headers are * not modified. * * This is a low-level function; if you use - * soup_session_websocket_connect_async() to create a WebSocket - * connection, it will call this for you. + * method@Session.websocket_connect_async to create a WebSocket connection, it + * will call this for you. */ void soup_websocket_client_prepare_handshake (SoupMessage *msg, @@ -545,9 +536,9 @@ * only requests containing valid supported extensions in * "Sec-WebSocket-Extensions" header will be accepted. * - * Normally soup_websocket_server_process_handshake() + * Normally func@websocket_server_process_handshake * will take care of this for you, and if you use - * soup_server_add_websocket_handler() to handle accepting WebSocket + * method@Server.add_websocket_handler to handle accepting WebSocket * connections, it will call that for you. However, this function may * be useful if you need to perform more complicated validation; eg, * accepting multiple different Origins, or handling different protocols @@ -687,7 +678,7 @@ * will be returned in @accepted_extensions parameter if non-%NULL. * * This is a low-level function; if you use - * soup_server_add_websocket_handler() to handle accepting WebSocket + * method@Server.add_websocket_handler to handle accepting WebSocket * connections, it will call this for you. * * Returns: %TRUE if @msg contained a valid WebSocket handshake @@ -802,7 +793,7 @@ * extensions are returned in @accepted_extensions parameter if non-%NULL. * * This is a low-level function; if you use - * soup_session_websocket_connect_async() to create a WebSocket + * method@Session.websocket_connect_async to create a WebSocket * connection, it will call this for you. * * Returns: %TRUE if @msg contains a completed valid WebSocket
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/libsoup/websocket/soup-websocket.h -> _service:tar_scm:libsoup-3.2.2.tar.xz/libsoup/websocket/soup-websocket.h
Changed
@@ -24,6 +24,12 @@ G_BEGIN_DECLS +/** + * soup_websocket_error_quark: + * Registers error quark for SoupWebsocket if needed. + * + * Returns: Error quark for SoupWebsocket. + */ #define SOUP_WEBSOCKET_ERROR (soup_websocket_error_quark ()) SOUP_AVAILABLE_IN_ALL GQuark soup_websocket_error_quark (void) G_GNUC_CONST;
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/meson.build -> _service:tar_scm:libsoup-3.2.2.tar.xz/meson.build
Changed
@@ -1,5 +1,5 @@ project('libsoup', 'c', - version: '3.0.6', + version: '3.2.2', meson_version : '>= 0.54', license : 'LGPL-2.0-or-later', default_options : @@ -11,23 +11,25 @@ soup_version = meson.project_version() -# Before making a release, the libversion string should be modified. -# -# * Bump the first component if binary compatibility has been broken; or -# * Bump the second component if new APIs are added; or -# * Bump the third component otherwise. -# -# When bumping the first component version, set the second and third components -# to 0. When bumping the second version, set the third one to zero. -libversion = '0.0.5' +# Before making a release, the soversion string should be modified. +# The string is of the form C, R, A. +# - If interfaces have been changed or added, but binary compatibility has +# been preserved, change to C+1, 0, A+1. +# - If binary compatibility has been broken (eg removed or changed interfaces) +# change to C+1, 0, 0 +# - If the interface is the same as the previous version, use C, R+1, A. +soup_version_info = 6, 0, 6 + +# Turn C, R, A into an actual usable *soversion*. +soup_soversion_major = soup_version_info0 - soup_version_info2 # Current-Age +soup_soversion_minor = soup_version_info2 # Age +soup_soversion_micro = soup_version_info1 # Revision +libversion = '@0@.@1@.@2@'.format(soup_soversion_major, soup_soversion_minor, soup_soversion_micro) + +darwin_versions = soup_soversion_major + soup_soversion_minor + 1, '@0@.@1@'.format(soup_soversion_major + soup_soversion_minor + 1, soup_soversion_micro) + apiversion = '3.0' -soversion = libversion.split('.')0 libsoup_api_name = '@0@-@1@'.format(meson.project_name(), apiversion) -libversion_arr = libversion.split('.') -darwin_version_major = libversion_arr0.to_int() -darwin_version_minor = libversion_arr1.to_int() -darwin_version_micro = libversion_arr2.to_int() -darwin_versions = darwin_version_major + darwin_version_minor + 1, '@0@.@1@'.format(darwin_version_major + darwin_version_minor + 1, darwin_version_micro) host_system = host_machine.system() @@ -108,7 +110,12 @@ glib_deps = glib_dep, gmodule_dep, gobject_dep, gio_dep +cdata = configuration_data() + libnghttp2_dep = dependency('libnghttp2') +if cc.has_function('nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation', prefix : '#include <nghttp2/nghttp2.h>', dependencies : libnghttp2_dep) + cdata.set('HAVE_NGHTTP2_OPTION_SET_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION', '1') +endif sqlite_dep = dependency('sqlite3', required: false) @@ -124,8 +131,6 @@ sqlite_dep = dependency('sqlite3') endif -cdata = configuration_data() - brotlidec_dep = dependency('libbrotlidec', required : get_option('brotli')) if brotlidec_dep.found() cdata.set('WITH_BROTLI', true) @@ -266,10 +271,11 @@ cdata.set('APACHE_MODULE_DIR', apache_modules_dirs0) message('Apache SSL module directory: ' + apache_modules_dirs1) cdata.set('APACHE_SSL_MODULE_DIR', apache_modules_dirs1) - message('Apache PHP module file: ' + apache_modules_dirs2) - cdata.set('APACHE_PHP_MODULE_FILE', apache_modules_dirs2) - message('Apache mod_unixd module directory: ' + (apache_modules_dirs3 != '' ? apache_modules_dirs3 : '(none)')) - cdata.set('IF_HAVE_MOD_UNIXD', apache_modules_dirs3 != '' ? '' : '#') + message('Apache mod_unixd module directory: ' + (apache_modules_dirs2 != '' ? apache_modules_dirs2 : '(none)')) + cdata.set('IF_HAVE_MOD_UNIXD', apache_modules_dirs2 != '' ? '' : '#') + message('Apache HTTP/2 module directory: ' + apache_modules_dirs3) + cdata.set('IF_HAVE_MOD_HTTP2', apache_modules_dirs3 != '' ? '' : '#') + cdata.set('APACHE_HTTP2_MODULE_DIR', apache_modules_dirs3) cdata.set('HAVE_APACHE', have_apache) else message('Failed to locate necessary Apache modules for full test coverage') @@ -284,27 +290,9 @@ have_autobahn = find_program('wstest', required: get_option('autobahn')).found() endif -# Quart server used for HTTP/2 tests -quart_found = false - -if not get_option('http2_tests').disabled() - pymod = import('python') - python = pymod.find_installation('python3') - if python.found() - ret = run_command(python, '-c', 'import importlib\nassert(importlib.find_loader("quart"))', check: false) - if ret.returncode() == 0 - quart_found = true - endif - endif - message('Python module quart found: @0@'.format(quart_found.to_string('YES', 'NO'))) - if get_option('http2_tests').enabled() and not quart_found - error('quart is required for http2 tests') - endif -endif - gnutls_dep = dependency('gnutls', version: '>= 3.6.0', required : get_option('pkcs11_tests')) -if not have_apache or not quart_found or not have_autobahn or not gnutls_dep.found() +if not have_apache or not have_autobahn or not gnutls_dep.found() warning('Some regression tests will not be compiled due to missing libraries or modules. Please check the logs for more details.') endif @@ -402,13 +390,11 @@ subdir('fuzzing') if get_option('tests') subdir('tests') - endif - -if get_option('gtk_doc') - srcdir = include_directories('libsoup') - subdir('docs/reference') endif +srcdir = include_directories('libsoup') +subdir('docs/reference') + summary({ 'prefix' : get_option('prefix'), 'libdir' : get_option('libdir'), @@ -424,7 +410,7 @@ 'Translations' : xgettext.found(), 'GIR' : enable_introspection, 'VAPI' : enable_vapi, - 'Documentation' : get_option('gtk_doc'), + 'Documentation' : have_docs, }, section : 'Features' ) @@ -432,7 +418,7 @@ summary({ 'All tests' : get_option('tests'), 'Tests requiring Apache' : have_apache, - 'Tests requiring Quart' : quart_found, + 'Documentation tests' : get_option('doc_tests'), 'Fuzzing tests' : get_option('fuzzing').enabled(), 'Autobahn tests' : have_autobahn, 'PKCS #11 tests' : gnutls_dep.found(),
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/meson_options.txt -> _service:tar_scm:libsoup-3.2.2.tar.xz/meson_options.txt
Changed
@@ -47,10 +47,16 @@ description : 'Build Vala bindings' ) -option('gtk_doc', +option('docs', + type: 'feature', + value: 'auto', + description: 'Enable generating the API reference' +) + +option('doc_tests', type: 'boolean', value: false, - description: 'Enable generating the API reference' + description: 'Enable strict validation of API docs' ) option('tests', @@ -83,12 +89,6 @@ description: 'enable fuzzing support' ) -option('http2_tests', - type: 'feature', - value: 'auto', - description: 'enable HTTP/2 tests depending on quart' -) - option('pkcs11_tests', type: 'feature', value: 'auto',
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/po/LINGUAS -> _service:tar_scm:libsoup-3.2.2.tar.xz/po/LINGUAS
Changed
@@ -30,6 +30,7 @@ id it ja +ka kn ko lt
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/po/POTFILES.in -> _service:tar_scm:libsoup-3.2.2.tar.xz/po/POTFILES.in
Changed
@@ -7,9 +7,10 @@ libsoup/http1/soup-message-io-data.c libsoup/http2/soup-body-input-stream-http2.c libsoup/http2/soup-client-message-io-http2.c +libsoup/server/http1/soup-server-message-io-http1.c +libsoup/server/http2/soup-server-message-io-http2.c +libsoup/server/soup-listener.c libsoup/server/soup-server.c -libsoup/server/soup-server-io.c -libsoup/server/soup-socket.c libsoup/soup-session.c libsoup/soup-tld.c libsoup/websocket/soup-websocket.c
View file
_service:tar_scm:libsoup-3.2.2.tar.xz/po/ka.po
Added
@@ -0,0 +1,193 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: libsoup\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/libsoup/issues\n" +"POT-Creation-Date: 2022-06-02 11:25+0000\n" +"PO-Revision-Date: 2022-06-06 16:49+0200\n" +"Last-Translator: Temuri Doghonadze <temuri.doghonadze@gmail.com>\n" +"Language-Team: Georgian <(nothing)>\n" +"Language: ka\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 3.0.1\n" + +#: libsoup/cache/soup-cache-input-stream.c:70 +msgid "Network stream unexpectedly closed" +msgstr "ქსელური ნაკადი მოულოდნელად დაიხურა" + +#: libsoup/cache/soup-cache-input-stream.c:252 +msgid "Failed to completely cache the resource" +msgstr "რესურსის მთლიანად დაქეშვა შეუძლებელია" + +#: libsoup/content-decoder/soup-converter-wrapper.c:197 +#, c-format +msgid "Output buffer is too small" +msgstr "გამოტანის ბუფერი მეტისმეტად პატარაა" + +#: libsoup/http1/soup-body-input-stream.c:155 +#: libsoup/http1/soup-body-input-stream.c:187 +#: libsoup/http1/soup-body-input-stream.c:220 +#: libsoup/http1/soup-message-io-data.c:77 +msgid "Connection terminated unexpectedly" +msgstr "შეერთება მოულოდნელად დაიხურა" + +#: libsoup/http1/soup-body-input-stream.c:471 +msgid "Invalid seek request" +msgstr "გადახვევის არასწორი მოთხოვნა" + +#: libsoup/http1/soup-body-input-stream.c:499 +msgid "Cannot truncate SoupBodyInputStream" +msgstr "SoupBodyInputStream-ის წაკვეთის შეცდომა" + +#: libsoup/http1/soup-client-message-io-http1.c:312 +#: libsoup/http1/soup-client-message-io-http1.c:756 +#: libsoup/http2/soup-body-input-stream-http2.c:221 +#: libsoup/server/soup-server-io.c:363 libsoup/server/soup-server-io.c:828 +msgid "Operation would block" +msgstr "ოპერაცია დაიბლოკებოდა" + +#: libsoup/http1/soup-client-message-io-http1.c:456 +msgid "Could not parse HTTP response" +msgstr "HTTP პასუხის დამუშავების შეცდომა" + +#: libsoup/http1/soup-client-message-io-http1.c:479 +msgid "Unrecognized HTTP response encoding" +msgstr "HTTP პასუხის უცნობი კოდირება" + +#: libsoup/http1/soup-client-message-io-http1.c:715 +#: libsoup/http1/soup-client-message-io-http1.c:741 +#: libsoup/http2/soup-client-message-io-http2.c:1606 +#: libsoup/http2/soup-client-message-io-http2.c:1630 +msgid "Operation was cancelled" +msgstr "ოპერაცია გაუქმდა" + +#: libsoup/http1/soup-message-io-data.c:105 +msgid "Header too big" +msgstr "თავსართი ძალიან დიდია" + +#: libsoup/server/soup-server.c:1203 +msgid "Can’t create a TLS server without a TLS certificate" +msgstr "TLS სერვერის შექმნა შეუძლებელია TLS სერტიფიკატის გარეშე" + +#: libsoup/server/soup-server.c:1225 +#, c-format +msgid "Could not listen on address %s, port %d: " +msgstr "მისამართზე: %s, პორტზე %d მოსმენა შეუძლებელია: " + +#: libsoup/server/soup-socket.c:123 +msgid "Could not import existing socket: " +msgstr "არსებული სოკეტის შემოტანა შეუძლებელია: " + +#: libsoup/server/soup-socket.c:132 +msgid "Can’t import unconnected socket" +msgstr "დაუკავშირებელი სოკეტის შემოტანა შეუძლებელია" + +#: libsoup/soup-session.c:1180 +msgid "Location header is missing or empty in response headers" +msgstr "პასუხის თავსართებში თავსართი \"Location\" არ არსებობს ან ცარიელია" + +#: libsoup/soup-session.c:1194 +#, c-format +msgid "Invalid URI “%s” in Location response header" +msgstr "\"Location\" თავსართის არასწორი URI: \"%s\"" + +#: libsoup/soup-session.c:1214 +msgid "Too many redirects" +msgstr "მეტისმეტად ბევრი გადამისამართება" + +#: libsoup/soup-session.c:1219 +msgid "Message was restarted too many times" +msgstr "შეტყობინება მეტისმეტად ბევრჯერ გაეშვა" + +#: libsoup/soup-session.c:3310 libsoup/soup-session.c:3458 +msgid "Message is already in session queue" +msgstr "შეტყობინება უკვე სესიის რიგშია" + +#: libsoup/soup-session.c:3821 +msgid "The server did not accept the WebSocket handshake." +msgstr "სერვერი WebSocket-ის ტიპის კავშირს არ დაეთანხმა." + +#: libsoup/soup-tld.c:129 +msgid "No public-suffix list available." +msgstr "Public-suffix სია მიუწვდომელია." + +#: libsoup/soup-tld.c:139 libsoup/soup-tld.c:155 +msgid "Invalid hostname" +msgstr "ჰოსტის არასწორი სახელი" + +#: libsoup/soup-tld.c:146 +msgid "Hostname is an IP address" +msgstr "ჰოსის სახელი IP მისამართს წარმოადგენს" + +#: libsoup/soup-tld.c:167 +msgid "Hostname has no base domain" +msgstr "ჰოსტის სახელს ბაზისური დომენი არ გააჩნია" + +#: libsoup/soup-tld.c:175 +msgid "Not enough domains" +msgstr "არასაკმარისი დომენები" + +#: libsoup/websocket/soup-websocket.c:390 +#: libsoup/websocket/soup-websocket.c:434 +#: libsoup/websocket/soup-websocket.c:450 +msgid "Server requested unsupported extension" +msgstr "სერვერმა მხარდაუჭერელი გაფართოება მოითხოვა" + +#: libsoup/websocket/soup-websocket.c:413 +#: libsoup/websocket/soup-websocket.c:605 +#, c-format +msgid "Incorrect WebSocket “%s” header" +msgstr "WebSocket-ის არასწორი თავსართი: \"%s\"" + +#: libsoup/websocket/soup-websocket.c:414 +#: libsoup/websocket/soup-websocket.c:869 +#, c-format +msgid "Server returned incorrect “%s” key" +msgstr "სერვერმა არასწორი გასაღებს დააბრუნა: \"%s\"" + +#: libsoup/websocket/soup-websocket.c:477 +#, c-format +msgid "Duplicated parameter in “%s” WebSocket extension header" +msgstr "დუბლრებული პარამეტრი WebSocket-ის გაფართოების თავსართში: \"%s\"" + +#: libsoup/websocket/soup-websocket.c:478 +#, c-format +msgid "Server returned a duplicated parameter in “%s” WebSocket extension header" +msgstr "სერვერმა დააბრუნა დუბლრებული პარამეტრი WebSocket-ის გაფართოების თავსართში: \"%s\"" + +#: libsoup/websocket/soup-websocket.c:568 +#: libsoup/websocket/soup-websocket.c:578 +msgid "WebSocket handshake expected" +msgstr "მოსალოდნელი იყო WebSocket-ის ტიპის შეერთება" + +#: libsoup/websocket/soup-websocket.c:586 +msgid "Unsupported WebSocket version" +msgstr "WebSocket-ის მხარდაუჭერელი ვერსია" + +#: libsoup/websocket/soup-websocket.c:595 +msgid "Invalid WebSocket key" +msgstr "WebSocket-ის არასწორი გასაღები" + +#: libsoup/websocket/soup-websocket.c:614 +msgid "Unsupported WebSocket subprotocol" +msgstr "WebSocket-ის მხარდაუჭერელი ქვეპროტოკოლი" + +#: libsoup/websocket/soup-websocket.c:820 +msgid "Server rejected WebSocket handshake" +msgstr "სერვერმა უარჰყო WebSocket-ის ტიპის შეერთება" + +#: libsoup/websocket/soup-websocket.c:828 +#: libsoup/websocket/soup-websocket.c:837 +msgid "Server ignored WebSocket handshake" +msgstr "სერვერმა დააიგნორა WebSocket-ის ტიპის შეერთება" + +#: libsoup/websocket/soup-websocket.c:849 +msgid "Server requested unsupported protocol" +msgstr "სერვერმა მხარდაუჭერელი პროტოკოლი მოითხოვა"
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/po/sk.po -> _service:tar_scm:libsoup-3.2.2.tar.xz/po/sk.po
Changed
@@ -7,8 +7,8 @@ msgstr "" "Project-Id-Version: libsoup\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/libsoup/issues\n" -"POT-Creation-Date: 2020-06-26 17:08+0000\n" -"PO-Revision-Date: 2020-09-06 17:36+0200\n" +"POT-Creation-Date: 2021-06-11 18:40+0000\n" +"PO-Revision-Date: 2022-04-01 14:04+0200\n" "Last-Translator: Dušan Kazik <prescott66@gmail.com>\n" "Language-Team: Slovak <gnome-sk-list@gnome.org>\n" "Language: sk\n" @@ -16,195 +16,218 @@ "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 1 : (n>=2 && n<=4) ? 2 : 0;\n" -"X-Generator: Poedit 2.4.1\n" +"X-Generator: Poedit 3.0.1\n" -#: libsoup/soup-body-input-stream.c:139 libsoup/soup-body-input-stream.c:170 -#: libsoup/soup-body-input-stream.c:203 libsoup/soup-message-io.c:236 -msgid "Connection terminated unexpectedly" -msgstr "Pripojenie bolo neočakávane ukončené" - -#: libsoup/soup-body-input-stream.c:459 -msgid "Invalid seek request" -msgstr "Neplatná požiadavka na posunutie" - -# struct -#: libsoup/soup-body-input-stream.c:487 -msgid "Cannot truncate SoupBodyInputStream" -msgstr "SoupBodyInputStream sa nedá skrátiť" - -#: libsoup/soup-cache-input-stream.c:76 +#: libsoup/cache/soup-cache-input-stream.c:70 msgid "Network stream unexpectedly closed" msgstr "Sieťový prúd bol neočakávane uzavretý" -#: libsoup/soup-cache-input-stream.c:291 +#: libsoup/cache/soup-cache-input-stream.c:252 msgid "Failed to completely cache the resource" msgstr "Úplné načítanie zdroja do dočasnej pamäte zlyhalo" -#: libsoup/soup-directory-input-stream.c:231 -msgid "Name" -msgstr "Názov" - -#: libsoup/soup-directory-input-stream.c:232 -msgid "Size" -msgstr "Veľkosť" - -#: libsoup/soup-directory-input-stream.c:233 -msgid "Date Modified" -msgstr "Dátum zmeny" - # PM: buffer by som preložil ako schránka # PK: schranka je clipboard, buffer je jednoznacne vyrovnavacia pamet -#: libsoup/soup-converter-wrapper.c:189 +#: libsoup/content-decoder/soup-converter-wrapper.c:197 #, c-format msgid "Output buffer is too small" msgstr "Výstupná vyrovnávacia pamäť je príliš malá" -#: libsoup/soup-message-client-io.c:39 -msgid "Could not parse HTTP response" -msgstr "Nepodarilo sa analyzovať odpoveď HTTP" +#: libsoup/http1/soup-body-input-stream.c:155 +#: libsoup/http1/soup-body-input-stream.c:187 +#: libsoup/http1/soup-body-input-stream.c:220 +#: libsoup/http1/soup-message-io-data.c:77 +msgid "Connection terminated unexpectedly" +msgstr "Pripojenie bolo neočakávane ukončené" -#: libsoup/soup-message-client-io.c:62 -msgid "Unrecognized HTTP response encoding" -msgstr "Nerozpoznané kódovanie odpovede HTTP" +#: libsoup/http1/soup-body-input-stream.c:471 +msgid "Invalid seek request" +msgstr "Neplatná požiadavka na posunutie" -#: libsoup/soup-message-io.c:261 -msgid "Header too big" -msgstr "Záhlavie je príliš veľké" +# struct +#: libsoup/http1/soup-body-input-stream.c:499 +msgid "Cannot truncate SoupBodyInputStream" +msgstr "SoupBodyInputStream sa nedá skrátiť" # PK: tu neviem ako to povedat, malo by ist o to, ze proste ta operacia neni async -#: libsoup/soup-message-io.c:393 libsoup/soup-message-io.c:1016 +#: libsoup/http1/soup-client-message-io-http1.c:312 +#: libsoup/http1/soup-client-message-io-http1.c:756 +#: libsoup/http2/soup-body-input-stream-http2.c:221 +#: libsoup/server/soup-server-io.c:354 libsoup/server/soup-server-io.c:819 msgid "Operation would block" msgstr "Operácia by blokovala spracovanie" -#: libsoup/soup-message-io.c:968 libsoup/soup-message-io.c:1001 -msgid "Operation was cancelled" -msgstr "Operácia bola zrušená" +#: libsoup/http1/soup-client-message-io-http1.c:456 +msgid "Could not parse HTTP response" +msgstr "Nepodarilo sa analyzovať odpoveď HTTP" -#: libsoup/soup-message-server-io.c:63 -msgid "Could not parse HTTP request" -msgstr "Nepodarilo sa analyzovať požiadavku HTTP" +#: libsoup/http1/soup-client-message-io-http1.c:479 +msgid "Unrecognized HTTP response encoding" +msgstr "Nerozpoznané kódovanie odpovede HTTP" -# error -#: libsoup/soup-request.c:141 -#, c-format -msgid "No URI provided" -msgstr "Nebol poskytnutý identifikátor URI" +#: libsoup/http1/soup-client-message-io-http1.c:715 +#: libsoup/http1/soup-client-message-io-http1.c:741 +#: libsoup/http2/soup-client-message-io-http2.c:1426 +#: libsoup/http2/soup-client-message-io-http2.c:1450 +msgid "Operation was cancelled" +msgstr "Operácia bola zrušená" -# first %s - scheme (http, ftp, ...) -#: libsoup/soup-request.c:151 -#, c-format -msgid "Invalid “%s” URI: %s" -msgstr "Neplatná schéma „%s“ identifikátora URI: %s" +#: libsoup/http1/soup-message-io-data.c:105 +msgid "Header too big" +msgstr "Záhlavie je príliš veľké" -#: libsoup/soup-server.c:1810 +#: libsoup/server/soup-server.c:1072 msgid "Can’t create a TLS server without a TLS certificate" msgstr "Nedá sa vytvoriť TLS server bez TLS certifikátu" -#: libsoup/soup-server.c:1827 +#: libsoup/server/soup-server.c:1088 #, c-format msgid "Could not listen on address %s, port %d: " msgstr "Nepodarilo sa počúvať na adrese %s, porte %d: " -#: libsoup/soup-session.c:4570 -#, c-format -msgid "Could not parse URI “%s”" -msgstr "Nepodarilo sa analyzovať identifikátor URI „%s“" +#: libsoup/server/soup-socket.c:116 +msgid "Could not import existing socket: " +msgstr "Nepodarilo sa importovať existujúci soket: " -#: libsoup/soup-session.c:4607 -#, c-format -msgid "Unsupported URI scheme “%s”" -msgstr "Nepodporovaná schéma „%s“ pre identifikátor URI" +#: libsoup/server/soup-socket.c:125 +msgid "Can’t import unconnected socket" +msgstr "Nedá sa importovať nepripojený soket" + +#: libsoup/soup-session.c:1166 +msgid "Location header is missing or empty in response headers" +msgstr "" +"Hlavička s umiestnením chýba alebo je prázdna v hlavičkách s odpoveďami" -#: libsoup/soup-session.c:4629 +#: libsoup/soup-session.c:1180 #, c-format -msgid "Not an HTTP URI" -msgstr "Nie je HTTP URI" +msgid "Invalid URI “%s” in Location response header" +msgstr "Neplatný URI „%s“ v hlavičke odpovede s umiestnením" + +#: libsoup/soup-session.c:1200 +msgid "Too many redirects" +msgstr "Príliš veľa presmerovaní" + +#: libsoup/soup-session.c:1205 +msgid "Message was restarted too many times" +msgstr "Správa bola reštartovaná príliš veľakrát" -#: libsoup/soup-session.c:4840 +#: libsoup/soup-session.c:3315 libsoup/soup-session.c:3464 +msgid "Message is already in session queue" +msgstr "Správa už je vo fronte relácie" + +#: libsoup/soup-session.c:3825 msgid "The server did not accept the WebSocket handshake." msgstr "Server neprijal vyjednanie protokolu WebSocket." -#: libsoup/soup-socket.c:148 -msgid "Can’t import non-socket as SoupSocket" -msgstr "Nedá sa importovať ne-soket ako SoupSocket" +#: libsoup/soup-tld.c:142 +msgid "No public-suffix list available." +msgstr "Nie je dostupný žiadny zoznam verejných prípon." -#: libsoup/soup-socket.c:166 -msgid "Could not import existing socket: " -msgstr "Nepodarilo sa importovať existujúci soket: " +#: libsoup/soup-tld.c:152 libsoup/soup-tld.c:168 +msgid "Invalid hostname"
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/po/tr.po -> _service:tar_scm:libsoup-3.2.2.tar.xz/po/tr.po
Changed
@@ -1,5 +1,5 @@ # Turkish translation for libsoup. -# Copyright (C) 2012-2019 libsoup's COPYRIGHT HOLDER +# Copyright (C) 2012-2022 libsoup's COPYRIGHT HOLDER # This file is distributed under the same license as the libsoup package. # # Ozan Çağlayan <ozancag@gmail.com>, 2013. @@ -13,7 +13,7 @@ msgstr "" "Project-Id-Version: libsoup master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/libsoup/issues\n" -"POT-Creation-Date: 2021-08-09 09:48+0000\n" +"POT-Creation-Date: 2022-08-13 12:28+0000\n" "PO-Revision-Date: 2021-09-09 22:15+0300\n" "Last-Translator: Emin Tufan Çetin <etcetin@gmail.com>\n" "Language-Team: Türkçe <gnome-turk@gnome.org>\n" @@ -53,25 +53,26 @@ msgid "Cannot truncate SoupBodyInputStream" msgstr "SoupBodyInputStream kesilemiyor" -#: libsoup/http1/soup-client-message-io-http1.c:312 -#: libsoup/http1/soup-client-message-io-http1.c:756 +#: libsoup/http1/soup-client-message-io-http1.c:321 +#: libsoup/http1/soup-client-message-io-http1.c:762 #: libsoup/http2/soup-body-input-stream-http2.c:221 -#: libsoup/server/soup-server-io.c:363 libsoup/server/soup-server-io.c:828 +#: libsoup/server/http1/soup-server-message-io-http1.c:416 +#: libsoup/server/http1/soup-server-message-io-http1.c:889 msgid "Operation would block" msgstr "İşlem engellenebilir" -#: libsoup/http1/soup-client-message-io-http1.c:456 +#: libsoup/http1/soup-client-message-io-http1.c:462 msgid "Could not parse HTTP response" msgstr "HTTP yanıtı ayrıştırılamadı" -#: libsoup/http1/soup-client-message-io-http1.c:479 +#: libsoup/http1/soup-client-message-io-http1.c:485 msgid "Unrecognized HTTP response encoding" msgstr "HTTP yanıtı tanınmayan biçimde kodlanmış" -#: libsoup/http1/soup-client-message-io-http1.c:715 -#: libsoup/http1/soup-client-message-io-http1.c:741 -#: libsoup/http2/soup-client-message-io-http2.c:1456 -#: libsoup/http2/soup-client-message-io-http2.c:1480 +#: libsoup/http1/soup-client-message-io-http1.c:721 +#: libsoup/http1/soup-client-message-io-http1.c:747 +#: libsoup/http2/soup-client-message-io-http2.c:1544 +#: libsoup/http2/soup-client-message-io-http2.c:1568 msgid "Operation was cancelled" msgstr "İşlem iptal edildi" @@ -79,152 +80,118 @@ msgid "Header too big" msgstr "Başlık çok büyük" -#: libsoup/server/soup-server.c:1201 -msgid "Can’t create a TLS server without a TLS certificate" -msgstr "TLS sertifikası olmadan TLS sunucusu oluşturulamaz" - -#: libsoup/server/soup-server.c:1223 -#, c-format -msgid "Could not listen on address %s, port %d: " -msgstr "%s adresinin %d bağlantı noktası dinlenemedi: " - -#: libsoup/server/soup-socket.c:121 +#: libsoup/server/soup-listener.c:261 msgid "Could not import existing socket: " msgstr "Var olan yuva içe aktarılamadı: " -#: libsoup/server/soup-socket.c:130 +#: libsoup/server/soup-listener.c:267 msgid "Can’t import unconnected socket" msgstr "Bağlı olmayan yuva içe aktarılamıyor" -#: libsoup/soup-session.c:1166 +#: libsoup/server/soup-server.c:1209 +msgid "Can’t create a TLS server without a TLS certificate" +msgstr "TLS sertifikası olmadan TLS sunucusu oluşturulamaz" + +#: libsoup/soup-session.c:1116 msgid "Location header is missing or empty in response headers" msgstr "Konum başlığı eksik veya yanıt başlıklarında boş" -#: libsoup/soup-session.c:1180 +#: libsoup/soup-session.c:1130 #, c-format msgid "Invalid URI “%s” in Location response header" msgstr "Konum yanıt başlığında geçersiz URI “%s”" -#: libsoup/soup-session.c:1200 +#: libsoup/soup-session.c:1150 msgid "Too many redirects" msgstr "Çok sayıda yönlendirme" -#: libsoup/soup-session.c:1205 +#: libsoup/soup-session.c:1155 msgid "Message was restarted too many times" msgstr "İleti birçok kez yeniden başladı" -#: libsoup/soup-session.c:3317 libsoup/soup-session.c:3466 +#: libsoup/soup-session.c:3011 libsoup/soup-session.c:3159 msgid "Message is already in session queue" msgstr "İleti zaten oturum sırasında" -#: libsoup/soup-session.c:3827 +#: libsoup/soup-session.c:3491 msgid "The server did not accept the WebSocket handshake." msgstr "Sunucu, WebSocket el sıkışmasını kabul etmedi." -#: libsoup/soup-tld.c:142 +#: libsoup/soup-tld.c:129 msgid "No public-suffix list available." msgstr "Uygun halka açık son ek listesi yok." -#: libsoup/soup-tld.c:152 libsoup/soup-tld.c:168 +#: libsoup/soup-tld.c:139 libsoup/soup-tld.c:155 msgid "Invalid hostname" msgstr "Geçersiz makine adı" -#: libsoup/soup-tld.c:159 +#: libsoup/soup-tld.c:146 msgid "Hostname is an IP address" msgstr "Makine adı bir IP adresi" -#: libsoup/soup-tld.c:180 +#: libsoup/soup-tld.c:167 msgid "Hostname has no base domain" msgstr "Ana makinenin temel etki alanı yok" -#: libsoup/soup-tld.c:188 +#: libsoup/soup-tld.c:175 msgid "Not enough domains" msgstr "Yeterli etki alanı yok" -#: libsoup/websocket/soup-websocket.c:399 -#: libsoup/websocket/soup-websocket.c:443 -#: libsoup/websocket/soup-websocket.c:459 +#: libsoup/websocket/soup-websocket.c:390 +#: libsoup/websocket/soup-websocket.c:434 +#: libsoup/websocket/soup-websocket.c:450 msgid "Server requested unsupported extension" msgstr "Sunucu, desteklenmeyen eklenti isteğinde bulundu" -#: libsoup/websocket/soup-websocket.c:422 -#: libsoup/websocket/soup-websocket.c:614 +#: libsoup/websocket/soup-websocket.c:413 +#: libsoup/websocket/soup-websocket.c:605 #, c-format msgid "Incorrect WebSocket “%s” header" msgstr "Hatalı WebSocket “%s” başlığı" -#: libsoup/websocket/soup-websocket.c:423 -#: libsoup/websocket/soup-websocket.c:878 +#: libsoup/websocket/soup-websocket.c:414 +#: libsoup/websocket/soup-websocket.c:869 #, c-format msgid "Server returned incorrect “%s” key" msgstr "Sunucu, geçersiz “%s” anahtarı döndürdü" -#: libsoup/websocket/soup-websocket.c:486 +#: libsoup/websocket/soup-websocket.c:477 #, c-format msgid "Duplicated parameter in “%s” WebSocket extension header" msgstr "“%s” WebSocket eklenti başlığında yinelenen parametre" -#: libsoup/websocket/soup-websocket.c:487 +#: libsoup/websocket/soup-websocket.c:478 #, c-format -msgid "Server returned a duplicated parameter in “%s” WebSocket extension header" +msgid "" +"Server returned a duplicated parameter in “%s” WebSocket extension header" msgstr "Sunucu, “%s” WebSocket eklenti başlığında yinelenen parametre döndürdü" -#: libsoup/websocket/soup-websocket.c:577 -#: libsoup/websocket/soup-websocket.c:587 +#: libsoup/websocket/soup-websocket.c:568 +#: libsoup/websocket/soup-websocket.c:578 msgid "WebSocket handshake expected" msgstr "WebSocket el sıkışması bekleniyor" -#: libsoup/websocket/soup-websocket.c:595 +#: libsoup/websocket/soup-websocket.c:586 msgid "Unsupported WebSocket version" msgstr "Desteklenmeyen WebSocket sürümü" -#: libsoup/websocket/soup-websocket.c:604 +#: libsoup/websocket/soup-websocket.c:595 msgid "Invalid WebSocket key" msgstr "Geçersiz WebSocket anahtarı" -#: libsoup/websocket/soup-websocket.c:623 +#: libsoup/websocket/soup-websocket.c:614 msgid "Unsupported WebSocket subprotocol" msgstr "Desteklenmeyen WebSocket alt iletişim kuralı" -#: libsoup/websocket/soup-websocket.c:829 +#: libsoup/websocket/soup-websocket.c:820 msgid "Server rejected WebSocket handshake" msgstr "Sunucu, WebSocket el sıkışmasını reddetti"
View file
_service:tar_scm:libsoup-3.2.2.tar.xz/subprojects/gi-docgen.wrap
Added
@@ -0,0 +1,6 @@ +wrap-git +directory=gi-docgen +url=https://gitlab.gnome.org/GNOME/gi-docgen.git +push-url=ssh://git@gitlab.gnome.org:GNOME/gi-docgen.git +revision=main +depth=1
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/tests/auth-test.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/tests/auth-test.c
Changed
@@ -803,6 +803,42 @@ soup_test_session_abort_unref (session); } +static gboolean +sync_bad_password_authenticate (SoupMessage *msg, + SoupAuth *auth, + gboolean retrying) +{ + if (retrying) + return FALSE; + + soup_auth_authenticate (auth, "user1", "wrong"); + return TRUE; +} + +static void +do_sync_auth_bad_password_test (void) +{ + SoupSession *session; + SoupMessage *msg; + char *uri; + + SOUP_TEST_SKIP_IF_NO_APACHE; + + session = soup_test_session_new (NULL); + uri = g_strconcat (base_uri, "Basic/realm1/", NULL); + + msg = soup_message_new ("GET", uri); + g_free (uri); + g_signal_connect (msg, "authenticate", + G_CALLBACK (sync_bad_password_authenticate), + NULL); + soup_test_session_send_message (session, msg); + soup_test_assert_message_status (msg, SOUP_STATUS_UNAUTHORIZED); + g_object_unref (msg); + + soup_test_session_abort_unref (session); +} + typedef struct { const char *password; struct { @@ -1849,6 +1885,7 @@ g_test_add_func ("/auth/async-auth/bad-password", do_async_auth_bad_password_test); g_test_add_func ("/auth/async-auth/no-password", do_async_auth_no_password_test); g_test_add_func ("/auth/async-auth/cancel", do_async_auth_cancel_test); + g_test_add_func ("/auth/sync-auth/bad-password", do_sync_auth_bad_password_test); g_test_add_func ("/auth/select-auth", do_select_auth_test); g_test_add_func ("/auth/auth-close", do_auth_close_test); g_test_add_func ("/auth/infinite-auth", do_infinite_auth_test);
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/tests/cache-test.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/tests/cache-test.c
Changed
@@ -4,6 +4,7 @@ */ #include "test-utils.h" +#include <glib/gstdio.h> static void server_callback (SoupServer *server, @@ -861,6 +862,239 @@ g_free (cache_dir); } +typedef struct { + SoupSession *session; + GUri *uri; + gboolean must_revalidate; + gboolean is_expired; + gboolean hit_network; + gboolean validated; + GError *error; +} ThreadTestRequest; + +static void +threads_message_starting (SoupMessage *msg, + ThreadTestRequest *request) +{ + SoupMessageHeaders *request_headers; + + if (request->validated) + return; + + request_headers = soup_message_get_request_headers (msg); + request->validated = !!soup_message_headers_get_one (request_headers, "If-Modified-Since"); +} + +static void +threads_request_queued (SoupSession *session, + SoupMessage *msg, + ThreadTestRequest *request) +{ + if (soup_message_get_uri (msg) != request->uri) + return; + + g_signal_connect (msg, "starting", + G_CALLBACK (threads_message_starting), + request); +} + +static void +task_async_function (GTask *task, + GObject *source, + gpointer task_data, + GCancellable *cancellable) +{ + GMainContext *context; + SoupMessage *msg; + SoupMessageHeaders *request_headers; + GInputStream *stream; + ThreadTestRequest *request = (ThreadTestRequest *)task_data; + + context = g_main_context_new (); + g_main_context_push_thread_default (context); + + msg = soup_message_new_from_uri ("GET", request->uri); + g_signal_connect (request->session, "request-queued", + G_CALLBACK (threads_request_queued), + request); + request_headers = soup_message_get_request_headers (msg); + if (request->must_revalidate) { + soup_message_headers_append (request_headers, + "Test-Set-Last-Modified", + request->is_expired ? "Sat, 02 Jan 2010 00:00:00 GMT" : "Fri, 01 Jan 2010 00:00:00 GMT"); + soup_message_headers_append (request_headers, + "Test-Set-Expires", "Sat, 02 Jan 2011 00:00:00 GMT"); + soup_message_headers_append (request_headers, + "Test-Set-Cache-Control", "must-revalidate"); + } else { + soup_message_headers_append (request_headers, + "Test-Set-Expires", "Fri, 01 Jan 2100 00:00:00 GMT"); + } + + stream = soup_test_request_send (request->session, msg, NULL, 0, &request->error); + if (stream) { + request->hit_network = is_network_stream (stream); + soup_test_request_read_all (stream, NULL, &request->error); + g_object_unref (stream); + } + + g_signal_handlers_disconnect_by_data (request->session, request); + + g_object_unref (msg); + + /* Continue iterating to ensure the item is unqueued and the connection released */ + while (g_main_context_pending (context)) + g_main_context_iteration (context, TRUE); + + /* Cache writes are G_PRIORITY_LOW, so they won't have happened yet */ + soup_cache_flush ((SoupCache *)soup_session_get_feature (request->session, SOUP_TYPE_CACHE)); + + g_task_return_boolean (task, TRUE); + + g_main_context_pop_thread_default (context); + g_main_context_unref (context); +} + +static void +task_finished_cb (SoupSession *session, + GAsyncResult *result, + guint *finished_count) +{ + g_assert_true (g_task_propagate_boolean (G_TASK (result), NULL)); + g_atomic_int_inc (finished_count); +} + +static void +do_threads_test (gconstpointer data) +{ + GUri *base_uri = (GUri *)data; + SoupSession *session; + SoupCache *cache; + char *cache_dir; + ThreadTestRequest requests4; + guint i; + guint finished_count = 0; + + session = soup_test_session_new (NULL); + + cache_dir = g_dir_make_tmp ("cache-test-XXXXXX", NULL); + cache = soup_cache_new (cache_dir, SOUP_CACHE_SINGLE_USER); + soup_session_add_feature (session, SOUP_SESSION_FEATURE (cache)); + + requests0.session = session; + requests0.uri = g_uri_parse_relative (base_uri, "/1", SOUP_HTTP_URI_FLAGS, NULL); + requests0.must_revalidate = FALSE; + requests0.is_expired = FALSE; + requests1.session = session; + requests1.uri = g_uri_parse_relative (base_uri, "/2", SOUP_HTTP_URI_FLAGS, NULL); + requests1.must_revalidate = TRUE; + requests1.is_expired = FALSE; + requests2.session = session; + requests2.uri = g_uri_parse_relative (base_uri, "/3", SOUP_HTTP_URI_FLAGS, NULL); + requests2.must_revalidate = FALSE; + requests2.is_expired = FALSE; + requests3.session = session; + requests3.uri = g_uri_parse_relative (base_uri, "/4", SOUP_HTTP_URI_FLAGS, NULL); + requests3.must_revalidate = TRUE; + requests3.is_expired = FALSE; + + for (i = 0; i < 4; i++) { + GTask *task; + + requestsi.hit_network = FALSE; + requestsi.validated = FALSE; + requestsi.error = NULL; + + task = g_task_new (NULL, NULL, (GAsyncReadyCallback)task_finished_cb, &finished_count); + g_task_set_task_data (task, &requestsi, NULL); + g_task_run_in_thread (task, (GTaskThreadFunc)task_async_function); + g_object_unref (task); + } + + while (g_atomic_int_get (&finished_count) != 4) + g_main_context_iteration (NULL, TRUE); + + /* Initial requests hit the network */ + for (i = 0; i < 4; i++) { + g_assert_true (requestsi.hit_network); + g_assert_false (requestsi.validated); + g_assert_no_error (requestsi.error); + } + + finished_count = 0; + for (i = 0; i < 4; i++) { + GTask *task; + + requestsi.hit_network = FALSE; + requestsi.validated = FALSE; + requestsi.error = NULL; + + task = g_task_new (NULL, NULL, (GAsyncReadyCallback)task_finished_cb, &finished_count); + g_task_set_task_data (task, &requestsi, NULL); + g_task_run_in_thread (task, (GTaskThreadFunc)task_async_function); + g_object_unref (task); + } + + while (g_atomic_int_get (&finished_count) != 4) + g_main_context_iteration (NULL, TRUE); + + /* None of the requests hit the ntwork */ + for (i = 0; i < 4; i++) { + g_assert_false (requestsi.hit_network); + g_assert_no_error (requestsi.error); + } + + /* The ones including must-revalidate are validated */ + g_assert_false (requests0.validated); + g_assert_true (requests1.validated); + g_assert_false (requests2.validated); + g_assert_true (requests3.validated); +
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/tests/connection-test.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/tests/connection-test.c
Changed
@@ -6,13 +6,14 @@ #include "test-utils.h" #include "soup-connection.h" -#include "soup-socket.h" +#include "soup-server-connection.h" #include "soup-server-message-private.h" #include <gio/gnetworking.h> static SoupServer *server; static GUri *base_uri; +static GUri *base_https_uri; static GMutex server_mutex; static void @@ -24,17 +25,17 @@ } static void -close_socket (SoupServerMessage *msg, - SoupSocket *sock) +close_socket (SoupServerMessage *msg, + SoupServerConnection *conn) { - GSocket *gsocket; + GSocket *socket; int sockfd; /* Actually calling soup_socket_disconnect() here would cause * us to leak memory, so just shutdown the socket instead. */ - gsocket = soup_socket_get_gsocket (sock); - sockfd = g_socket_get_fd (gsocket); + socket = soup_server_connection_get_socket (conn); + sockfd = g_socket_get_fd (socket); #ifdef G_OS_WIN32 shutdown (sockfd, SD_SEND); #else @@ -50,41 +51,39 @@ } static gboolean -timeout_socket (GObject *pollable, - SoupSocket *sock) +timeout_socket (GObject *pollable, + SoupServerConnection *conn) { - soup_socket_disconnect (sock); + soup_server_connection_disconnect (conn); return FALSE; } static void -timeout_request_started (SoupServer *server, - SoupServerMessage *msg, - gpointer user_data) +timeout_request_finished (SoupServer *server, + SoupServerMessage *msg, + gpointer user_data) { - SoupSocket *sock; - GMainContext *context = g_main_context_get_thread_default (); + SoupServerConnection *conn; GIOStream *iostream; GInputStream *istream; GSource *source; - g_signal_handlers_disconnect_by_func (server, timeout_request_started, NULL); + g_signal_handlers_disconnect_by_func (server, timeout_request_finished, NULL); - sock = soup_server_message_get_soup_socket (msg); - iostream = soup_socket_get_iostream (sock); + conn = soup_server_message_get_connection (msg); + iostream = soup_server_connection_get_iostream (conn); istream = g_io_stream_get_input_stream (iostream); source = g_pollable_input_stream_create_source (G_POLLABLE_INPUT_STREAM (istream), NULL); - g_source_set_callback (source, (GSourceFunc)timeout_socket, sock, NULL); + g_source_set_callback (source, (GSourceFunc)timeout_socket, conn, NULL); g_source_attach (source, g_main_context_get_thread_default ()); g_source_unref (source); g_mutex_unlock (&server_mutex); - while (soup_socket_is_connected (sock)) - g_main_context_iteration (context, TRUE); } static void -setup_timeout_persistent (SoupServer *server, SoupSocket *sock) +setup_timeout_persistent (SoupServer *server, + SoupServerConnection *conn) { /* In order for the test to work correctly, we have to * close the connection *after* the client side writes @@ -101,8 +100,8 @@ * 3. Close the socket. */ g_mutex_lock (&server_mutex); - g_signal_connect (server, "request-started", - G_CALLBACK (timeout_request_started), NULL); + g_signal_connect (server, "request-finished", + G_CALLBACK (timeout_request_finished), NULL); } static void @@ -143,16 +142,16 @@ "Connection", "close"); if (too_long) { - SoupSocket *sock; + SoupServerConnection *conn; /* soup-message-io will wait for us to add * another chunk after the first, to fill out * the declared Content-Length. Instead, we * forcibly close the socket at that point. */ - sock = soup_server_message_get_soup_socket (msg); + conn = soup_server_message_get_connection (msg); g_signal_connect (msg, "wrote-chunk", - G_CALLBACK (close_socket), sock); + G_CALLBACK (close_socket), conn); } else if (no_close) { /* Remove the 'Connection: close' after writing * the headers, so that when we check it after @@ -166,10 +165,10 @@ } if (!strcmp (path, "/timeout-persistent")) { - SoupSocket *sock; + SoupServerConnection *conn; - sock = soup_server_message_get_soup_socket (msg); - setup_timeout_persistent (server, sock); + conn = soup_server_message_get_connection (msg); + setup_timeout_persistent (server, conn); } soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL); @@ -260,14 +259,17 @@ } static void -do_timeout_test_for_session (SoupSession *session) +do_timeout_test_for_base_uri (GUri *base_uri) { + SoupSession *session; SoupMessage *msg; GSocket *sockets4 = { NULL, NULL, NULL, NULL }; GUri *timeout_uri; int i; GBytes *body; + session = soup_test_session_new (NULL); + g_signal_connect (session, "request-queued", G_CALLBACK (request_queued_socket_collector), &sockets); @@ -310,23 +312,24 @@ for (i = 0; socketsi; i++) g_object_unref (socketsi); + + soup_test_session_abort_unref (session); } static void do_persistent_connection_timeout_test (void) { - SoupSession *session; - g_test_bug ("631525"); - debug_printf (1, " Normal session, message API\n"); - session = soup_test_session_new (NULL); - do_timeout_test_for_session (session); - soup_test_session_abort_unref (session); + debug_printf (1, " HTTP/1\n"); + do_timeout_test_for_base_uri (base_uri); + + debug_printf (1, " HTTP/2\n"); + do_timeout_test_for_base_uri (base_https_uri); } static void -do_persistent_connection_timeout_test_with_cancellation (void) +do_persistent_connection_timeout_test_with_cancellation_for_base_uri (GUri *base_uri) { SoupSession *session; SoupMessage *msg; @@ -409,6 +412,16 @@ soup_test_session_abort_unref (session); } +static void +do_persistent_connection_timeout_test_with_cancellation (void) +{ + debug_printf (1, " HTTP/1\n"); + do_persistent_connection_timeout_test_with_cancellation_for_base_uri (base_uri); +
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/tests/context-test.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/tests/context-test.c
Changed
@@ -9,7 +9,6 @@ static char *base_uri; typedef struct { - SoupServer *server; SoupServerMessage *msg; GSource *timeout; } SlowData; @@ -35,7 +34,7 @@ soup_message_body_append (response_body, SOUP_MEMORY_STATIC, "OK\r\n", 4); soup_message_body_complete (response_body); - soup_server_unpause_message (sd->server, sd->msg); + soup_server_message_unpause (sd->msg); g_object_unref (sd->msg); return FALSE; @@ -67,10 +66,9 @@ soup_message_headers_set_encoding (response_headers, SOUP_ENCODING_CHUNKED); g_object_ref (msg); - soup_server_pause_message (server, msg); + soup_server_message_pause (msg); sd = g_new (SlowData, 1); - sd->server = server; sd->msg = msg; sd->timeout = soup_add_timeout ( g_main_context_get_thread_default (), @@ -132,11 +130,11 @@ GAsyncResult *result, GMainContext *async_context) { - GInputStream *stream; + GBytes *body; g_assert_true (async_context == g_main_context_get_thread_default ()); - stream = soup_session_send_finish (session, result, NULL); - g_clear_object (&stream); + body = soup_session_send_and_read_finish (session, result, NULL); + g_clear_pointer (&body, g_bytes_unref); } static void @@ -178,9 +176,9 @@ msg = soup_message_new ("GET", uri); loop = g_main_loop_new (async_context, FALSE); g_signal_connect (msg, "finished", G_CALLBACK (message_finished), loop); - soup_session_send_async (session, msg, G_PRIORITY_DEFAULT, NULL, - (GAsyncReadyCallback)message_send_cb, - async_context); + soup_session_send_and_read_async (session, msg, G_PRIORITY_DEFAULT, NULL, + (GAsyncReadyCallback)message_send_cb, + async_context); g_main_loop_run (loop); /* We need one more iteration, because SoupMessage::finished is emitted * right before the message is unqueued. @@ -217,7 +215,7 @@ SoupSession *session; char *uri; SoupMessage *msg; - GInputStream *stream; + GBytes *body; GMainLoop *loop; idle = g_idle_add_full (G_PRIORITY_HIGH, idle_test2_fail, NULL, NULL); @@ -231,18 +229,18 @@ debug_printf (1, " send_message\n"); msg = soup_message_new ("GET", uri); - stream = soup_session_send (session, msg, NULL, NULL); + body = soup_session_send_and_read (session, msg, NULL, NULL); soup_test_assert_message_status (msg, SOUP_STATUS_OK); - g_object_unref (stream); + g_bytes_unref (body); g_object_unref (msg); debug_printf (1, " queue_message\n"); msg = soup_message_new ("GET", uri); loop = g_main_loop_new (async_context, FALSE); g_signal_connect (msg, "finished", G_CALLBACK (message_finished), loop); - soup_session_send_async (session, msg, G_PRIORITY_DEFAULT, NULL, - (GAsyncReadyCallback)message_send_cb, - async_context); + soup_session_send_and_read_async (session, msg, G_PRIORITY_DEFAULT, NULL, + (GAsyncReadyCallback)message_send_cb, + async_context); g_main_loop_run (loop); /* We need one more iteration, because SoupMessage::finished is emitted * right before the message is unqueued.
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/tests/cookies-test.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/tests/cookies-test.c
Changed
@@ -419,6 +419,92 @@ g_uri_unref (uri); } +typedef struct { + SoupSession *session; + const char *cookie; +} ThreadTestData; + +static void +task_sync_function (GTask *task, + GObject *source, + ThreadTestData *data, + GCancellable *cancellable) +{ + SoupMessage *msg; + GBytes *body; + + msg = soup_message_new_from_uri ("GET", first_party_uri); + soup_message_headers_append (soup_message_get_request_headers (msg), + "Echo-Set-Cookie", data->cookie); + body = soup_session_send_and_read (data->session, msg, NULL, NULL); + g_assert_nonnull (body); + g_bytes_unref (body); + g_object_unref (msg); + + g_task_return_boolean (task, TRUE); +} + +static void +task_finished_cb (SoupSession *session, + GAsyncResult *result, + guint *finished_count) +{ + g_assert_true (g_task_propagate_boolean (G_TASK (result), NULL)); + g_atomic_int_inc (finished_count); +} + +static gint +find_cookie (SoupCookie *cookie, + const char *name) +{ + return g_strcmp0 (soup_cookie_get_name (cookie), name); +} + +static void +do_cookies_threads_test (void) +{ + SoupSession *session; + SoupCookieJar *jar; + guint n_msgs = 4; + guint finished_count = 0; + guint i; + const char *values4 = { "one=1", "two=2", "three=3", "four=4" }; + GSList *cookies; + + session = soup_test_session_new (NULL); + soup_session_add_feature_by_type (session, SOUP_TYPE_COOKIE_JAR); + jar = SOUP_COOKIE_JAR (soup_session_get_feature (session, SOUP_TYPE_COOKIE_JAR)); + + for (i = 0; i < n_msgs; i++) { + GTask *task; + ThreadTestData *data; + + data = g_new (ThreadTestData, 1); + data->session = session; + data->cookie = valuesi; + + task = g_task_new (NULL, NULL, (GAsyncReadyCallback)task_finished_cb, &finished_count); + g_task_set_task_data (task, data, g_free); + g_task_run_in_thread (task, (GTaskThreadFunc)task_sync_function); + g_object_unref (task); + } + + while (g_atomic_int_get (&finished_count) != n_msgs) + g_main_context_iteration (NULL, TRUE); + + cookies = soup_cookie_jar_get_cookie_list (jar, first_party_uri, TRUE); + g_assert_cmpuint (g_slist_length (cookies), ==, 4); + g_assert_nonnull (g_slist_find_custom (cookies, "one", (GCompareFunc)find_cookie)); + g_assert_nonnull (g_slist_find_custom (cookies, "two", (GCompareFunc)find_cookie)); + g_assert_nonnull (g_slist_find_custom (cookies, "three", (GCompareFunc)find_cookie)); + g_assert_nonnull (g_slist_find_custom (cookies, "four", (GCompareFunc)find_cookie)); + + while (g_main_context_pending (NULL)) + g_main_context_iteration (NULL, FALSE); + + soup_test_session_abort_unref (session); +} + int main (int argc, char **argv) { @@ -443,6 +529,7 @@ g_test_add_func ("/cookies/get-cookies/empty-host", do_get_cookies_empty_host_test); g_test_add_func ("/cookies/remove-feature", do_remove_feature_test); g_test_add_func ("/cookies/secure-cookies", do_cookies_strict_secure_test); + g_test_add_func ("/cookies/threads", do_cookies_threads_test); ret = g_test_run ();
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/tests/http2-test.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/tests/http2-test.c
Changed
@@ -20,13 +20,20 @@ #include "test-utils.h" #include "soup-connection.h" #include "soup-message-private.h" +#include "soup-message-headers-private.h" +#include "soup-server-message-private.h" #include "soup-body-input-stream-http2.h" +#include <gio/gnetworking.h> + +static GUri *base_uri; typedef struct { SoupSession *session; - SoupMessage *msg; } Test; +#define LARGE_N_CHARS 24 +#define LARGE_CHARS_REPEAT 1024 + static void setup_session (Test *test, gconstpointer data) { @@ -42,56 +49,74 @@ static void do_basic_async_test (Test *test, gconstpointer data) { - test->msg = soup_message_new (SOUP_METHOD_GET, "https://127.0.0.1:5000/"); + SoupMessage *msg; + GBytes *response; GError *error = NULL; - GBytes *response = soup_test_session_async_send (test->session, test->msg, NULL, &error); + msg = soup_message_new_from_uri (SOUP_METHOD_GET, base_uri); + g_assert_cmpuint (soup_message_get_http_version (msg), ==, SOUP_HTTP_1_1); + + response = soup_test_session_async_send (test->session, msg, NULL, &error); g_assert_no_error (error); + g_assert_cmpuint (soup_message_get_http_version (msg), ==, SOUP_HTTP_2_0); g_assert_cmpstr (g_bytes_get_data (response, NULL), ==, "Hello world"); g_bytes_unref (response); - g_object_unref (test->msg); + g_object_unref (msg); } static void do_basic_sync_test (Test *test, gconstpointer data) { - test->msg = soup_message_new (SOUP_METHOD_GET, "https://127.0.0.1:5000/"); + SoupMessage *msg; + GBytes *response; GError *error = NULL; - GBytes *response = soup_session_send_and_read (test->session, test->msg, NULL, &error); + msg = soup_message_new_from_uri (SOUP_METHOD_GET, base_uri); + g_assert_cmpuint (soup_message_get_http_version (msg), ==, SOUP_HTTP_1_1); + response = soup_session_send_and_read (test->session, msg, NULL, &error); g_assert_no_error (error); + g_assert_cmpuint (soup_message_get_http_version (msg), ==, SOUP_HTTP_2_0); g_assert_cmpstr (g_bytes_get_data (response, NULL), ==, "Hello world"); g_bytes_unref (response); - g_object_unref (test->msg); + g_object_unref (msg); } static void do_no_content_async_test (Test *test, gconstpointer data) { - test->msg = soup_message_new (SOUP_METHOD_GET, "https://127.0.0.1:5000/no-content"); + GUri *uri; + SoupMessage *msg; + GBytes *response; GError *error = NULL; - GBytes *response = soup_test_session_async_send (test->session, test->msg, NULL, &error); + uri = g_uri_parse_relative (base_uri, "/no-content", SOUP_HTTP_URI_FLAGS, NULL); + msg = soup_message_new_from_uri (SOUP_METHOD_GET, uri); + response = soup_test_session_async_send (test->session, msg, NULL, &error); g_assert_no_error (error); - g_assert_cmpuint (soup_message_get_status (test->msg), ==, 204); + g_assert_cmpuint (soup_message_get_status (msg), ==, 204); g_assert_cmpuint (g_bytes_get_size (response), ==, 0); + g_uri_unref (uri); g_bytes_unref (response); - g_object_unref (test->msg); + g_object_unref (msg); } static void do_large_test (Test *test, gconstpointer data) { gboolean async = GPOINTER_TO_INT (data); - SoupMessage *msg = soup_message_new (SOUP_METHOD_GET, "https://127.0.0.1:5000/large"); + GUri *uri; + SoupMessage *msg; GBytes *response; GError *error = NULL; + uri = g_uri_parse_relative (base_uri, "/large", SOUP_HTTP_URI_FLAGS, NULL); + msg = soup_message_new_from_uri (SOUP_METHOD_GET, uri); + /* This is both large and read in chunks */ if (async) response = soup_test_session_async_send (test->session, msg, NULL, &error); @@ -99,9 +124,9 @@ response = soup_session_send_and_read (test->session, msg, NULL, &error); g_assert_no_error (error); - /* Size hardcoded to match http2-server.py's response */ - g_assert_cmpuint (g_bytes_get_size (response), ==, (1024 * 24) + 1); + g_assert_cmpuint (g_bytes_get_size (response), ==, (LARGE_N_CHARS * LARGE_CHARS_REPEAT) + 1); + g_uri_unref (uri); g_bytes_unref (response); g_object_unref (msg); } @@ -144,15 +169,18 @@ do_multi_message_async_test (Test *test, gconstpointer data) { GMainContext *async_context = g_main_context_ref_thread_default (); + GUri *uri1, *uri2; + SoupMessage *msg1, *msg2; + GBytes *response1 = NULL; + GBytes *response2 = NULL; - SoupMessage *msg1 = soup_message_new (SOUP_METHOD_GET, "https://127.0.0.1:5000/echo_query?body%201"); + uri1 = g_uri_parse_relative (base_uri, "echo_query?body%201", SOUP_HTTP_URI_FLAGS, NULL); + msg1 = soup_message_new_from_uri (SOUP_METHOD_GET, uri1); soup_message_set_http_version (msg1, SOUP_HTTP_2_0); - SoupMessage *msg2 = soup_message_new (SOUP_METHOD_GET, "https://127.0.0.1:5000/echo_query?body%202"); + uri2 = g_uri_parse_relative (base_uri, "echo_query?body%202", SOUP_HTTP_URI_FLAGS, NULL); + msg2 = soup_message_new_from_uri (SOUP_METHOD_GET, uri2); soup_message_set_http_version (msg2, SOUP_HTTP_2_0); - - GBytes *response1 = NULL; - GBytes *response2 = NULL; soup_session_send_async (test->session, msg1, G_PRIORITY_DEFAULT, NULL, on_send_complete, &response1); soup_session_send_async (test->session, msg2, G_PRIORITY_DEFAULT, NULL, on_send_complete, &response2); @@ -173,6 +201,8 @@ g_bytes_unref (response2); g_object_unref (msg1); g_object_unref (msg2); + g_uri_unref (uri1); + g_uri_unref (uri2); g_main_context_unref (async_context); } @@ -208,21 +238,19 @@ static void do_cancellation_test (Test *test, gconstpointer data) { + GUri *uri; SoupMessage *msg; GMainContext *async_context = g_main_context_ref_thread_default (); GCancellable *cancellable = g_cancellable_new (); gboolean done = FALSE; - msg = soup_message_new (SOUP_METHOD_GET, "https://127.0.0.1:5000/large"); + uri = g_uri_parse_relative (base_uri, "/large", SOUP_HTTP_URI_FLAGS, NULL); + msg = soup_message_new_from_uri (SOUP_METHOD_GET, uri); soup_session_send_and_read_async (test->session, msg, G_PRIORITY_DEFAULT, cancellable, (GAsyncReadyCallback)on_send_and_read_cancelled_complete, &done); - /* Just iterate until a partial read is happening */ - for (guint i = 100000; i; i--) - g_main_context_iteration (async_context, FALSE); - - /* Then cancel everything */ - g_cancellable_cancel (cancellable); + /* Cancel right after getting the headers */ + g_signal_connect_swapped (msg, "got-headers", G_CALLBACK (g_cancellable_cancel), cancellable); while (!done) g_main_context_iteration (async_context, FALSE); @@ -230,13 +258,14 @@ g_object_unref (msg); done = FALSE; - msg = soup_message_new (SOUP_METHOD_GET, "https://127.0.0.1:5000/large"); + msg = soup_message_new_from_uri (SOUP_METHOD_GET, uri); soup_session_send_and_read_async (test->session, msg, G_PRIORITY_DEFAULT, NULL, (GAsyncReadyCallback)on_send_and_read_complete, &done); while (!done) g_main_context_iteration (async_context, FALSE); + g_uri_unref (uri); g_object_unref (msg); g_object_unref (cancellable); g_main_context_unref (async_context); @@ -258,7 +287,7 @@ if (cancelled_by_session) flags |= SOUP_TEST_REQUEST_CANCEL_BY_SESSION;
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/tests/httpd.conf.in -> _service:tar_scm:libsoup-3.2.2.tar.xz/tests/httpd.conf.in
Changed
@@ -13,7 +13,7 @@ # Change this to "./error.log" if it's failing and you don't know why ErrorLog /dev/null -LoadModule mpm_prefork_module @APACHE_MODULE_DIR@/mod_mpm_prefork.so +LoadModule mpm_event_module @APACHE_MODULE_DIR@/mod_mpm_event.so LoadModule alias_module @APACHE_MODULE_DIR@/mod_alias.so LoadModule auth_basic_module @APACHE_MODULE_DIR@/mod_auth_basic.so LoadModule auth_digest_module @APACHE_MODULE_DIR@/mod_auth_digest.so @@ -29,12 +29,15 @@ LoadModule proxy_connect_module @APACHE_MODULE_DIR@/mod_proxy_connect.so LoadModule ssl_module @APACHE_SSL_MODULE_DIR@/mod_ssl.so @IF_HAVE_MOD_UNIXD@LoadModule unixd_module @APACHE_SSL_MODULE_DIR@/mod_unixd.so +@IF_HAVE_MOD_HTTP2@LoadModule http2_module @APACHE_HTTP2_MODULE_DIR@/mod_http2.so DirectoryIndex index.txt TypesConfig /dev/null -AddType application/x-httpd-php .php Redirect permanent /redirected /index.txt +# Prefer http1 for now because most of the tests expect http1 behavior. +Protocols http/1.1 h2 + # Proxy #1: unauthenticated Listen 127.0.0.1:47526 <VirtualHost 127.0.0.1:47526> @@ -281,3 +284,7 @@ # test RFC2069-style Digest AuthDigestQop none </Location> + +<Location /client-cert> + SSLVerifyClient require +</Location> \ No newline at end of file
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/tests/meson.build -> _service:tar_scm:libsoup-3.2.2.tar.xz/tests/meson.build
Changed
@@ -78,12 +78,14 @@ {'name': 'date'}, {'name': 'forms'}, {'name': 'header-parsing'}, + {'name': 'http2'}, {'name': 'http2-body-stream'}, {'name': 'hsts'}, {'name': 'hsts-db'}, {'name': 'logger'}, {'name': 'misc'}, {'name': 'multipart'}, + {'name': 'multithread'}, {'name': 'no-ssl'}, {'name': 'ntlm'}, {'name': 'redirect'}, @@ -93,7 +95,6 @@ {'name': 'server-auth'}, {'name': 'server'}, {'name': 'sniffing'}, - {'name': 'socket'}, {'name': 'ssl', 'dependencies': gnutls_dep, 'depends': mock_pkcs11_module, @@ -107,16 +108,6 @@ 'dependencies': libz_dep}, -if quart_found - configure_file(input : 'http2-server.py', - output : 'http2-server.py', - copy : true, - install : installed_tests_enabled, - install_dir : installed_tests_execdir) - - tests += {'name': 'http2'} -endif - if brotlidec_dep.found() tests += {'name': 'brotli-decompressor'}
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/tests/misc-test.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/tests/misc-test.c
Changed
@@ -21,9 +21,7 @@ static gboolean timeout_finish_message (gpointer msg) { - SoupServer *server = g_object_get_data (G_OBJECT (msg), "server"); - - soup_server_unpause_message (server, msg); + soup_server_message_unpause (msg); return FALSE; } @@ -37,7 +35,7 @@ const char *method = soup_server_message_get_method (msg); GUri *uri = soup_server_message_get_uri (msg); - if (method != SOUP_METHOD_GET && method != SOUP_METHOD_POST) { + if (method != SOUP_METHOD_GET && method != SOUP_METHOD_POST && method != SOUP_METHOD_PUT) { soup_server_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED, NULL); return; } @@ -47,10 +45,28 @@ return; } + if (!strcmp (path, "/session")) { + SoupMessageHeaders *request_headers; + const char *session_id; + + request_headers = soup_server_message_get_request_headers (msg); + session_id = soup_message_headers_get_one (request_headers, "X-SoupTest-Session-Id"); + if (!session_id) { + SoupMessageHeaders *response_headers; + + response_headers = soup_server_message_get_response_headers (msg); + soup_message_headers_replace (response_headers, "X-SoupTest-Session-Id", "session-1"); + soup_server_message_set_status (msg, SOUP_STATUS_CONFLICT, NULL); + } else { + soup_server_message_set_status (msg, SOUP_STATUS_CREATED, NULL); + } + + return; + } + if (!strcmp (path, "/slow")) { GSource *timeout; - soup_server_pause_message (server, msg); - g_object_set_data (G_OBJECT (msg), "server", server); + soup_server_message_pause (msg); timeout = soup_add_timeout (g_main_context_get_thread_default (), 1000, timeout_finish_message, msg); g_source_unref (timeout); @@ -817,14 +833,14 @@ g_bytes_unref (body); g_object_unref (msg2); - /* We get a new one if we force a new connection */ + /* We get the same one if we force a new connection */ msg2 = soup_message_new_from_uri (SOUP_METHOD_GET, base_uri); soup_message_add_flags (msg2, SOUP_MESSAGE_NEW_CONNECTION); g_assert_null (soup_message_get_remote_address (msg2)); body = soup_test_session_async_send (session, msg2, NULL, NULL); g_assert_nonnull (soup_message_get_remote_address (msg2)); g_assert_cmpuint (soup_message_get_connection_id (msg1), !=, soup_message_get_connection_id (msg2)); - g_assert_false (soup_message_get_remote_address (msg1) == soup_message_get_remote_address (msg2)); + g_assert_true (soup_message_get_remote_address (msg1) == soup_message_get_remote_address (msg2)); g_bytes_unref (body); g_object_unref (msg2); @@ -871,6 +887,141 @@ soup_test_session_abort_unref (session); } +typedef struct { + SoupSession *session; + GCancellable *cancellable; + GBytes *body; + guint64 connections2; + gboolean done; +} ConflictTestData; + +static void +conflict_test_send_ready_cb (SoupSession *session, + GAsyncResult *result, + ConflictTestData *data) +{ + GInputStream *stream; + SoupMessage *msg = soup_session_get_async_result_message (session, result); + GError *error = NULL; + + stream = soup_session_send_finish (session, result, &error); + if (stream) { + guint status = soup_message_get_status (msg); + + soup_test_request_read_all (stream, NULL, NULL); + g_object_unref (stream); + + if (status != SOUP_STATUS_CONFLICT) { + g_assert_cmpuint (status, ==, SOUP_STATUS_CREATED); + data->connections1 = soup_message_get_connection_id (msg); + data->done = TRUE; + } + } else { + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); + g_error_free (error); + } +} + +static void +conflict_test_on_conflict_cb (SoupMessage *msg, + ConflictTestData *data) +{ + SoupMessageHeaders *response_headers; + SoupMessageHeaders *request_headers; + const gchar *session_id; + SoupMessage *new_msg; + + g_cancellable_cancel (data->cancellable); + g_clear_object (&data->cancellable); + + data->connections0 = soup_message_get_connection_id (msg); + response_headers = soup_message_get_response_headers (msg); + session_id = soup_message_headers_get_one (response_headers, "X-SoupTest-Session-Id"); + new_msg = soup_message_new_from_uri (SOUP_METHOD_PUT, soup_message_get_uri (msg)); + request_headers = soup_message_get_request_headers (new_msg); + soup_message_headers_replace (request_headers, "X-SoupTest-Session-Id", session_id); + + data->cancellable = g_cancellable_new (); + soup_message_set_request_body_from_bytes (new_msg, "text/plain", data->body); + soup_session_send_async (data->session, new_msg, G_PRIORITY_DEFAULT, data->cancellable, + (GAsyncReadyCallback)conflict_test_send_ready_cb, data); + g_object_unref (new_msg); +} + +static void +conflict_test_on_got_body_cb (SoupMessage *msg, + ConflictTestData *data) +{ + if (soup_message_get_status (msg) == SOUP_STATUS_CONFLICT) + conflict_test_on_conflict_cb (msg, data); +} + +static void +do_new_request_on_conflict_test (void) +{ + GUri *uri; + SoupMessage *msg; + ConflictTestData data; + static const char *body = "conflict test body"; + + data.session = soup_test_session_new (NULL); + data.cancellable = g_cancellable_new (); + data.body = g_bytes_new_static (body, strlen (body)); + data.connections0 = data.connections1 = 0; + data.done = FALSE; + + /* First try with restarting on got-headers */ + uri = g_uri_parse_relative (base_uri, "/session", SOUP_HTTP_URI_FLAGS, NULL); + msg = soup_message_new_from_uri (SOUP_METHOD_PUT, uri); + soup_message_set_request_body_from_bytes (msg, "text/plain", data.body); + soup_message_add_status_code_handler (msg, "got-headers", SOUP_STATUS_CONFLICT, + G_CALLBACK (conflict_test_on_conflict_cb), + &data); + soup_session_send_async (data.session, msg, G_PRIORITY_DEFAULT, data.cancellable, + (GAsyncReadyCallback)conflict_test_send_ready_cb, &data); + + while (!data.done) + g_main_context_iteration (NULL, TRUE); + + g_assert_cmpuint (data.connections0, >, 0); + g_assert_cmpuint (data.connections1, >, 0); + g_assert_cmpuint (data.connections0, !=, data.connections1); + + g_object_unref (msg); + g_object_unref (data.cancellable); + + while (g_main_context_pending (NULL)) + g_main_context_iteration (NULL, FALSE); + + data.cancellable = g_cancellable_new (); + data.connections0 = data.connections1 = 0; + data.done = FALSE; + + /* Now try with the restarting on got-body */ + msg = soup_message_new_from_uri (SOUP_METHOD_PUT, uri); + soup_message_set_request_body_from_bytes (msg, "text/plain", data.body); + g_signal_connect (msg, "got-body", G_CALLBACK (conflict_test_on_got_body_cb), &data); + soup_session_send_async (data.session, msg, G_PRIORITY_DEFAULT, data.cancellable, + (GAsyncReadyCallback)conflict_test_send_ready_cb, &data); + + while (!data.done) + g_main_context_iteration (NULL, TRUE); + + g_assert_cmpuint (data.connections0, >, 0); + g_assert_cmpuint (data.connections1, >, 0); + g_assert_cmpuint (data.connections0, ==, data.connections1); + + g_object_unref (msg); + g_object_unref (data.cancellable); + + while (g_main_context_pending (NULL))
View file
_service:tar_scm:libsoup-3.2.2.tar.xz/tests/multithread-test.c
Added
@@ -0,0 +1,564 @@ +/* + * Copyright 2022 Igalia S.L. + * + * This file is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * SPDX-License-Identifier: LGPL-2.0-or-later + */ + +#include "test-utils.h" + +#include "soup-connection.h" +#include "soup-message-private.h" + +static GUri *base_uri; + +typedef enum { + BASIC_SYNC = 1 << 0, + BASIC_SSL = 1 << 1, + BASIC_PROXY = 1 << 2, + BASIC_HTTP2 = 1 << 3, + BASIC_MAX_CONNS = 1 << 4, + BASIC_NO_MAIN_THREAD = 1 << 5 +} BasicTestFlags; + +typedef struct { + SoupSession *session; + BasicTestFlags flags; +} Test; + +#define HTTPS_SERVER "https://127.0.0.1:47525" +#define HTTP_PROXY "http://127.0.0.1:47526" + +static void +test_setup (Test *test, gconstpointer data) +{ + test->flags = GPOINTER_TO_UINT (data); + if (test->flags & BASIC_MAX_CONNS) + test->session = soup_test_session_new ("max-conns", 1, NULL); + else + test->session = soup_test_session_new (NULL); +} + +static void +test_teardown (Test *test, gconstpointer data) +{ + soup_test_session_abort_unref (test->session); + while (g_main_context_pending (NULL)) + g_main_context_iteration (NULL, FALSE); +} + +static void +msg_signal_check_context (SoupMessage *msg, + GMainContext *context) +{ + g_assert_true (g_object_get_data (G_OBJECT (msg), "thread-context") == context); +} + +static void +connect_message_signals_to_check_context (SoupMessage *msg, + GMainContext *context) +{ + g_object_set_data (G_OBJECT (msg), "thread-context", context); + g_signal_connect (msg, "starting", G_CALLBACK (msg_signal_check_context), context); + g_signal_connect (msg, "wrote-headers", G_CALLBACK (msg_signal_check_context), context); + g_signal_connect (msg, "wrote-body", G_CALLBACK (msg_signal_check_context), context); + g_signal_connect (msg, "got-headers", G_CALLBACK (msg_signal_check_context), context); + g_signal_connect (msg, "got-body", G_CALLBACK (msg_signal_check_context), context); + g_signal_connect (msg, "finished", G_CALLBACK (msg_signal_check_context), context); +} + +static void +msg_signal_check_thread (SoupMessage *msg, + GThread *thread) +{ + g_assert_true (g_object_get_data (G_OBJECT (msg), "thread-id") == thread); +} + +static void +connect_message_signals_to_check_thread (SoupMessage *msg, + GThread *thread) +{ + g_object_set_data (G_OBJECT (msg), "thread-id", thread); + g_signal_connect (msg, "starting", G_CALLBACK (msg_signal_check_thread), thread); + g_signal_connect (msg, "wrote-headers", G_CALLBACK (msg_signal_check_thread), thread); + g_signal_connect (msg, "wrote-body", G_CALLBACK (msg_signal_check_thread), thread); + g_signal_connect (msg, "got-headers", G_CALLBACK (msg_signal_check_thread), thread); + g_signal_connect (msg, "got-body", G_CALLBACK (msg_signal_check_thread), thread); + g_signal_connect (msg, "finished", G_CALLBACK (msg_signal_check_thread), thread); +} + +static void +message_send_and_read_ready_cb (SoupSession *session, + GAsyncResult *result, + GMainLoop *loop) +{ + GBytes *body; + GBytes *index = soup_test_get_index (); + GError *error = NULL; + + if (loop) + g_assert_true (g_main_loop_get_context (loop) == g_main_context_get_thread_default ()); + + body = soup_session_send_and_read_finish (session, result, &error); + g_assert_no_error (error); + g_assert_nonnull (body); + g_assert_cmpmem (g_bytes_get_data (body, NULL), g_bytes_get_size (body), g_bytes_get_data (index, NULL), g_bytes_get_size (index)); + g_bytes_unref (body); + + if (loop) + g_main_loop_quit (loop); +} + +static void +task_async_function (GTask *task, + GObject *source, + Test *test, + GCancellable *cancellable) +{ + GMainContext *context; + GMainLoop *loop; + SoupMessage *msg; + + context = g_main_context_new (); + g_main_context_push_thread_default (context); + + loop = g_main_loop_new (context, FALSE); + + if (test->flags & BASIC_SSL) + msg = soup_message_new ("GET", HTTPS_SERVER); + else + msg = soup_message_new_from_uri ("GET", base_uri); + if (test->flags & BASIC_HTTP2) + soup_message_set_force_http_version (msg, SOUP_HTTP_2_0); + connect_message_signals_to_check_context (msg, context); + soup_session_send_and_read_async (test->session, msg, G_PRIORITY_DEFAULT, NULL, + (GAsyncReadyCallback)message_send_and_read_ready_cb, + loop); + g_object_unref (msg); + + g_main_loop_run (loop); + g_main_loop_unref (loop); + + g_task_return_boolean (task, TRUE); + + g_main_context_pop_thread_default (context); + g_main_context_unref (context); +} + +static void +task_sync_function (GTask *task, + GObject *source, + Test *test, + GCancellable *cancellable) +{ + SoupMessage *msg; + GBytes *body; + GBytes *index = soup_test_get_index (); + GError *error = NULL; + + if (test->flags & BASIC_SSL) + msg = soup_message_new ("GET", HTTPS_SERVER); + else + msg = soup_message_new_from_uri ("GET", base_uri); + if (test->flags & BASIC_HTTP2) + soup_message_set_force_http_version (msg, SOUP_HTTP_2_0); + connect_message_signals_to_check_thread (msg, g_thread_self ()); + body = soup_session_send_and_read (test->session, msg, NULL, &error); + g_assert_no_error (error); + g_assert_nonnull (body); + g_assert_cmpmem (g_bytes_get_data (body, NULL), g_bytes_get_size (body), g_bytes_get_data (index, NULL), g_bytes_get_size (index)); + g_bytes_unref (body); + g_object_unref (msg); + + g_task_return_boolean (task, TRUE); +} + +static void +task_finished_cb (GObject *source, + GAsyncResult *result, + guint *finished_count) +{ + g_assert_true (g_task_propagate_boolean (G_TASK (result), NULL)); + g_atomic_int_inc (finished_count); +} + +static void +message_finished_cb (SoupMessage *msg, + guint *finished_count)
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/tests/proxy-test.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/tests/proxy-test.c
Changed
@@ -340,11 +340,43 @@ g_object_unref (cache); } +static void +do_proxy_connect_error_test (gconstpointer data) +{ + GUri *base_uri = (GUri *)data; + GUri *proxy_uri; + char *proxy_uri_str; + SoupSession *session; + SoupMessage *msg; + GProxyResolver *resolver; + GBytes *body; + GError *error = NULL; + + /* Proxy connection will success, but CONNECT message to https will fail due to TLS errors */ + proxy_uri = soup_uri_copy (base_uri, SOUP_URI_SCHEME, "http", NULL); + proxy_uri_str = g_uri_to_string (proxy_uri); + g_uri_unref (proxy_uri); + + resolver = g_simple_proxy_resolver_new (proxy_uri_str, (char **)ignore_hosts); + g_free (proxy_uri_str); + session = soup_test_session_new ("proxy-resolver", resolver, NULL); + g_object_unref (resolver); + + msg = soup_message_new_from_uri (SOUP_METHOD_GET, base_uri); + body = soup_test_session_async_send (session, msg, NULL, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED); + + g_error_free (error); + g_bytes_unref (body); + g_object_unref (msg); + soup_test_session_abort_unref (session); +} + int main (int argc, char **argv) { SoupServer *server; - GUri *base_uri; + GUri *base_uri, *base_https_uri; char *path; int i, ret; @@ -359,6 +391,7 @@ server = soup_test_server_new (SOUP_TEST_SERVER_IN_THREAD); soup_server_add_handler (server, NULL, server_callback, NULL, NULL); base_uri = soup_test_server_get_uri (server, "http", NULL); + base_https_uri = soup_test_server_get_uri (server, "https", NULL); for (i = 0; i < ntests; i++) { path = g_strdup_printf ("/proxy/%s", testsi.explanation); @@ -369,10 +402,12 @@ g_test_add_data_func ("/proxy/fragment", base_uri, do_proxy_fragment_test); g_test_add_func ("/proxy/redirect", do_proxy_redirect_test); g_test_add_func ("/proxy/auth-cache", do_proxy_auth_cache_test); + g_test_add_data_func ("/proxy/connect-error", base_https_uri, do_proxy_connect_error_test); ret = g_test_run (); g_uri_unref (base_uri); + g_uri_unref (base_https_uri); soup_test_server_quit_unref (server); for (i = 0; i < 3; i++) g_object_unref (proxy_resolversi);
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/tests/server-test.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/tests/server-test.c
Changed
@@ -6,6 +6,7 @@ #include "test-utils.h" #include "soup-message-private.h" #include "soup-uri-utils-private.h" +#include "soup-misc.h" #include <gio/gnetworking.h> @@ -770,7 +771,6 @@ } typedef struct { - SoupServer *server; SoupServerMessage *smsg; gboolean handler_called; gboolean paused; @@ -781,7 +781,7 @@ { UnhandledServerData *usd = user_data; - soup_server_unpause_message (usd->server, usd->smsg); + soup_server_message_unpause (usd->smsg); return FALSE; } @@ -798,10 +798,10 @@ if (soup_message_headers_get_one (soup_server_message_get_request_headers (msg), "X-Test-Server-Pause")) { usd->paused = TRUE; - usd->server = server; usd->smsg = msg; - soup_server_pause_message (server, msg); - g_idle_add (idle_unpause_message, usd); + soup_server_message_pause (msg); + soup_add_completion (g_main_context_get_thread_default (), + idle_unpause_message, usd); } } @@ -1237,7 +1237,7 @@ SOUP_MEMORY_COPY, error->message, strlen (error->message)); g_error_free (error); - soup_server_unpause_message (tunnel->self, tunnel->msg); + soup_server_message_unpause (tunnel->msg); tunnel_close (tunnel); return; } @@ -1246,7 +1246,7 @@ tunnel->server.ostream = g_io_stream_get_output_stream (tunnel->server.iostream); soup_server_message_set_status (tunnel->msg, SOUP_STATUS_OK, NULL); - soup_server_unpause_message (tunnel->self, tunnel->msg); + soup_server_message_unpause (tunnel->msg); g_signal_connect (tunnel->msg, "wrote-body", G_CALLBACK (start_tunnel), tunnel); } @@ -1267,7 +1267,7 @@ return; } - soup_server_pause_message (server, msg); + soup_server_message_pause (msg); tunnel = g_new0 (Tunnel, 1); tunnel->self = g_object_ref (server);
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/tests/ssl-test.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/tests/ssl-test.c
Changed
@@ -165,10 +165,12 @@ GTlsDatabase *tls_db; GTlsCertificate *certificate; GTlsInteraction *interaction; + GUri *peer_uri; GError *error = NULL; SOUP_TEST_SKIP_IF_NO_TLS; + peer_uri = g_uri_parse_relative (uri, "/check-peer", SOUP_HTTP_URI_FLAGS, NULL); session = soup_test_session_new (NULL); tls_db = soup_session_get_tls_database (session); g_object_set (server, "tls-database", tls_db, "tls-auth-mode", G_TLS_AUTHENTICATION_REQUIRED, NULL); @@ -200,7 +202,7 @@ g_object_unref (interaction); /* With a GTlsInteraction */ - msg = soup_message_new_from_uri ("GET", uri); + msg = soup_message_new_from_uri ("GET", peer_uri); body = soup_test_session_async_send (session, msg, NULL, &error); g_assert_no_error (error); soup_test_assert_message_status (msg, SOUP_STATUS_OK); @@ -213,6 +215,7 @@ soup_test_session_abort_unref (session); g_object_unref (certificate); + g_uri_unref (peer_uri); } static gboolean @@ -700,6 +703,26 @@ soup_server_message_set_response (msg, "text/plain", SOUP_MEMORY_STATIC, "ok\r\n", 4); + + if (!strcmp (path, "/check-peer")) { + GTlsCertificate *certificate; + GTlsCertificateFlags flags; + + certificate = soup_server_message_get_tls_peer_certificate (msg); + g_assert_nonnull (certificate); + + flags = soup_server_message_get_tls_peer_certificate_errors (msg); + g_assert_cmpuint (flags, ==, 0); + + /* Check also the properties are properly working */ + g_object_get (G_OBJECT (msg), + "tls-peer-certificate", &certificate, + "tls-peer-certificate-errors", &flags, + NULL); + g_assert_nonnull (certificate); + g_assert_cmpuint (flags, ==, 0); + g_object_unref (certificate); + } } int
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/tests/test-utils.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/tests/test-utils.c
Changed
@@ -3,6 +3,7 @@ #include "test-utils.h" #include "soup-misc.h" #include "soup-session-private.h" +#include "soup-server-private.h" #include <glib/gprintf.h> #ifdef G_OS_UNIX @@ -114,8 +115,6 @@ apache_cleanup (); #endif - quart_cleanup (); - if (logger) g_object_unref (logger); if (index_buffer) @@ -274,75 +273,6 @@ #endif /* HAVE_APACHE */ -static GSubprocess *quart_proc; - -gboolean -quart_init (void) -{ - if (quart_proc) - return TRUE; - - GSubprocessLauncher *launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDOUT_PIPE); // | G_SUBPROCESS_FLAGS_STDERR_SILENCE - g_subprocess_launcher_set_cwd (launcher, g_test_get_dir (G_TEST_DIST)); - - GError *error = NULL; - char *script = soup_test_build_filename_abs (G_TEST_DIST, "http2-server.py", NULL); - quart_proc = g_subprocess_launcher_spawn (launcher, &error, script, NULL); - g_free (script); - g_object_unref (launcher); - - if (error) { - g_test_message ("Failed to start quart server: %s", error->message); - g_error_free (error); - return FALSE; - } - - GDataInputStream *in_stream = g_data_input_stream_new (g_subprocess_get_stdout_pipe (quart_proc)); - - // We don't own the stream, don't break the pipe - g_filter_input_stream_set_close_base_stream (G_FILTER_INPUT_STREAM (in_stream), FALSE); - - // Read stdout until the server says it is running - while (TRUE) { - char *line = g_data_input_stream_read_line_utf8 (in_stream, NULL, NULL, &error); - - if (error) { - g_test_message ("Failed to start quart server: %s", error->message); - g_error_free (error); - g_object_unref (in_stream); - return FALSE; - } else if (line == NULL) { - g_test_message ("Failed to start quart server (not installed?)"); - g_object_unref (in_stream); - return FALSE; - } - - if (g_str_has_prefix (line, " * Running")) { - g_test_message ("Started quart server: %s", line + 3); - g_free (line); - g_object_unref (in_stream); - return TRUE; - } - g_free (line); - } -} - -void -quart_cleanup (void) -{ - if (quart_proc) { - GError *error = NULL; - g_subprocess_force_exit (quart_proc); - g_subprocess_wait (quart_proc, NULL, &error); - if (error) { - g_test_message ("Failed to stop quart server: %s", error->message); - g_error_free (error); - } - } - - g_clear_object (&quart_proc); -} - SoupSession * soup_test_session_new (const char *propname, ...) { @@ -567,6 +497,8 @@ NULL); g_clear_object (&cert); + soup_server_set_http2_enabled (server, options & SOUP_TEST_SERVER_HTTP2); + g_object_set_data (G_OBJECT (server), "options", GUINT_TO_POINTER (options)); if (options & SOUP_TEST_SERVER_UNIX_SOCKET) {
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/tests/test-utils.h -> _service:tar_scm:libsoup-3.2.2.tar.xz/tests/test-utils.h
Changed
@@ -47,9 +47,6 @@ } G_STMT_END #endif -gboolean quart_init (void); -void quart_cleanup (void); - gboolean have_curl (void); typedef enum { @@ -74,7 +71,8 @@ SOUP_TEST_SERVER_DEFAULT = 0, SOUP_TEST_SERVER_IN_THREAD = (1 << 0), SOUP_TEST_SERVER_NO_DEFAULT_LISTENER = (1 << 1), - SOUP_TEST_SERVER_UNIX_SOCKET = (1 << 2) + SOUP_TEST_SERVER_UNIX_SOCKET = (1 << 2), + SOUP_TEST_SERVER_HTTP2 = (1 << 3) } SoupTestServerOptions; SoupServer *soup_test_server_new (SoupTestServerOptions options);
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/tests/timeout-test.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/tests/timeout-test.c
Changed
@@ -179,9 +179,7 @@ static gboolean timeout_finish_message (gpointer msg) { - SoupServer *server = g_object_get_data (G_OBJECT (msg), "server"); - - soup_server_unpause_message (server, msg); + soup_server_message_unpause (msg); return FALSE; } @@ -199,8 +197,7 @@ if (!strcmp (path, "/slow")) { GSource *timeout; - soup_server_pause_message (server, msg); - g_object_set_data (G_OBJECT (msg), "server", server); + soup_server_message_pause (msg); timeout = soup_add_timeout (g_main_context_get_thread_default (), 4000, timeout_finish_message, msg); g_source_unref (timeout);
View file
_service:tar_scm:libsoup-3.0.6.tar.xz/tests/websocket-test.c -> _service:tar_scm:libsoup-3.2.2.tar.xz/tests/websocket-test.c
Changed
@@ -907,6 +907,11 @@ g_assert_cmpstr (soup_message_headers_get_one (soup_message_get_response_headers (test->msg), "Sec-WebSocket-Protocol"), ==, NULL); } +typedef enum { + CLOSE_TEST_FLAG_SERVER = 1 << 0, + CLOSE_TEST_FLAG_CLIENT = 1 << 1 +} CloseTestFlags; + static const struct { gushort code; const char *reason; @@ -914,11 +919,16 @@ const char *expected_sender_reason; gushort expected_receiver_code; const char *expected_receiver_reason; + CloseTestFlags flags; } close_clean_tests = { - { SOUP_WEBSOCKET_CLOSE_NORMAL, "NORMAL", SOUP_WEBSOCKET_CLOSE_NORMAL, "NORMAL", SOUP_WEBSOCKET_CLOSE_NORMAL, "NORMAL" }, - { SOUP_WEBSOCKET_CLOSE_GOING_AWAY, "GOING_AWAY", SOUP_WEBSOCKET_CLOSE_GOING_AWAY, "GOING_AWAY", SOUP_WEBSOCKET_CLOSE_GOING_AWAY, "GOING_AWAY" }, - { SOUP_WEBSOCKET_CLOSE_NORMAL, NULL, SOUP_WEBSOCKET_CLOSE_NORMAL, NULL, SOUP_WEBSOCKET_CLOSE_NORMAL, NULL }, - { SOUP_WEBSOCKET_CLOSE_NO_STATUS, NULL, SOUP_WEBSOCKET_CLOSE_NORMAL, NULL, SOUP_WEBSOCKET_CLOSE_NO_STATUS, NULL }, + { SOUP_WEBSOCKET_CLOSE_NORMAL, "NORMAL", SOUP_WEBSOCKET_CLOSE_NORMAL, "NORMAL", SOUP_WEBSOCKET_CLOSE_NORMAL, "NORMAL", CLOSE_TEST_FLAG_SERVER | CLOSE_TEST_FLAG_CLIENT }, + { SOUP_WEBSOCKET_CLOSE_GOING_AWAY, "GOING_AWAY", SOUP_WEBSOCKET_CLOSE_GOING_AWAY, "GOING_AWAY", SOUP_WEBSOCKET_CLOSE_GOING_AWAY, "GOING_AWAY", CLOSE_TEST_FLAG_SERVER | CLOSE_TEST_FLAG_CLIENT }, + { SOUP_WEBSOCKET_CLOSE_NORMAL, NULL, SOUP_WEBSOCKET_CLOSE_NORMAL, NULL, SOUP_WEBSOCKET_CLOSE_NORMAL, NULL, CLOSE_TEST_FLAG_SERVER | CLOSE_TEST_FLAG_CLIENT }, + { SOUP_WEBSOCKET_CLOSE_NO_STATUS, NULL, SOUP_WEBSOCKET_CLOSE_NORMAL, NULL, SOUP_WEBSOCKET_CLOSE_NO_STATUS, NULL, CLOSE_TEST_FLAG_SERVER | CLOSE_TEST_FLAG_CLIENT }, + { 2999, NULL, SOUP_WEBSOCKET_CLOSE_PROTOCOL_ERROR, NULL, SOUP_WEBSOCKET_CLOSE_PROTOCOL_ERROR, NULL, CLOSE_TEST_FLAG_CLIENT }, + { 2999, NULL, 0, NULL, SOUP_WEBSOCKET_CLOSE_PROTOCOL_ERROR, NULL, CLOSE_TEST_FLAG_SERVER }, + { 5000, NULL, SOUP_WEBSOCKET_CLOSE_PROTOCOL_ERROR, NULL, SOUP_WEBSOCKET_CLOSE_PROTOCOL_ERROR, NULL, CLOSE_TEST_FLAG_CLIENT }, + { 5000, NULL, 0, NULL, SOUP_WEBSOCKET_CLOSE_PROTOCOL_ERROR, NULL, CLOSE_TEST_FLAG_SERVER }, }; static void @@ -958,6 +968,9 @@ guint i; for (i = 0; i < G_N_ELEMENTS (close_clean_tests); i++) { + if (!(close_clean_testsi.flags & CLOSE_TEST_FLAG_CLIENT)) + continue; + setup_soup_connection (test, data); do_close_clean_client (test, @@ -979,6 +992,9 @@ guint i; for (i = 0; i < G_N_ELEMENTS (close_clean_tests); i++) { + if (!(close_clean_testsi.flags & CLOSE_TEST_FLAG_CLIENT)) + continue; + setup_direct_connection (test, data); do_close_clean_client (test, @@ -1030,6 +1046,9 @@ guint i; for (i = 0; i < G_N_ELEMENTS (close_clean_tests); i++) { + if (!(close_clean_testsi.flags & CLOSE_TEST_FLAG_SERVER)) + continue; + setup_direct_connection (test, data); do_close_clean_server (test, @@ -1051,6 +1070,9 @@ guint i; for (i = 0; i < G_N_ELEMENTS (close_clean_tests); i++) { + if (!(close_clean_testsi.flags & CLOSE_TEST_FLAG_SERVER)) + continue; + setup_direct_connection (test, data); do_close_clean_server (test, @@ -1549,6 +1571,8 @@ g_assert_cmpstr (remote_ip, ==, str); g_free (str); + g_assert_nonnull (soup_server_message_get_socket (msg)); + test->server = g_object_ref (connection); }
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2