[libsoup] Port to gi-docgen



commit c7a4b24e98797f8f2baa07449b7e2a33d36fc525
Author: Maximiliano Sandoval R <msandova gnome org>
Date:   Sun Jan 16 12:02:16 2022 +0100

    Port to gi-docgen
    
    The file  was not used anywhere docs/reference/client-howto.xml.

 .gitlab-ci.yml                                     |   23 +-
 .gitlab-ci/check-docs.py                           |   24 -
 docs/reference/build-howto.md                      |   68 ++
 docs/reference/build-howto.xml                     |   70 --
 docs/reference/client-advanced.md                  |  156 +++
 docs/reference/client-advanced.xml                 |  171 ----
 .../{client-basic.xml => client-basic.md}          |   96 +-
 docs/reference/client-howto.xml                    |  535 ----------
 docs/reference/{client-tls.xml => client-tls.md}   |   55 +-
 docs/reference/libsoup-3.0-docs.xml                |  118 ---
 docs/reference/libsoup-3.0-sections.txt            | 1037 --------------------
 docs/reference/libsoup.toml.in                     |   50 +
 docs/reference/meson.build                         |  119 +--
 docs/reference/migrating-from-libsoup-2.md         |  162 +++
 docs/reference/migrating-from-libsoup-2.xml        |  192 ----
 docs/reference/server-howto.md                     |  247 +++++
 docs/reference/server-howto.xml                    |  380 -------
 docs/reference/urlmap.js                           |    6 +
 subprojects/gi-docgen.wrap                         |    6 +
 19 files changed, 820 insertions(+), 2695 deletions(-)
---
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index f2b61d9d..b7aefaaa 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -86,28 +86,27 @@ fedora-asan:
 reference:
   stage: docs
   variables:
-    DESTDIR: _install
-  needs: []
+    MESON_ARGS: >-
+      -Dgtk_doc=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
+    - ninja -C _build
+    - 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
diff --git a/docs/reference/build-howto.md b/docs/reference/build-howto.md
new file mode 100644
index 00000000..366dec36
--- /dev/null
+++ b/docs/reference/build-howto.md
@@ -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>
+```
diff --git a/docs/reference/client-advanced.md b/docs/reference/client-advanced.md
new file mode 100644
index 00000000..e7bc1045
--- /dev/null
+++ b/docs/reference/client-advanced.md
@@ -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@SessionFeature]s, 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_feature]function 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;
+}
+```
diff --git a/docs/reference/client-basic.xml b/docs/reference/client-basic.md
similarity index 58%
rename from docs/reference/client-basic.xml
rename to docs/reference/client-basic.md
index 00b6baa4..a1909f27 100644
--- a/docs/reference/client-basic.xml
+++ b/docs/reference/client-basic.md
@@ -1,25 +1,25 @@
-<?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>
+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)
 {
@@ -54,16 +54,17 @@ int main (int argc, char **argv)
     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>
+}
+```
+
+## 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)
 {
@@ -128,18 +129,19 @@ int main (int argc, char **argv)
     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>
+}
+```
+
+## 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)
 {
@@ -177,7 +179,5 @@ int main (int argc, char **argv)
     g_object_unref (msg);
     g_object_unref (session);
     return 0;
-}]]>
-</programlisting></informalexample>
-        </sect2>
-</sect1>
+}
+```
diff --git a/docs/reference/client-tls.xml b/docs/reference/client-tls.md
similarity index 67%
rename from docs/reference/client-tls.xml
rename to docs/reference/client-tls.md
index 2e329e65..e6e1974d 100644
--- a/docs/reference/client-tls.xml
+++ b/docs/reference/client-tls.md
@@ -1,15 +1,16 @@
-<?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[
+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)
@@ -32,12 +33,12 @@ int main (int argc, char **argv)
     }
 
     return 0;
-}]]>
-</programlisting></informalexample>
-  </sect2>
-  <sect2>
-    <title>Setting a Custom CA</title>
-<informalexample><programlisting><![CDATA[
+}
+```
+
+## Setting a Custom CA
+
+```c
 {
     GError *error = NULL;
     // NOTE: This is blocking IO
@@ -51,12 +52,12 @@ int main (int argc, char **argv)
 
     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[
+}
+```
+
+## Using Client Certificates
+
+```c
 static gboolean
 on_request_certificate (SoupMessage *msg, GTlsClientConnection *conn, gpointer user_data)
 {
@@ -96,7 +97,5 @@ int main (int argc, char **argv)
     g_object_unref (session);
     g_object_unref (client_cert);
     return 0;
-}]]>
-</programlisting></informalexample>
-  </sect2>
-</sect1>
\ No newline at end of file
+}
+```
diff --git a/docs/reference/libsoup.toml.in b/docs/reference/libsoup.toml.in
new file mode 100644
index 00000000..775ff3bd
--- /dev/null
+++ b/docs/reference/libsoup.toml.in
@@ -0,0 +1,50 @@
+[library]
+version = "@VERSION@"
+browse_url = "https://gitlab.gnome.org/GNOME/libsoup";
+repository_url = "https://gitlab.gnome.org/GNOME/libsoup.git";
+docs_url = "https://gnome.pages.gitlab.gnome.org/libsoup/libsoup-3.0/";
+website_url = "https://libsoup.org/";
+authors = "Dan Winship, Claudio Saavedra, and Patrick Griffis"
+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-tls.md',
+  'server-howto.md',
+  "migrating-from-libsoup-2.md",
+]
+
+content_images = [
+]
+urlmap_file = "urlmap.js"
diff --git a/docs/reference/meson.build b/docs/reference/meson.build
index 70282eca..e36c2fd3 100644
--- a/docs/reference/meson.build
+++ b/docs/reference/meson.build
@@ -1,87 +1,46 @@
-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-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_]*"'
-]
+libsoup_toml = configure_file(
+  input: 'libsoup.toml.in',
+  output: 'libsoup.toml',
+  configuration: toml_data
+)
 
-glib_prefix = glib_dep.get_pkgconfig_variable('prefix')
-glib_docpath = glib_prefix / 'share' / 'gtk-doc' / 'html'
+dependency('gi-docgen', version: '>= 2021.1',
+           fallback: ['gi-docgen', 'dummy_dep'],
+           native: true,
+           required: get_option('gtk_doc'))
 
-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',
+gidocgen = find_program('gi-docgen')
+
+docs_dir = get_option('datadir') / 'doc'
+
+custom_target('libsoup-doc',
+  input: [ libsoup_toml, soup_gir_gen_sources[0] ],
+  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,
 )
diff --git a/docs/reference/migrating-from-libsoup-2.md b/docs/reference/migrating-from-libsoup-2.md
new file mode 100644
index 00000000..0c399aa5
--- /dev/null
+++ b/docs/reference/migrating-from-libsoup-2.md
@@ -0,0 +1,162 @@
+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.
+
+In libsoup 3 it now behaves in line with other GObject libraries. Once you
+create a [class@Session] all usage of that session must happen on the same
+thread. You may create separate sessions per thread but in most use-cases you
+should be using the async APIs which handle non-blocking IO for you.
diff --git a/docs/reference/server-howto.md b/docs/reference/server-howto.md
new file mode 100644
index 00000000..cb1beb8d
--- /dev/null
+++ b/docs/reference/server-howto.md
@@ -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);
+```
+
+Then, every request under one of the auth domain's paths will be passed to the
+`auth_callback` first before being passed to the `server_callback`:
+
+```c
+static gboolean
+auth_callback (SoupAuthDomain *domain, SoupServerMessage *msg,
+               const char *username, const char *password,
+               gpointer user_data)
+{
+    MyServerData *server_data = user_data;
+    MyUserData *user;
+
+    user = my_server_data_lookup_user (server_data, username);
+    if (!user)
+        return FALSE;
+
+    /* FIXME: Don't do this. Keeping a cleartext password database
+     * is bad.
+     */
+    return strcmp (password, user->password) == 0;
+}
+```
+
+
+The [callback@AuthDomainBasicAuthCallback] is given the username and password
+from the `Authorization` header and must determine, in some server-specific
+manner, whether or not to accept them. (In this example we compare the password
+against a cleartext password database, but it would be better to store the
+password somehow encoded, as in the UNIX password database. Alternatively, you
+may need to delegate the password check to PAM or some other service.)
+
+If you are using Digest authentication, note that
+[callback@AuthDomainDigestAuthCallback] works completely differently (since the
+server doesn't receive the cleartext password from the client in that case, so
+there's no way to compare it directly). See the documentation for
+[class@AuthDomainDigest] for more details.
+
+You can have multiple [class@AuthDomain]s attached to a [class@Server], either
+in separate parts of the path hierarchy, or overlapping. (e.g. you might want to
+accept either Basic or Digest authentication for a given path.) When more than
+one auth domain covers a given path, the request will be accepted if the user
+authenticates successfully against *any* of the domains.
+
+If you want to require authentication for some requests under a certain path,
+but not all of them (e.g. you want to authenticate `PUT` requests, but not `GET`
+requests), use a [callback@AuthDomainFilter].
diff --git a/docs/reference/urlmap.js b/docs/reference/urlmap.js
new file mode 100644
index 00000000..67e8a251
--- /dev/null
+++ b/docs/reference/urlmap.js
@@ -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/' ],
+]
diff --git a/subprojects/gi-docgen.wrap b/subprojects/gi-docgen.wrap
new file mode 100644
index 00000000..98cd9211
--- /dev/null
+++ b/subprojects/gi-docgen.wrap
@@ -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


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]